sockd_request.c
上传用户:zm130024
上传日期:2007-01-04
资源大小:432k
文件大小:34k
源码类别:

代理服务器

开发平台:

Unix_Linux

  1. /*
  2.  * Copyright (c) 1997, 1998, 1999
  3.  *      Inferno Nettverk A/S, Norway.  All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. The above copyright notice, this list of conditions and the following
  9.  *    disclaimer must appear in all copies of the software, derivative works
  10.  *    or modified versions, and any portions thereof, aswell as in all
  11.  *    supporting documentation.
  12.  * 2. All advertising materials mentioning features or use of this software
  13.  *    must display the following acknowledgement:
  14.  *      This product includes software developed by
  15.  *      Inferno Nettverk A/S, Norway.
  16.  * 3. The name of the author may not be used to endorse or promote products
  17.  *    derived from this software without specific prior written permission.
  18.  *
  19.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  20.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  21.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  22.  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  23.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  24.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  25.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  26.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  28.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29.  *
  30.  * Inferno Nettverk A/S requests users of this software to return to
  31.  *
  32.  *  Software Distribution Coordinator  or  sdc@inet.no
  33.  *  Inferno Nettverk A/S
  34.  *  Oslo Research Park
  35.  *  Gaustadal閑n 21
  36.  *  N-0349 Oslo
  37.  *  Norway
  38.  *
  39.  * any improvements or extensions that they make and grant Inferno Nettverk A/S
  40.  * the rights to redistribute these changes.
  41.  *
  42.  */
  43. #include "common.h"
  44. static const char rcsid[] =
  45. "$Id: sockd_request.c,v 1.110 1999/12/22 09:29:27 karls Exp $";
  46. /*
  47.  * Since it only handles one client at a time there is no possibility
  48.  * for the mother to send a new client before we have got rid of the
  49.  * old one and thus no need for locking even on broken systems.
  50.  * (#ifdef HAVE_SENDMSG_DEADLOCK)
  51.  * XXX I have started to work on fixing this, so this process too
  52.  * can support multiple clients, perhaps for a later release I will
  53.  * have time to complete it.  Will also fix the terrible fact
  54.  * that we just sit around and wait if the command is bind, wasting
  55.  * the whole process on practically nothing.
  56.  */
  57. __BEGIN_DECLS
  58. static void
  59. dorequest __P((int mother, const struct sockd_request_t *request));
  60. /*
  61.  * When a complete request has been read, this function can be
  62.  * called.  It will perform the request "request->req" and send the
  63.  * result to "mother".
  64.  */
  65. static void
  66. flushio __P((int mother, int clientcontrol, const struct response_t *response,
  67.  struct sockd_io_t *io));
  68. /*
  69.  * "flushes" a complete io object and free's any state/resources held by it.
  70.  * "mother" is connection to mother for sending the io.
  71.  * "clientcontrol" is the client connection.
  72.  * "response" is the response to be sent the client.
  73.  * "io" is the io object sent mother.
  74.  */
  75. static void
  76. proctitleupdate __P((const struct sockaddr *from));
  77. /*
  78.  * Updates the title of this process.
  79.  */
  80. static struct sockd_io_t *
  81. io_add __P((struct sockd_io_t *iolist, const struct sockd_io_t *newio));
  82. /*
  83.  * Adds _a copy_ of the object "newio" to the list "iolist".
  84.  * Returns a pointer to the (new) iolist.
  85.  */
  86. static struct sockd_io_t *
  87. io_remove __P((struct sockd_io_t *iolist, struct sockd_io_t *rmio));
  88. /*
  89.  * Removes the object "rmio" from the list "iolist".
  90.  * Returns a pointer to the (new) iolist.
  91.  */
  92. static struct sockd_io_t *
  93. io_find __P((struct sockd_io_t *iolist, const struct sockaddr *addr));
  94. /*
  95.  * Scans "iolist" for a object that contains "addr" as a local address.
  96.  * If "addr" is NULL, returns "iolist".
  97.  * Returns:
  98.  * On success: pointer to the matching io object.
  99.  * On failure: NULL.
  100.  */
  101. __END_DECLS
  102. void
  103. run_request(mother)
  104. struct sockd_mother_t *mother;
  105. {
  106. const char *function = "run_request()";
  107. struct sockd_request_t req;
  108. #if DIAGNOSTIC
  109. const int freec = freedescriptors(config.option.debug ? "start" : NULL);
  110. #endif /* DIAGNOSTIC */
  111. proctitleupdate(NULL);
  112. /* CONSTCOND */
  113. while (1) {
  114. /*
  115.  * Get request from mother, perform it, get next request.
  116.  */
  117. const char command = SOCKD_FREESLOT;
  118. proctitleupdate(NULL);
  119. if (recv_req(mother->s, &req) == -1)
  120. sockdexit(-EXIT_FAILURE);
  121. /* LINTED pointer casts may be troublesome */
  122. proctitleupdate((struct sockaddr *)&req.from);
  123. dorequest(mother->s, &req);
  124. if (writen(mother->ack, &command, sizeof(command)) != sizeof(command))
  125. serr(EXIT_FAILURE, "%s: sending ack to mother failed", function);
  126. #if DIAGNOSTIC
  127. SASSERTX(freec == freedescriptors(config.option.debug ? "end" : NULL));
  128. #endif /* DIAGNOSTIC */
  129. }
  130. }
  131. int
  132. recv_req(s, req)
  133. int s;
  134. struct sockd_request_t *req;
  135. {
  136. const char *function = "recv_req()";
  137. int fdexpect, fdreceived, r;
  138. struct iovec iovec[1];
  139. struct msghdr msg;
  140. CMSG_AALLOC(sizeof(int));
  141. iovec[0].iov_base = req;
  142. iovec[0].iov_len = sizeof(*req);
  143. msg.msg_iov = iovec;
  144. msg.msg_iovlen = ELEMENTS(iovec);
  145. msg.msg_name = NULL;
  146. msg.msg_namelen = 0;
  147. CMSG_SETHDR_RECV(sizeof(cmsgmem));
  148. if ((r = recvmsgn(s, &msg, 0, sizeof(*req))) != sizeof(*req)) {
  149. switch (r) {
  150. case -1:
  151. swarn("%s: recvmsg() from mother", function);
  152. break;
  153. case 0:
  154. slog(LOG_DEBUG, "%s: recvmsg(): mother closed connection",
  155. function);
  156. break;
  157. default:
  158. swarnx("%s: recvmsg(): unexpected %d/%d bytes from mother",
  159. function, r, sizeof(*req));
  160. }
  161. return -1;
  162. }
  163. fdexpect = 1;
  164. #if !HAVE_DEFECT_RECVMSG
  165. SASSERT(CMSG_GETLEN(msg) == sizeof(int) * fdexpect);
  166. #endif
  167. fdreceived = 0;
  168. CMSG_GETOBJECT(req->s, sizeof(req->s) * fdreceived++);
  169. /* pointer fixup */
  170. req->req.auth = &req->state.auth;
  171. return 0;
  172. }
  173. static void
  174. dorequest(mother, request)
  175. int mother;
  176. const struct sockd_request_t *request;
  177. {
  178. const char *function = "dorequest()";
  179. static const struct sockd_io_t ioinit;
  180. struct sockaddr_in bound;
  181. struct sockd_io_t io;
  182. struct response_t response;
  183. char a[MAXSOCKSHOSTSTRING], b[MAXSOCKSHOSTSTRING];
  184. int p, permit, out;
  185. slog(LOG_DEBUG, "received request: %s",
  186. socks_packet2string(&request->req, SOCKS_REQUEST));
  187. bzero(&response, sizeof(response));
  188. response.host = request->req.host;
  189. response.auth = request->req.auth;
  190. io = ioinit;
  191. io.acceptrule = request->rule;
  192. io.state = request->state;
  193. io.state.extension = config.extension;
  194. /*
  195.  * examine client request.
  196.  */
  197. /* supported version? */
  198. switch (request->req.version) {
  199. case SOCKS_V4:
  200. response.version = SOCKS_V4REPLY_VERSION;
  201. /* recognized command for this version? */
  202. switch (request->req.command) {
  203. case SOCKS_BIND:
  204. case SOCKS_CONNECT:
  205. io.state.protocol = SOCKS_TCP;
  206. break;
  207. default:
  208. /* LINTED pointer casts may be troublesome */
  209. slog(LOG_INFO, "%s: unrecognized v%d command: %d",
  210. sockaddr2string((const struct sockaddr *)&request->from,
  211. a, sizeof(a)), request->req.version, request->req.command);
  212. send_failure(request->s, &response, SOCKS_FAILURE);
  213. close(request->s);
  214. return;
  215. }
  216. /* supported address format for this version? */
  217. switch (request->req.host.atype) {
  218. case SOCKS_ADDR_IPV4:
  219. break;
  220. default:
  221. /* LINTED pointer casts may be troublesome */
  222. slog(LOG_INFO, "%s: unrecognized v%d address type: %d",
  223. sockaddr2string((const struct sockaddr *)&request->from,
  224. a, sizeof(a)), request->req.version, request->req.host.atype);
  225. send_failure(request->s, &response, SOCKS_ADDR_UNSUPP);
  226. close(request->s);
  227. return;
  228. }
  229. break; /* SOCKS_V4 */
  230. case SOCKS_V5:
  231. response.version = request->req.version;
  232. /* recognized command for this version? */
  233. switch (request->req.command) {
  234. case SOCKS_BIND:
  235. case SOCKS_CONNECT:
  236. io.state.protocol = SOCKS_TCP;
  237. break;
  238. case SOCKS_UDPASSOCIATE:
  239. io.state.protocol = SOCKS_UDP;
  240. break;
  241. default:
  242. /* LINTED pointer casts may be troublesome */
  243. slog(LOG_INFO, "%s: unrecognized v%d command: %d",
  244. sockaddr2string((const struct sockaddr *)&request->from,
  245. a, sizeof(a)), request->req.version, request->req.command);
  246. send_failure(request->s, &response, SOCKS_CMD_UNSUPP);
  247. close(request->s);
  248. return;
  249. }
  250. /* supported address format for this version? */
  251. switch (request->req.host.atype) {
  252. case SOCKS_ADDR_IPV4:
  253. case SOCKS_ADDR_DOMAIN:
  254. break;
  255. default:
  256. /* LINTED pointer casts may be troublesome */
  257. slog(LOG_INFO, "%s: unrecognized v%d address type: %d",
  258. sockaddr2string((const struct sockaddr *)&request->from,
  259. a, sizeof(a)), request->req.version, request->req.host.atype);
  260. send_failure(request->s, &response, SOCKS_ADDR_UNSUPP);
  261. close(request->s);
  262. return;
  263. }
  264. break; /* SOCKS_V5 */
  265. default:
  266. SERRX(request->req.version);
  267. }
  268. /*
  269.  * packet looks ok, fill in remaining bits needed to check rules.
  270.  */
  271. switch (request->req.command) {
  272. case SOCKS_BIND:
  273. /* LINTED pointer casts may be troublesome */
  274. sockaddr2sockshost((const struct sockaddr *)&request->from, &io.src);
  275. io.dst = request->req.host;
  276. if (io.dst.atype != SOCKS_ADDR_IPV4
  277. ||  io.dst.addr.ipv4.s_addr != htonl(0)
  278. ||  io.dst.port == htons(0))
  279. io.state.extension.bind = 0; /* not requesting bind extension. */
  280. break;
  281. case SOCKS_CONNECT:
  282. /* LINTED pointer casts may be troublesome */
  283. sockaddr2sockshost((const struct sockaddr *)&request->from, &io.src);
  284. io.dst = request->req.host;
  285. break;
  286. case SOCKS_UDPASSOCIATE:
  287. /*
  288.  * for UDP_ASSOCIATE we are getting clients udp address,
  289.  * not destination in request.
  290.  * Destination address will be checked in the i/o loop for
  291.  * each destination, for now just set it to INADDR_ANY.
  292.  */
  293. io.src = request->req.host;
  294. io.dst.atype = SOCKS_ADDR_IPV4;
  295. io.dst.addr.ipv4.s_addr = htonl(INADDR_ANY);
  296. io.dst.port = htons(0);
  297. break;
  298. default:
  299. SERRX(request->req.command);
  300. }
  301. /* socket to use for outgoing connection. */
  302. switch (io.state.protocol) {
  303. case SOCKS_TCP:
  304. if ((out = socket(AF_INET, SOCK_STREAM, 0)) == -1)
  305. swarn("%s: socket(SOCK_STREAM)", function);
  306. break;
  307. case SOCKS_UDP:
  308. if ((out = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
  309. swarn("%s: socket(SOCK_DGRAM)", function);
  310. break;
  311. default:
  312. SERRX(io.state.protocol);
  313. }
  314. if (out == -1) {
  315. send_failure(request->s, &response, SOCKS_FAILURE);
  316. close(request->s);
  317. return;
  318. }
  319. setsockoptions(out);
  320. /* find out what address to bind on clients behalf. */
  321. bound = *config.externalv;
  322. switch (request->req.command) {
  323. case SOCKS_BIND:
  324. /* find out what port to bind;  v4/v5 semantics?  bind extension? */
  325. switch (request->req.version) {
  326. case SOCKS_V4:
  327. if (io.state.extension.bind)
  328. bound.sin_port = io.dst.port;
  329. else
  330. /* best we can try for is to use same port as source. */
  331. bound.sin_port = request->from.sin_port;
  332. break;
  333. case SOCKS_V5:
  334. bound.sin_port = io.dst.port;
  335. break;
  336. default:
  337. SERRX(request->req.version);
  338. }
  339. break;
  340. case SOCKS_CONNECT:
  341. bound.sin_port = request->from.sin_port;
  342. break;
  343. case SOCKS_UDPASSOCIATE:
  344. bound.sin_port = request->req.host.port;
  345. break;
  346. default:
  347. SERRX(request->req.command);
  348. }
  349. /*
  350.  * bind socket.
  351.  */
  352. if (config.compat.reuseaddr) {
  353. p = 1;
  354. if (setsockopt(out, SOL_SOCKET, SO_REUSEADDR, &p, sizeof(p)) != 0)
  355. swarn("%s: setsockopt(SO_REUSEADDR)", function);
  356. }
  357. if (PORTISRESERVED(bound.sin_port) && config.compat.sameport) {
  358. uid_t euid;
  359. socks_seteuid(&euid, config.uid.privileged);
  360. p = bindresvport(out, &bound);
  361. socks_reseteuid(config.uid.privileged, euid);
  362. }
  363. else
  364. /* LINTED pointer casts may be troublesome */
  365. p = sockd_bind(out, (struct sockaddr *)&bound, 1);
  366. if (p != 0) { /* no such luck, bind any port and let client decide if ok. */
  367. bound.sin_port = htons(0);
  368. /* LINTED pointer casts may be troublesome */
  369. if ((p = sockd_bind(out, (struct sockaddr *)&bound, 0)) != 0)
  370. swarn("%s: bind(%s)",
  371. /* LINTED pointer casts may be troublesome */
  372. function, sockaddr2string((struct sockaddr *)&bound, a, sizeof(a)));
  373. }
  374. if (p != 0) {
  375. send_failure(request->s, &response, errno2reply(errno, response.version));
  376. close(request->s);
  377. close(out);
  378. return;
  379. }
  380. /* rules permit? */
  381. switch (request->req.command) {
  382. case SOCKS_BIND: {
  383. struct sockshost_t boundhost;
  384. socklen_t boundlen;
  385. boundlen = sizeof(bound);
  386. /* LINTED pointer casts may be troublesome */
  387. if (getsockname(out, (struct sockaddr *)&bound, &boundlen) != 0) {
  388. swarn("%s: getsockname(out)", function);
  389. close(request->s);
  390. close(out);
  391. return;
  392. }
  393. /* LINTED pointer casts may be troublesome */
  394. sockaddr2sockshost((struct sockaddr *)&bound, &boundhost);
  395. permit
  396. = rulespermit(request->s, &io.rule, &io.state, &io.src, &boundhost);
  397. iolog(&io.rule, &io.state, OPERATION_CONNECT, &io.src, &boundhost,
  398. NULL, 0);
  399. break;
  400. }
  401. case SOCKS_CONNECT:
  402. permit
  403. = rulespermit(request->s, &io.rule, &io.state, &io.src, &io.dst);
  404. iolog(&io.rule, &io.state, OPERATION_CONNECT, &io.src, &io.dst,
  405. NULL, 0);
  406. break;
  407. case SOCKS_UDPASSOCIATE: {
  408. struct sockshost_t *src;
  409. struct connectionstate_t replystate;
  410. /*
  411.  * Client is allowed to send a "incomplete" address.
  412.  */
  413. if (io.src.atype == SOCKS_ADDR_IPV4
  414. && (io.src.addr.ipv4.s_addr == htonl(0) || io.src.port == htons(0)))
  415. src = NULL;
  416. else
  417. src = &io.src;
  418. /* only set temporary here for one replypacket at a time. */
  419. replystate = io.state;
  420. replystate.command = SOCKS_UDPREPLY;
  421. /* one direction is atleast in theory good enough. */
  422. permit = rulespermit(request->s, &io.rule, &io.state, src, NULL)
  423. || rulespermit(request->s, &io.rule, &replystate, NULL, src);
  424. iolog(&io.rule, &io.state, OPERATION_CONNECT, &io.src, &io.dst, NULL,
  425. 0);
  426. break;
  427. }
  428. default:
  429. SERRX(request->req.command);
  430. }
  431. if (!permit) {
  432. send_failure(request->s, &response, SOCKS_NOTALLOWED);
  433. close(request->s);
  434. close(out);
  435. return;
  436. }
  437. /*
  438.  * Set up missing bits of io and send it to mother.
  439.  */
  440. switch (io.state.command) {
  441. case SOCKS_BIND: {
  442. struct sockd_io_t *iolist;
  443. struct sockd_io_t bindio; /* send this to proxyrelayer. */
  444. struct sockaddr boundaddr; /* address we listen on. */
  445. struct sockaddr clientaddr; /* clientaddress we forward to. */
  446. socklen_t len;
  447. int flags, emfile;
  448. enum socketindex { client, childpipe, ourpipe, reply, remote };
  449. /* array of sockets, indexed by above enums, -1 if not open. */
  450. int sv[(int)(remote) + 1] = { -1, -1, -1, -1, -1 };
  451. SASSERTX(sv[ELEMENTS(sv) - 1] == -1);
  452. sv[client] = request->s;
  453. if (listen(out, 5) != 0) {
  454. swarn("%s: listen(out)", function);
  455. send_failure(sv[client], &response, SOCKS_FAILURE);
  456. closev(sv, ELEMENTS(sv));
  457. break;
  458. }
  459. /* for accept(). */
  460. if ((flags = fcntl(out, F_GETFL, 0)) == -1
  461. || fcntl(out, F_SETFL, flags | O_NONBLOCK) == -1) {
  462. swarn("%s: fcntl()", function);
  463. send_failure(sv[client], &response, SOCKS_FAILURE);
  464. closev(sv, ELEMENTS(sv));
  465. break;
  466. }
  467. len = sizeof(boundaddr);
  468. if (getsockname(out, &boundaddr, &len) != 0) {
  469. swarn("%s: getsockname()", function);
  470. send_failure(sv[client], &response, SOCKS_FAILURE);
  471. closev(sv, ELEMENTS(sv));
  472. break;
  473. }
  474. sockaddr2sockshost(&boundaddr, &response.host);
  475. response.reply = (char)sockscode(response.version, SOCKS_SUCCESS);
  476. /* LINTED pointer casts may be troublesome */
  477. clientaddr = *(const struct sockaddr *)&request->from;
  478. if (io.state.extension.bind) {
  479. int pipev[2];
  480. /*
  481.  * The problem is that both we and the process which receives
  482.  * the io packet needs to know when the client closes it's
  483.  * connection, but _we_ need to receive a query from the
  484.  * client on the connection aswell, and the io process would
  485.  * get confused about that.  We try to hack around that
  486.  * by making a "dummy" descriptor that the io process can
  487.  * check as all other controlconnections and which we
  488.  * can close when the client closes the real controlconnection,
  489.  * so the io process can detect it.  Not very nice, no.
  490.  */
  491. if (socketpair(AF_LOCAL, SOCK_STREAM, 0, pipev) != 0) {
  492. swarn("%s: socketpair()", function);
  493. send_failure(sv[client], &response, SOCKS_FAILURE);
  494. closev(sv, ELEMENTS(sv));
  495. break;
  496. }
  497. sv[childpipe] = pipev[0];
  498. sv[ourpipe] = pipev[1];
  499. /* LINTED pointer casts may be troublesome */
  500. ((struct sockaddr_in *)&clientaddr)->sin_port = io.dst.port;
  501. }
  502. /* let client know what address we bound to on it's behalf. */
  503. if (send_response(sv[client], &response) != 0) {
  504. iolog(&io.rule, &io.state, OPERATION_ABORT, &io.src, &response.host,
  505. NULL, 0);
  506. closev(sv, ELEMENTS(sv));
  507. break;
  508. }
  509. setproctitle("bindrelayer: %s -> %s",
  510. sockaddr2string(&boundaddr, a, sizeof(a)),
  511. sockaddr2string(&clientaddr, b, sizeof(b)));
  512. /*
  513.  * regardless of what kind of bind semantics are in use,
  514.  * portnumber is something we ignore when checking remote peer.
  515.  */
  516. io.dst.port = htons(0);
  517. emfile = 0;
  518. iolist = NULL;
  519. /* CONSTCOND */
  520. while (1) {
  521. struct ruleaddress_t ruleaddr;
  522. struct sockaddr remoteaddr; /* remote address we accepted. */
  523. struct sockshost_t remotehost; /* remote address, sockhost form.*/
  524. struct sockaddr_in replyaddr; /* address of bindreply socket. */
  525. int fdbits = -1;
  526. fd_set rset;
  527. /* some sockets change, most remain the same. */
  528. sv[reply] = -1;
  529. sv[remote] = -1;
  530. FD_ZERO(&rset);
  531. FD_SET(sv[client], &rset);
  532. fdbits = MAX(fdbits, sv[client]);
  533. if (!emfile) {
  534. FD_SET(out, &rset);
  535. fdbits = MAX(fdbits, out);
  536. }
  537. ++fdbits;
  538. if ((p = selectn(fdbits, &rset, NULL, NULL, NULL)) <= 0)
  539. SERR(p);
  540. if (FD_ISSET(sv[client], &rset)) {
  541. /*
  542.  * nothing is normally expected on controlconnection so
  543.  * assume it's a bind extension query or eof.
  544.  */
  545. struct request_t query;
  546. struct response_t queryresponse;
  547. struct negotiate_state_t state;
  548. struct sockaddr queryaddr;
  549. bzero(&state, sizeof(state));
  550. bzero(&query, sizeof(query));
  551. bzero(&queryresponse, sizeof(queryresponse));
  552. query.auth = request->req.auth;
  553. switch (p = recv_sockspacket(sv[client], &query, &state)) {
  554. case -1:
  555. iolog(&io.rule, &io.state, OPERATION_ABORT, &io.src,
  556. &response.host, NULL, 0);
  557. break;
  558. case 0:
  559. p = -1; /* session ended. */
  560. break;
  561. default: {
  562. struct sockd_io_t *fio;
  563. slog(LOG_DEBUG, "received request: %s",
  564. socks_packet2string(&query, SOCKS_REQUEST));
  565. switch (query.version) {
  566. case SOCKS_V4:
  567. queryresponse.version = SOCKS_V4REPLY_VERSION;
  568. break;
  569. case SOCKS_V5:
  570. queryresponse.version = query.version;
  571. break;
  572. default:
  573. SERRX(query.version);
  574. }
  575. sockshost2sockaddr(&query.host, &queryaddr);
  576. if ((fio = io_find(iolist, &queryaddr)) == NULL) {
  577. queryresponse.host.atype = SOCKS_ADDR_IPV4;
  578. queryresponse.host.addr.ipv4.s_addr = htonl(0);
  579. queryresponse.host.port = htons(0);
  580. }
  581. else {
  582. SASSERTX(fio->state.command = SOCKS_BINDREPLY);
  583. /* LINTED pointer casts may be troublesome */
  584. SASSERTX(sockaddrareeq((struct sockaddr *)
  585. &fio->in.laddr, &queryaddr));
  586. /* LINTED pointer casts may be troublesome */
  587. sockaddr2sockshost((struct sockaddr *)&fio->out.raddr,
  588. &queryresponse.host);
  589. }
  590. if (fio != NULL) {
  591. flushio(mother, sv[client], &queryresponse, fio);
  592. emfile = MAX(0, emfile - 3); /* flushio() closes 3. */
  593. iolist = io_remove(iolist, fio);
  594. p = 0;
  595. }
  596. else
  597. if ((p = send_response(sv[client], &queryresponse))
  598. != 0)
  599. iolog(&io.rule, &io.state, OPERATION_ABORT, &io.src,
  600. &response.host, NULL, 0);
  601. }
  602. }
  603. if (p != 0)
  604. break;
  605. }
  606. if (!FD_ISSET(out, &rset))
  607. continue;
  608. len = sizeof(remoteaddr);
  609. if ((sv[remote] = acceptn(out, &remoteaddr, &len)) == -1) {
  610. swarn("%s: accept(out)", function);
  611. switch (errno) {
  612. #ifdef EPROTO
  613. case EPROTO: /* overloaded SVR4 error */
  614. #endif
  615. case EWOULDBLOCK: /* BSD */
  616. case ECONNABORTED: /* POSIX */
  617. /* rest appears to be linux stuff according to apache src. */
  618. #ifdef ECONNRESET
  619. case ECONNRESET:
  620. #endif
  621. #ifdef ETIMEDOUT
  622. case ETIMEDOUT:
  623. #endif
  624. #ifdef EHOSTUNREACH
  625. case EHOSTUNREACH:
  626. #endif
  627. #ifdef ENETUNREACH
  628. case ENETUNREACH:
  629. #endif
  630. continue;
  631. case EMFILE:
  632. case ENFILE:
  633. ++emfile;
  634. continue;
  635. }
  636. break; /* errno is not ok. */
  637. }
  638. sockaddr2sockshost(&remoteaddr, &remotehost);
  639. /* accepted connection; does remote address match requested? */
  640. if (io.state.extension.bind
  641. || addressmatch(sockshost2ruleaddress(&io.dst, &ruleaddr),
  642. &remotehost, SOCKS_TCP, 1)) {
  643. bindio = io; /* quick init of most stuff. */
  644. bindio.src = remotehost;
  645. sockaddr2sockshost(&clientaddr, &bindio.dst);
  646. bindio.state.command = SOCKS_BINDREPLY;
  647. permit = rulespermit(sv[client], &bindio.rule, &bindio.state,
  648. &bindio.src, &bindio.dst);
  649. iolog(&bindio.rule, &bindio.state, OPERATION_CONNECT,
  650. &bindio.src, &bindio.dst, NULL, 0);
  651. }
  652. else {
  653. slog(LOG_INFO, "%s(0): unexpected bindreply: %s -> %s",
  654. VERDICT_BLOCKs, sockaddr2string(&remoteaddr, a, sizeof(a)),
  655. sockshost2string(&io.src, b, sizeof(b)));
  656. permit = 0;
  657. }
  658. if (!permit) {
  659. close(sv[remote]);
  660. continue; /* wait for next connect, but will there be one? */
  661. }
  662. /*
  663.  * Someone connected to socket we listen to on behalf of client.
  664.  * If we are using the bind extension, connect to address client
  665.  * is listening on.  Otherwise, send the data on the connection
  666.  * we already have.
  667.  */
  668. if (bindio.state.extension.bind) {
  669. if ((sv[reply] = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
  670. swarn("%s: socket(SOCK_STREAM)", function);
  671. switch (errno) {
  672. case EMFILE:
  673. case ENFILE:
  674. ++emfile;
  675. /* FALLTHROUGH */
  676. case ENOBUFS:
  677. close(sv[remote]);
  678. continue;
  679. }
  680. break; /* errno is not ok. */
  681. }
  682. setsockoptions(sv[reply]);
  683. /* LINTED pointer casts may be troublesome */
  684. replyaddr = *(struct sockaddr_in *)&boundaddr;
  685. replyaddr.sin_port = htons(0);
  686. /* LINTED pointer casts may be troublesome */
  687. if (sockd_bind(sv[reply], (struct sockaddr *)&replyaddr, 0)
  688. != 0) {
  689. /* LINTED pointer casts may be troublesome */
  690. swarn("%s: bind(%s)", function,
  691. sockaddr2string((struct sockaddr *)&replyaddr, a, sizeof(a)));
  692. break;
  693. }
  694. len = sizeof(replyaddr);
  695. /* LINTED pointer casts may be troublesome */
  696. if (getsockname(sv[reply], (struct sockaddr *)&replyaddr, &len)
  697. != 0) {
  698. swarn("%s: getsockname(sv[reply])", function);
  699. if (errno == ENOBUFS) {
  700. close(sv[remote]);
  701. close(sv[reply]);
  702. continue;
  703. }
  704. break;
  705. }
  706. slog(LOG_DEBUG, "connecting to %s",
  707. sockaddr2string(&clientaddr, a, sizeof(a)));
  708. if (connect(sv[reply], &clientaddr, sizeof(clientaddr)) != 0) {
  709. iolog(&bindio.rule, &bindio.state, OPERATION_ABORT,
  710. &bindio.src, &bindio.dst, NULL, 0);
  711. break;
  712. }
  713. }
  714. if (bindio.state.extension.bind) {
  715. /*
  716.  * flushio() will close all descriptors set in io packet
  717.  * so dup what we need to keep going.
  718.  */
  719. if ((bindio.control.s = dup(sv[childpipe])) == -1) {
  720. switch (errno) {
  721. case EMFILE:
  722. case ENFILE:
  723. swarn("%s: dup()", function);
  724. ++emfile;
  725. continue;
  726. default:
  727. SERR(bindio.control.s);
  728. }
  729. }
  730. }
  731. else
  732. bindio.control.s = sv[client];
  733. bindio.control.laddr = request->to;
  734. bindio.control.raddr = request->from;
  735. bindio.control.state = bindio.state;
  736. /* back to blocking. */
  737. if (fcntl(sv[remote], F_SETFL, flags) == -1) {
  738. swarn("%s: fcntl()", function);
  739. break;
  740. }
  741. if (bindio.state.extension.bind) {
  742. bindio.in.s = sv[reply];
  743. bindio.in.laddr = replyaddr;
  744. bindio.in.state = bindio.state;
  745. }
  746. else {
  747. bindio.in = bindio.control;
  748. bindio.in.laddr = request->from;
  749. }
  750. /* LINTED pointer casts may be troublesome */
  751. bindio.in.raddr = *(struct sockaddr_in *)&clientaddr;
  752. bindio.out.s = sv[remote];
  753. /* LINTED pointer casts may be troublesome */
  754. bindio.out.laddr = *(struct sockaddr_in *)&boundaddr;
  755. /* LINTED pointer casts may be troublesome */
  756. bindio.out.raddr = *(struct sockaddr_in *)&remoteaddr;
  757. bindio.out.state.auth.method = AUTHMETHOD_NONE;
  758. if (bindio.state.extension.bind)
  759. /* add to list, client will query. */
  760. iolist = io_add(iolist, &bindio);
  761. else {
  762. response.host = bindio.dst;
  763. flushio(mother, sv[client], &response, &bindio);
  764. sv[client] = sv[remote] = -1; /* flushio() closes; closev(). */
  765. break; /* only one connection to relay and that is done. */
  766. }
  767. }
  768. if (bindio.state.extension.bind) {
  769. struct sockd_io_t *rmio;
  770. /* delete any connections we have queued. */
  771. while ((rmio = io_find(iolist, NULL)) != NULL) {
  772. close_iodescriptors(rmio);
  773. iolist = io_remove(iolist, rmio);
  774. }
  775. }
  776. closev(sv, ELEMENTS(sv));
  777. break;
  778. }
  779. case SOCKS_CONNECT: {
  780. socklen_t sinlen;
  781. if (socks_connect(out, &io.dst) != 0) {
  782. iolog(&io.rule, &io.state, OPERATION_ABORT, &io.src, &io.dst,
  783. NULL, 0);
  784. send_failure(request->s, &response,
  785. errno2reply(errno, response.version));
  786. close(request->s);
  787. break;
  788. }
  789. io.in.s = request->s;
  790. io.in.laddr = request->to;
  791. io.in.raddr = request->from;
  792. io.in.state = io.state;
  793. io.out.s = out;
  794. io.out.state = io.state;
  795. sinlen = sizeof(io.out.raddr);
  796. /* LINTED pointer casts may be troublesome */
  797. if (getpeername(io.out.s, (struct sockaddr *)&io.out.raddr, &sinlen)
  798. != 0) {
  799. swarn("%s: getpeername(io.out.s)", function);
  800. send_failure(request->s, &response, SOCKS_FAILURE);
  801. close(request->s);
  802. break;
  803. }
  804. sinlen = sizeof(io.out.laddr);
  805. /* LINTED pointer casts may be troublesome */
  806. if (getsockname(io.out.s, (struct sockaddr *)&io.out.laddr, &sinlen)
  807. != 0) {
  808. swarn("%s: getsockname(io.out.s)", function);
  809. send_failure(request->s, &response, SOCKS_FAILURE);
  810. close(request->s);
  811. break;
  812. }
  813. /* LINTED pointer casts may be troublesome */
  814. sockaddr2sockshost((struct sockaddr *)&io.out.laddr, &response.host);
  815. response.reply = (char)sockscode(response.version, SOCKS_SUCCESS);
  816. flushio(mother, request->s, &response, &io);
  817. break;
  818. }
  819. case SOCKS_UDPASSOCIATE: {
  820. struct sockaddr_in client;
  821. socklen_t boundlen;
  822. int clientfd;
  823. /* socket we receive datagram's from client on */
  824. if ((clientfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
  825. swarn("%s: socket(SOCK_DGRAM)", function);
  826. send_failure(request->s, &response, SOCKS_FAILURE);
  827. close(request->s);
  828. break;
  829. }
  830. setsockoptions(clientfd);
  831. /* LINTED pointer casts may be troublesome */
  832. sockshost2sockaddr(&request->req.host, (struct sockaddr *)&client);
  833. io.in.s = clientfd;
  834. io.in.state = io.state;
  835. io.in.raddr = client;
  836. io.in.laddr = request->to;
  837. io.in.laddr.sin_port = htons(0);
  838. /*
  839.  * bind to address for receiving udp packets so we can tell client
  840.  * where to send its packets.
  841.  */
  842. /* LINTED pointer casts may be troublesome */
  843. if (sockd_bind(clientfd, (struct sockaddr *)&io.in.laddr, 0) != 0) {
  844. /* LINTED pointer casts may be troublesome */
  845. swarn("%s: bind(%s)", function,
  846. sockaddr2string((struct sockaddr *)&io.in.laddr, a, sizeof(a)));
  847. send_failure(request->s, &response, SOCKS_FAILURE);
  848. close(request->s);
  849. close(clientfd);
  850. break;
  851. }
  852. boundlen = sizeof(io.in.laddr);
  853. /* LINTED pointer casts may be troublesome */
  854. if (getsockname(clientfd, (struct sockaddr *)&io.in.laddr, &boundlen)
  855. != 0) {
  856. swarn("%s: getsockname(clientfd)", function);
  857. send_failure(request->s, &response, SOCKS_FAILURE);
  858. close(request->s);
  859. close(clientfd);
  860. break;
  861. }
  862. io.out.s = out;
  863. io.out.state = io.state;
  864. io.out.state.auth.method = AUTHMETHOD_NONE;
  865. boundlen = sizeof(io.out.laddr);
  866. /* LINTED pointer casts may be troublesome */
  867. if (getsockname(out, (struct sockaddr *)&io.out.laddr, &boundlen)
  868. != 0) {
  869. swarn("%s: getsockname(out)", function);
  870. send_failure(request->s, &response, SOCKS_FAILURE);
  871. close(request->s);
  872. close(clientfd);
  873. break;
  874. }
  875. /* remote out changes each time, set to INADDR_ANY for now. */
  876. bzero(&io.out.raddr, sizeof(io.out.raddr));
  877. io.out.raddr.sin_family = AF_INET;
  878. io.out.raddr.sin_addr.s_addr = htonl(INADDR_ANY);
  879. io.out.raddr.sin_port = htons(0);
  880. io.control.s = request->s;
  881. io.control.laddr = request->from;
  882. io.control.raddr = request->to;
  883. io.control.state = io.state;
  884. if (request->req.flag & SOCKS_USECLIENTPORT)
  885. if (client.sin_port == io.out.laddr.sin_port)
  886. response.flag |= SOCKS_USECLIENTPORT;
  887. /* LINTED pointer casts may be troublesome */
  888. sockaddr2sockshost((struct sockaddr *)&io.in.laddr, &response.host);
  889. response.reply = (char)sockscode(response.version, SOCKS_SUCCESS);
  890. flushio(mother, request->s, &response, &io);
  891. break;
  892. }
  893. default:
  894. SERRX(request->req.command);
  895. }
  896. close(out);
  897. }
  898. static void
  899. flushio(mother, clientcontrol, response, io)
  900. int mother;
  901. int clientcontrol;
  902. const struct response_t *response;
  903. struct sockd_io_t *io;
  904. {
  905. const char *function = "flushio()";
  906. socklen_t len;
  907. int sndlowat, value;
  908. float skew;
  909. switch (io->state.command) {
  910. case SOCKS_UDPASSOCIATE:
  911. sndlowat = SOCKD_BUFSIZEUDP;
  912. skew = 1.0; /* no skew. */
  913. break;
  914. default:
  915. sndlowat = SOCKD_BUFSIZETCP;
  916. skew = LOWATSKEW;
  917. }
  918. /* set socket options for relay process. */
  919. #if SOCKD_IOMAX == 1
  920. /* only one client per process; doesn't matter much whether we block. */
  921. io->in.sndlowat = sndlowat;
  922. io->out.sndlowat = sndlowat;
  923. #elif HAVE_SO_SNDLOWAT
  924. len = sizeof(value);
  925. if (getsockopt(io->in.s, SOL_SOCKET, SO_SNDBUF, &value, &len) != 0)
  926. swarn("%s: getsockopt(in, SO_SNDBUF)", function);
  927. sndlowat = MIN(sndlowat, value * skew);
  928. if (setsockopt(io->in.s, SOL_SOCKET, SO_SNDLOWAT, &sndlowat,
  929. sizeof(sndlowat)) != 0)
  930. swarn("%s: setsockopt(in, SO_SNDLOWAT)", function);
  931. len = sizeof(io->in.sndlowat);
  932. if (getsockopt(io->in.s, SOL_SOCKET, SO_SNDLOWAT, &io->in.sndlowat, &len)
  933. != 0)
  934. swarn("%s: getsockopt(in, SO_SNDLOWAT)", function);
  935. len = sizeof(value);
  936. if (getsockopt(io->out.s, SOL_SOCKET, SO_SNDBUF, &value, &len) != 0)
  937. swarn("%s: getsockopt(out, SO_SNDBUF)", function);
  938. sndlowat = MIN(sndlowat, value * skew);
  939. if (setsockopt(io->out.s, SOL_SOCKET, SO_SNDLOWAT, &sndlowat,
  940. sizeof(sndlowat)) != 0)
  941. swarn("%s: setsockopt(out, SO_SNDLOWAT", function);
  942. len = sizeof(io->out.sndlowat);
  943. if (getsockopt(io->in.s, SOL_SOCKET, SO_SNDLOWAT, &io->out.sndlowat, &len)
  944. != 0)
  945. swarn("%s: getsockopt(in, SO_SNDLOWAT", function);
  946. #else /* SOCKD_IOMAX > 1 && !HAVE_SO_SNDLOWAT. */
  947. switch (io->state.command) {
  948. case SOCKS_UDPASSOCIATE:
  949. len = sizeof(sndlowat);
  950. if (getsockopt(io->in.s, SOL_SOCKET, SO_SNDBUF, &sndlowat, &len) != 0){
  951. swarn("%s: getsockopt(SO_SNDBUF", function);
  952. io->in.sndlowat = SOCKD_BUFSIZEUDP;
  953. }
  954. else if (sndlowat == 0)
  955. io->in.sndlowat = SOCKD_BUFSIZEUDP;
  956. else
  957. io->in.sndlowat = sndlowat;
  958. len = sizeof(sndlowat);
  959. if (getsockopt(io->out.s, SOL_SOCKET, SO_SNDBUF, &sndlowat, &len)
  960. != 0) {
  961. swarn("%s: getsockopt(SO_SNDBUF", function);
  962. io->out.sndlowat = SOCKD_BUFSIZEUDP;
  963. }
  964. else if (sndlowat == 0)
  965. io->out.sndlowat = SOCKD_BUFSIZEUDP;
  966. else
  967. io->out.sndlowat = sndlowat;
  968. break;
  969. default:
  970. /* TCP; use minimum guess. */
  971. io->in.sndlowat = SO_SNDLOWAT_SIZE;
  972. io->out.sndlowat = SO_SNDLOWAT_SIZE;
  973. }
  974. #endif  /* SOCKD_IOMAX > 1 && !HAVE_SO_SNDLOWAT */
  975. SASSERTX(io->in.sndlowat > 0
  976. && io->out.sndlowat >= sizeof(struct udpheader_t));
  977. if (send_response(clientcontrol, response) == 0)
  978. if (send_io(mother, io) != 0)
  979. serr(EXIT_FAILURE, "%s: sending io to mother failed", function);
  980. close_iodescriptors(io);
  981. }
  982. static void
  983. proctitleupdate(from)
  984. const struct sockaddr *from;
  985. {
  986. char fromstring[MAXSOCKADDRSTRING];
  987. setproctitle("requestcompleter: %s",
  988. from == NULL ?
  989. "<idle>" : sockaddr2string(from, fromstring, sizeof(fromstring)));
  990. }
  991. static struct sockd_io_t *
  992. io_add(iolist, newio)
  993. struct sockd_io_t *iolist;
  994. const struct sockd_io_t *newio;
  995. {
  996. const char *function = "io_add()";
  997. struct sockd_io_t *io, *previo;
  998. SASSERTX(newio->next == NULL);
  999. previo = io = iolist;
  1000. while (io != NULL) {
  1001. previo = io;
  1002. io = io->next;
  1003. }
  1004. if ((io = (struct sockd_io_t *)malloc(sizeof(*newio))) == NULL)
  1005. swarnx("%s: %s", function, NOMEM);
  1006. else {
  1007. *io = *newio;
  1008. if (previo == NULL)
  1009. previo = io;
  1010. else
  1011. previo->next = io;
  1012. }
  1013. return iolist == NULL ? previo : iolist;
  1014. }
  1015. static struct sockd_io_t *
  1016. io_remove(iolist, rmio)
  1017. struct sockd_io_t *iolist;
  1018. struct sockd_io_t *rmio;
  1019. {
  1020. struct sockd_io_t *io, *previo;
  1021. SASSERTX(iolist != NULL);
  1022. if (iolist == rmio) {
  1023. iolist = rmio->next;
  1024. free(rmio);
  1025. return iolist;
  1026. }
  1027. previo = iolist;
  1028. io = iolist->next;
  1029. while (io != NULL) {
  1030. if (io == rmio) {
  1031. previo->next = rmio->next;
  1032. free(rmio);
  1033. break;
  1034. }
  1035. previo = io;
  1036. io = io->next;
  1037. }
  1038. return iolist;
  1039. }
  1040. static struct sockd_io_t *
  1041. io_find(iolist, addr)
  1042. struct sockd_io_t *iolist;
  1043. const struct sockaddr *addr;
  1044. {
  1045. struct sockd_io_t *io;
  1046. if (addr == NULL)
  1047. return iolist;
  1048. io = iolist;
  1049. while (io != NULL)
  1050. /* LINTED pointer casts may be troublesome */
  1051. if (sockaddrareeq((struct sockaddr *)&io->in.laddr, addr)
  1052. ||  sockaddrareeq((struct sockaddr *)&io->out.laddr, addr)
  1053. ||  sockaddrareeq((struct sockaddr *)&io->control.laddr, addr))
  1054. return io;
  1055. else
  1056. io = io->next;
  1057. /* XXX should actually check that the io is still "active". */
  1058. return NULL;
  1059. }