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

代理服务器

开发平台:

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_io.c,v 1.165 1999/12/29 08:58:54 michaels Exp $";
  46. /*
  47.  * Accept io objects from mother and does io on them.  We never
  48.  * send back ancillary data, only ordinary data, so no need for
  49.  * locking here even on broken systems (#ifdef HAVE_SENDMSG_DEADLOCK).
  50.  */
  51. __BEGIN_DECLS
  52. static int
  53. allocated __P((void));
  54. /*
  55.  * Returns the number of allocated (active) io's
  56.  */
  57. static struct sockd_io_t *
  58. io_getset __P((fd_set *set));
  59. /*
  60.  * Goes through our list until it finds a io object where atleast one of the
  61.  * descriptors is set.
  62.  * Returns NULL if none found.
  63.  */
  64. static struct sockd_io_t *
  65. io_finddescriptor __P((int d));
  66. /*
  67.  * Finds the io object where one of the descriptors matches "fd".
  68.  */
  69. static int
  70. io_fillset __P((fd_set *set, int antiflags));
  71. /*
  72.  * Sets all descriptors in our list in the set "set".  If "flags"
  73.  * is set, io's with any of the flags in "flags" set will be excluded.
  74.  * Returns the highest descriptor in our list, or -1 if we don't
  75.  * have any descriptors open currently.
  76.  */
  77. static void
  78. io_clearset __P((const struct sockd_io_t *io, fd_set *set));
  79. /*
  80.  * Clears all filedescriptors in "io" from "set".
  81.  */
  82. static void
  83. doio __P((int mother, struct sockd_io_t *io, fd_set *rset, fd_set *wset,
  84.  int flags));
  85. /*
  86.  * Does i/o over the descriptors in "io", in to out and out to in.
  87.  * "mother" is write connection to mother if we need to send a ack.
  88.  * "io" is the object to do i/o over,
  89.  * "flags" is the flags to set on the actual i/o calls
  90.  * (read()/write(), recvfrom()/sendto()), currently only MSG_OOB.
  91.  * If any of the calls fails the "io" is deleted.
  92.  */
  93. static int
  94. io_rw __P((struct sockd_io_direction_t *in, struct sockd_io_direction_t *out,
  95.   int *bad, char *buf, int flags));
  96. /*
  97.  * Transfers data from "in" to "out" using flag "flags".  The data
  98.  * transfered uses "buf" as a buffer, which must be big enough to
  99.  * hold the data transfered.
  100.  * The function never transfers more that the receive low watermark of
  101.  * "out".
  102.  * Returns:
  103.  * On success: bytes transfered or 0 for eof.
  104.  * On failure: -1.  "bad" is set to the value of the descriptor that
  105.  * failure was first detected on.
  106.  */
  107. static void
  108. delete_io __P((int mother, struct sockd_io_t *io, int fd, int status));
  109. /*
  110.  * deletes the io object "io".  "fd" is the descriptor on which "status"
  111.  * was returned.  If "fd" is negative, it's ignored.
  112.  * If "mother" is >= 0 the deletion of "io" is ACK'ed to her.
  113.  * "status" can have one of these values and is normally intended to be the
  114.  * result from a io call (read/write/etc).
  115.  * IO_ERRORUNKNOWN: unknown error.
  116.  * IO_TIMEOUT : connection timed out.  ("fd" argument is ignored).
  117.  * IO_ERROR :  error using "fd".
  118.  * IO_CLOSE : socket was closed.
  119.  * > 0 :  short read/write
  120.  */
  121. static void
  122. proctitleupdate __P((void));
  123. /*
  124.  * Updates the title of this process.
  125.  */
  126. static struct timeval *
  127. io_gettimeout __P((struct timeval *timeout));
  128. /*
  129.  * If there is a timeout on the current clients for how long to exist
  130.  * without doing i/o, this function fills in "timeout" with the appropriate
  131.  * timeout.
  132.  * Returns:
  133.  * If there is a timeout: pointer to filled in "timeout".
  134.  * If there is no timeout: NULL.
  135.  */
  136. static struct sockd_io_t *
  137. io_gettimedout __P((void));
  138. /*
  139.  * Scans all clients for one that has timed out according to config
  140.  * settings.
  141.  * Returns:
  142.  * If timed out client found: pointer to it.
  143.  * Else: NULL.
  144.  */
  145. static void
  146. checkmother __P((struct sockd_mother_t *mother, fd_set *readset));
  147. /*
  148.  * Checks if "mother" is set in "readset" and if so receives
  149.  * a io from "mother".  Closes "mother" if there is an error.
  150.  */
  151. static void
  152. siginfo __P((int sig));
  153. /*
  154.  * Print information about our current connections.
  155.  */
  156. /* Solaris sometimes fails to return srcaddress in recvfrom(). */
  157. #define UDPFROMLENCHECK(socket, fromlen) 
  158. do { 
  159. if (fromlen == 0) { 
  160. static int failures; 
  161. swarnx("%s: system error: did not get address in recvfrom()", 
  162. function); 
  163. if (++failures > 5) { 
  164. swarnx("%s: running Solaris <= 2.5.1 are we?  " 
  165. "giving up after %d failures", function, failures); 
  166. delete_io(mother, io, (socket), IO_ERROR); 
  167. failures = 0; 
  168. return; 
  169. } while (lintnoloop_sockd_h)
  170. __END_DECLS
  171. static struct sockd_io_t iov[SOCKD_IOMAX]; /* each child has these io's. */
  172. static int ioc = ELEMENTS(iov);
  173. void
  174. run_io(mother)
  175. struct sockd_mother_t *mother;
  176. {
  177. const char *function = "run_io()";
  178. struct sigaction sigact;
  179. int p;
  180. sigemptyset(&sigact.sa_mask);
  181. sigact.sa_flags = SA_RESTART;
  182. sigact.sa_handler = siginfo;
  183. #if HAVE_SIGNAL_SIGINFO
  184. if (sigaction(SIGINFO, &sigact, NULL) != 0)
  185. serr(EXIT_FAILURE, "%s: sigaction(SIGINFO)", function);
  186. #endif  /* HAVE_SIGNAL_SIGINFO */
  187. /* same handler, for systems without SIGINFO. */
  188. if (sigaction(SIGUSR1, &sigact, NULL) != 0)
  189. serr(EXIT_FAILURE, "%s: sigaction(SIGINFO)", function);
  190. proctitleupdate();
  191. /* CONSTCOND */
  192. while (1) {
  193. int rbits, bits;
  194. fd_set rset, wset, xset, newrset, controlset, tmpset;
  195. struct sockd_io_t *io;
  196. struct timeval timeout;
  197. io_fillset(&xset, MSG_OOB);
  198. rbits = io_fillset(&rset, 0);
  199. if (mother->s != -1) {
  200. FD_SET(mother->s, &rset);
  201. rbits = MAX(rbits, mother->s);
  202. }
  203. else /* no mother.  Do we have any other descriptors to work with? */
  204. if (rbits == -1) {
  205. SASSERTX(allocated() == 0);
  206. slog(LOG_DEBUG, "%s: can't find mother and no io's", function);
  207. sockdexit(-EXIT_FAILURE);
  208. }
  209. /*
  210.  * first find descriptors that are readable; we won't write if
  211.  * we can't read.  Also select for exceptions so we can tell
  212.  * the i/o function if there's one pending later.
  213.  */
  214. ++rbits;
  215. switch (selectn(rbits, &rset, NULL, &xset, io_gettimeout(&timeout))) {
  216. case -1:
  217. SERR(-1);
  218. /* NOTREACHED */
  219. case 0:
  220. if ((io = io_gettimedout()) != NULL)
  221. delete_io(mother->ack, io, -1, IO_TIMEOUT);
  222. /* else: should only be possible if sighup received. */
  223. continue;
  224. }
  225. checkmother(mother, &rset);
  226. /*
  227.  * This is tricky but we need to check for write separately to
  228.  * avoid busylooping.
  229.  * The problem is that if the descriptor is ready for reading but
  230.  * the corresponding descriptor to write out on is not ready we will
  231.  * be busylooping; above select will keep returning descriptors set,
  232.  * but we will not be able to write (and thus read) them.
  233.  * We therefore only set in wset the descriptors that have the
  234.  * corresponding read descriptor readable so that when the
  235.  * below select() returns, the io objects we get from wset will
  236.  * be both readable and writable.
  237.  *
  238.  * Another problem is that if while we wait for writability, a new
  239.  * descriptor becomes readable, we thus can't block forever here.
  240.  * We solve this by in the below select() also checking for
  241.  * readability, but now only the descriptors that were not found
  242.  * to be readable in the previous select().
  243.  * This means that a positive return from below select does not
  244.  * necessarily indicate we have i/o to do, but it does mean we
  245.  * either have it or a new descriptor became readable; in either
  246.  * case, something has happened.
  247.  * Reason we do not check for exceptions in this select is that
  248.  * there is nothing we do about them until the descriptor becomes
  249.  * readable too, thus any new exceptions will be in newrset before
  250.  * we have reason to care about them.
  251.  */
  252. /* descriptors to check for readability; those not already set. */
  253. bits = io_fillset(&tmpset, 0);
  254. bits = fdsetop(bits + 1, '^', &rset, &tmpset, &newrset);
  255. if (mother->s != -1) { /* mother status may change too. */
  256. FD_SET(mother->s, &newrset);
  257. bits = MAX(bits, mother->s);
  258. }
  259. /*
  260.  * descriptors to check for writability aswell as
  261.  * controldescriptors to check for readability.
  262.  */
  263. FD_ZERO(&wset);
  264. FD_ZERO(&controlset);
  265. for (p = 0; p < rbits; ++p) {
  266. if (!FD_ISSET(p, &rset)) { /* only write after read. */
  267. FD_CLR(p, &xset); /* don't care about xset without rset */
  268. continue;
  269. }
  270. io = io_finddescriptor(p);
  271. SASSERTX(io != NULL);
  272. if (io->in.s == p) {
  273. /* read from in requires out to be writable. */
  274. FD_SET(io->out.s, &wset);
  275. bits = MAX(bits, io->out.s);
  276. }
  277. else if (io->out.s == p) {
  278. /* read from out requires in to be writable. */
  279. FD_SET(io->in.s, &wset);
  280. bits = MAX(bits, io->in.s);
  281. }
  282. else {
  283. SASSERTX(io->control.s == p);
  284. FD_SET(io->control.s, &controlset);
  285. /* also readable without matching writable. */
  286. FD_SET(io->control.s, &newrset);
  287. bits = MAX(bits, io->control.s);
  288. }
  289. }
  290. if (bits++ < 0) {
  291. SASSERTX(allocated() == 0
  292. && mother->s == mother->ack && mother->s < 0);
  293. continue;
  294. }
  295. switch (selectn(bits, &newrset, &wset, NULL, io_gettimeout(&timeout))) {
  296. case -1:
  297. SERR(-1);
  298. /* NOTREACHED */
  299. case 0:
  300. if ((io = io_gettimedout()) != NULL)
  301. delete_io(mother->ack, io, -1, IO_TIMEOUT);
  302. /* else: should only be possible if sighup received. */
  303. continue;
  304. }
  305. checkmother(mother, &rset);
  306. tmpset = controlset;
  307. fdsetop(bits, '&', &newrset, &tmpset, &controlset);
  308. /*
  309.  * newrset; descriptors readable, all new apart from controldescriptors.
  310.  * Don't do anything with them here, loop around and check for
  311.  * writability first.
  312.  *
  313.  * controlset; subset of newrset containing control descriptors
  314.  * that are readable.
  315.  *
  316.  * rset; descriptors readable, not necessarily with a match in wset.
  317.  *
  318.  * xset; subset of rset with exceptions pending.
  319.  *
  320.  * wset; descriptors writable with a matching in rset/xset,
  321.  * what we can do i/o over.
  322.  */
  323. /*
  324.  * First check all io's which have an exception pending.
  325.  * Getting a io here does not mean we can do i/o over it
  326.  * however.
  327.  */
  328. while ((io = io_getset(&xset)) != NULL) {
  329. slog(LOG_DEBUG, "select(): exception set");
  330. doio(mother->ack, io, &xset, &wset, MSG_OOB);
  331. io_clearset(io, &xset);
  332. io_clearset(io, &wset);
  333. /* xset is subset of rset so clear rset too. */
  334. io_clearset(io, &rset);
  335. }
  336. /*
  337.  * Get all io's which are writable.  They will have a matching
  338.  * descriptor that is readable.
  339.  */
  340. while ((io = io_getset(&wset)) != NULL) {
  341. doio(mother->ack, io, &rset, &wset, 0);
  342. io_clearset(io, &rset);
  343. io_clearset(io, &wset);
  344. /* xset is subset of rset so clear xset too. */
  345. io_clearset(io, &xset);
  346. }
  347. /*
  348.  * Get all io's which have controldescriptors that are readable.
  349.  */
  350. while ((io = io_getset(&controlset)) != NULL) {
  351. fd_set nullset;
  352. FD_ZERO(&nullset);
  353. doio(mother->ack, io, &controlset, &nullset, 0);
  354. io_clearset(io, &controlset);
  355. /* controlset is subset of newrset so clear newrset too. */
  356. io_clearset(io, &newrset);
  357. }
  358. /* possible future optimization: if newrset not empty, use it? */
  359. }
  360. }
  361. static void
  362. delete_io(mother, io, fd, status)
  363. int mother;
  364. struct sockd_io_t *io;
  365. int fd;
  366. int status;
  367. {
  368. const char *function = "delete_io()";
  369. const int errno_s = errno;
  370. SASSERTX(io->allocated);
  371. if (io->rule.log.disconnect) {
  372. char logmsg[MAXHOSTNAMELEN * 2 + 1024];
  373. char in[MAXSOCKADDRSTRING], out[MAXSOCKADDRSTRING];
  374. /* LINTED pointer casts may be troublesome */
  375. sockaddr2string((struct sockaddr *)&io->in.raddr, in, sizeof(in));
  376. switch (io->state.command) {
  377. case SOCKS_BIND:
  378. case SOCKS_BINDREPLY:
  379. case SOCKS_CONNECT:
  380. /* LINTED pointer casts may be troublesome */
  381. sockaddr2string((struct sockaddr *)&io->out.raddr, out,
  382. sizeof(out));
  383. break;
  384. case SOCKS_UDPASSOCIATE:
  385. snprintf(out, sizeof(out), "`world'");
  386. break;
  387. default:
  388. SERRX(io->state.command);
  389. }
  390. snprintf(logmsg, sizeof(logmsg),
  391. "%s: %lu -> %s -> %lu,  %lu -> %s -> %lu",
  392. protocol2string(io->state.protocol),
  393. (unsigned long)io->in.written, in, (unsigned long)io->in.read,
  394. (unsigned long)io->out.written, out, (unsigned long)io->out.read);
  395. errno = errno_s;
  396. if (fd < 0)
  397. switch (status) {
  398. case IO_SRCBLOCK:
  399. slog(LOG_INFO, "%s: delayed sourceblock", logmsg);
  400. break;
  401. case IO_ERROR:
  402. swarn("%s: connection error", logmsg);
  403. break;
  404. case IO_CLOSE:
  405. slog(LOG_INFO, "%s: connection closed", logmsg);
  406. break;
  407. case IO_TIMEOUT:
  408. slog(LOG_INFO, "%s: connection i/o expired", logmsg);
  409. break;
  410. default:
  411. slog(LOG_INFO, "%s: short read/write", logmsg);
  412. }
  413. else if (fd == io->in.s || fd == io->control.s) {
  414. switch (status) {
  415. case IO_SRCBLOCK:
  416. slog(LOG_INFO, "%s: delayed sourceblock", logmsg);
  417. break;
  418. case IO_ERROR:
  419. swarn("%s: client error", logmsg);
  420. break;
  421. case IO_CLOSE:
  422. slog(LOG_INFO, "%s: client closed", logmsg);
  423. break;
  424. case IO_TIMEOUT:
  425. slog(LOG_INFO, "%s: client i/o expired", logmsg);
  426. break;
  427. default:
  428. slog(LOG_INFO, "%s: client short read/write", logmsg);
  429. }
  430. }
  431. else if (fd == io->out.s) {
  432. switch (status) {
  433. case IO_SRCBLOCK:
  434. slog(LOG_INFO, "%s: delayed sourceblock", logmsg);
  435. break;
  436. case IO_ERROR:
  437. swarn("%s: remote error", logmsg);
  438. break;
  439. case IO_CLOSE:
  440. slog(LOG_INFO, "%s: remote closed", logmsg);
  441. break;
  442. case IO_TIMEOUT:
  443. slog(LOG_INFO, "%s: remote i/o expired", logmsg);
  444. break;
  445. default:
  446. slog(LOG_INFO, "%s: remote short read/write", logmsg);
  447. }
  448. }
  449. else
  450. SERRX(fd);
  451. }
  452. /* this may end up logging same disconnect twice, but not our choice. */
  453. if (io->acceptrule.log.disconnect) {
  454. struct connectionstate_t state = io->state;
  455. state.command = SOCKS_DISCONNECT;
  456. iolog(&io->acceptrule, &state, OPERATION_DISCONNECT, &io->src, &io->dst,
  457. NULL, 0);
  458. }
  459. close_iodescriptors(io);
  460. io->allocated = 0;
  461. if (mother != -1) {
  462. const char b = SOCKD_FREESLOT;
  463. /* ack io slot free. */
  464. if (writen(mother, &b, sizeof(b)) != sizeof(b))
  465. swarn("%s: writen(): mother", function);
  466. }
  467. proctitleupdate();
  468. }
  469. void
  470. close_iodescriptors(io)
  471. const struct sockd_io_t *io;
  472. {
  473. close(io->in.s);
  474. close(io->out.s);
  475. switch (io->state.command) {
  476. case SOCKS_CONNECT:
  477. break;
  478. case SOCKS_BIND:
  479. case SOCKS_BINDREPLY:
  480. if (!io->state.extension.bind)
  481. break;
  482. /* else: */ /* FALLTHROUGH */
  483. case SOCKS_UDPASSOCIATE:
  484. close(io->control.s);
  485. break;
  486. default:
  487. SERRX(io->state.command);
  488. }
  489. }
  490. int
  491. recv_io(s, io)
  492. int s;
  493. struct sockd_io_t *io;
  494. {
  495. const char *function = "recv_io()";
  496. int i, fdexpect, fdreceived;
  497. size_t length = 0;
  498. struct iovec iovec[1];
  499. struct msghdr msg;
  500. CMSG_AALLOC(sizeof(int) * FDPASS_MAX);
  501. if (io == NULL) { /* child semantics; find a io ourselves. */
  502. for (i = 0; i < ioc; ++i)
  503. if (!iov[i].allocated) {
  504. io = &iov[i];
  505. break;
  506. }
  507. if (io == NULL) {
  508. /*
  509.  * either mother died/closed connection, or there is another error.
  510.  * Both cases should be rare so try to find out what the problem is.
  511.  */
  512. char buf;
  513. if (recv(s, &buf, sizeof(buf), MSG_PEEK) > 0)
  514. SERRX(allocated());
  515. return -1;
  516. }
  517. }
  518. iovec[0].iov_base = io;
  519. iovec[0].iov_len = sizeof(*io);
  520. length   += iovec[0].iov_len;
  521. msg.msg_iov = iovec;
  522. msg.msg_iovlen = ELEMENTS(iovec);
  523. msg.msg_name = NULL;
  524. msg.msg_namelen = 0;
  525. CMSG_SETHDR_RECV(sizeof(cmsgmem));
  526. if (recvmsgn(s, &msg, 0, length) != (ssize_t)length) {
  527. swarn("%s: recvmsgn()", function);
  528. return -1;
  529. }
  530. /* figure out how many descriptors we are supposed to be passed. */
  531. switch (io->state.command) {
  532. case SOCKS_BIND:
  533. case SOCKS_BINDREPLY:
  534. if (io->state.extension.bind)
  535. fdexpect = 3; /* in, out, control. */
  536. else
  537. fdexpect = 2; /* in and out. */
  538. break;
  539. case SOCKS_CONNECT:
  540. fdexpect = 2; /* in and out */
  541. break;
  542. case SOCKS_UDPASSOCIATE:
  543. fdexpect = 3; /* in, out, and control */
  544. break;
  545. default:
  546. SERRX(io->state.command);
  547. }
  548. /* calculate expected datalen */
  549. #if !HAVE_DEFECT_RECVMSG
  550. SASSERT(CMSG_GETLEN(msg) == sizeof(int) * fdexpect);
  551. #endif
  552. /*
  553.  * Get descriptors sent us.
  554.  */
  555. fdreceived = 0;
  556. CMSG_GETOBJECT(io->in.s, sizeof(io->in.s) * fdreceived++);
  557. CMSG_GETOBJECT(io->out.s, sizeof(io->out.s) * fdreceived++);
  558. switch (io->state.command) {
  559. case SOCKS_BIND:
  560. case SOCKS_BINDREPLY:
  561. if (io->state.extension.bind)
  562. CMSG_GETOBJECT(io->control.s, sizeof(io->control.s) * fdreceived++);
  563. else
  564. io->control.s = -1;
  565. break;
  566. case SOCKS_CONNECT:
  567. io->control.s = -1;
  568. break;
  569. case SOCKS_UDPASSOCIATE:
  570. CMSG_GETOBJECT(io->control.s, sizeof(io->control.s) * fdreceived++);
  571. break;
  572. default:
  573. SERRX(io->state.command);
  574. }
  575. time(&io->time);
  576. io->allocated = 1;
  577. #if DEBUG
  578. printfd(io, "received");
  579. #endif
  580. return 0;
  581. }
  582. static void
  583. io_clearset(io, set)
  584. const struct sockd_io_t *io;
  585. fd_set *set;
  586. {
  587. FD_CLR(io->in.s, set);
  588. FD_CLR(io->out.s, set);
  589. switch (io->state.command) {
  590. case SOCKS_CONNECT:
  591. break;
  592. case SOCKS_BIND:
  593. case SOCKS_BINDREPLY:
  594. if (!io->state.extension.bind)
  595. break;
  596. /* else: */ /* FALLTHROUGH */
  597. case SOCKS_UDPASSOCIATE:
  598. FD_CLR(io->control.s, set);
  599. break;
  600. default:
  601. SERRX(io->state.command);
  602. }
  603. }
  604. static int
  605. allocated(void)
  606. {
  607. int i, alloc;
  608. for (i = 0, alloc = 0; i < ioc; ++i)
  609. if (iov[i].allocated)
  610. ++alloc;
  611. return alloc;
  612. }
  613. static void
  614. doio(mother, io, rset, wset, flags)
  615. int mother;
  616. struct sockd_io_t *io;
  617. fd_set *rset, *wset;
  618. int flags;
  619. {
  620. const char *function = "doio()";
  621. /* CONSTCOND */
  622. char buf[MAX(SOCKD_BUFSIZETCP, SOCKD_BUFSIZEUDP)
  623. + sizeof(struct udpheader_t)];
  624. ssize_t r, w;
  625. SASSERTX(io->allocated);
  626. SASSERTX((FD_ISSET(io->in.s, rset) && FD_ISSET(io->out.s, wset))
  627. || (FD_ISSET(io->in.s, wset) && FD_ISSET(io->out.s, rset))
  628. || (flags & MSG_OOB)
  629. || (io->control.s != -1 && FD_ISSET(io->control.s, rset)));
  630. switch (io->state.protocol) {
  631. case SOCKS_TCP: {
  632. int bad;
  633. /* from in to out... */
  634. if (FD_ISSET(io->in.s, rset) && FD_ISSET(io->out.s, wset)) {
  635. bad = -1;
  636. r = io_rw(&io->in, &io->out, &bad, buf, flags);
  637. if (bad != -1) {
  638. delete_io(mother, io, bad, r);
  639. return;
  640. }
  641. iolog(&io->rule, &io->state, OPERATION_IO, &io->src, &io->dst, buf,
  642. (size_t)r);
  643. }
  644. /* ... and out to in. */
  645. if (FD_ISSET(io->out.s, rset) && FD_ISSET(io->in.s, wset)) {
  646. bad = -1;
  647. r = io_rw(&io->out, &io->in, &bad, buf, flags);
  648. if (bad != -1) {
  649. delete_io(mother, io, bad, r);
  650. return;
  651. }
  652. iolog(&io->rule, &io->state, OPERATION_IO, &io->dst, &io->src, buf,
  653. (size_t)r);
  654. }
  655. break;
  656. }
  657. case SOCKS_UDP: {
  658. struct udpheader_t header;
  659. socklen_t fromlen;
  660. int permit;
  661. /*
  662.  * UDP is sadly considerably more complex than TCP;
  663.  * need to check rules on each packet, need to check if it
  664.  * was received from expected src, etc.
  665.  */
  666. /* udp to relay from client to destination? */
  667. if (FD_ISSET(io->in.s, rset) && FD_ISSET(io->out.s, wset)) {
  668. const int lflags = flags & ~MSG_OOB;
  669. struct sockaddr from;
  670. fromlen = sizeof(from);
  671. if ((r = recvfrom(io->in.s, buf, io->out.sndlowat, lflags, &from,
  672. &fromlen)) == -1) {
  673. delete_io(mother, io, io->in.s, r);
  674. return;
  675. }
  676. UDPFROMLENCHECK(io->in.s, fromlen);
  677. /*
  678.  * If client hasn't sent us it's address yet we have to
  679.  * assume the first packet is from is it.
  680.  * Client can only blame itself if not.
  681.  */
  682. if (io->in.raddr.sin_addr.s_addr == htonl(INADDR_ANY)
  683. ||  io->in.raddr.sin_port == htons(0)) {
  684. if (io->in.raddr.sin_addr.s_addr == htonl(INADDR_ANY))
  685. /* LINTED pointer casts may be troublesome */
  686. io->in.raddr.sin_addr.s_addr
  687. = ((struct sockaddr_in *)&from)->sin_addr.s_addr;
  688. if (io->in.raddr.sin_port == htons(0))
  689. /* LINTED pointer casts may be troublesome */
  690. io->in.raddr.sin_port
  691. = ((struct sockaddr_in *)&from)->sin_port;
  692. /* LINTED pointer casts may be troublesome */
  693. sockaddr2sockshost((struct sockaddr *)&io->in.raddr, &io->src);
  694. }
  695. /*
  696.  * When we receive the first packet we also have a fixed source
  697.  * so connect the socket, both for better performance and so
  698.  * that getpeername() will work on it (libwrap/rulespermit()).
  699.  */
  700. if (io->in.read == 0) { /* could happen more than once, but ok. */
  701. struct connectionstate_t rstate;
  702. /* LINTED pointer casts may be troublesome */
  703. if (!sockaddrareeq((struct sockaddr *)&io->in.raddr, &from)) {
  704. char src[MAXSOCKADDRSTRING], dst[MAXSOCKADDRSTRING];
  705. /* perhaps this should be LOG_DEBUG. */
  706. slog(LOG_NOTICE,
  707. "%s(0): %s: expected from %s, got it from %s",
  708. VERDICT_BLOCKs, protocol2string(io->state.protocol),
  709. /* LINTED pointer casts may be troublesome */
  710. sockaddr2string((struct sockaddr *)&io->in.raddr, src,
  711. sizeof(src)), sockaddr2string(&from, dst, sizeof(dst)));
  712. break;
  713. }
  714. if (connect(io->in.s, &from, sizeof(from)) != 0) {
  715. delete_io(mother, io, io->in.s, IO_ERROR);
  716. return;
  717. }
  718. rstate = io->state;
  719. rstate.command = SOCKS_UDPREPLY;
  720. if (!rulespermit(io->in.s, &io->rule, &io->state, &io->src, NULL)
  721. &&  !rulespermit(io->in.s, &io->rule, &rstate, NULL, &io->src)) {
  722. /* can't send, can't receive; drop it. */
  723. delete_io(mother, io, io->in.s, IO_SRCBLOCK);
  724. return;
  725. }
  726. }
  727. io->in.read += r;
  728. /* got packet, pull out socks udp header. */
  729. if (string2udpheader(buf, (size_t)r, &header) == NULL) {
  730. char badfrom[MAXSOCKADDRSTRING];
  731. /* LINTED pointer casts may be troublesome */
  732. swarnx("%s: bad socks udppacket (length = %d) from %s",
  733. function, r, sockaddr2string((struct sockaddr *)&io->in.raddr,
  734. badfrom, sizeof(badfrom)));
  735. break;
  736. }
  737. if (header.frag != 0) {
  738. char badfrom[MAXSOCKADDRSTRING];
  739. /* LINTED pointer casts may be troublesome */
  740. swarnx("%s: %s: fragmented packet from %s.  Not supported",
  741. function, protocol2string(io->state.protocol),
  742. sockaddr2string((struct sockaddr *)&io->in.raddr, badfrom,
  743. sizeof(badfrom)));
  744. break;
  745. }
  746. io->dst = header.host;
  747. /* is the packet to be permitted out? */
  748. permit
  749. = rulespermit(io->in.s, &io->rule, &io->state, &io->src, &io->dst);
  750. /* set r to bytes sent by client sans socks udp header. */
  751. r -= PACKETSIZE_UDP(&header);
  752. iolog(&io->rule, &io->state, OPERATION_IO, &io->src, &io->dst,
  753. &buf[PACKETSIZE_UDP(&header)], (size_t)r);
  754. if (!permit)
  755. break;
  756. /* LINTED pointer casts may be troublesome */
  757. sockshost2sockaddr(&header.host, (struct sockaddr *)&io->out.raddr);
  758. /* LINTED pointer casts may be troublesome */
  759. if ((w = sendto(io->out.s, &buf[PACKETSIZE_UDP(&header)],
  760. (size_t)r, lflags, (struct sockaddr *)&io->out.raddr,
  761. sizeof(io->out.raddr))) != r)
  762. iolog(&io->rule, &io->state, OPERATION_ERROR, &io->src, &io->dst,
  763. NULL, 0);
  764. io->out.written += MAX(0, w);
  765. }
  766. /*
  767.  * Datagram reply from remote present?
  768.  * We first peek at it so we can find out what address it's from,
  769.  * then we check rules and then we read the packet out of the buffer.
  770.  * Reason why we first peek is that if the rule calls libwrap,
  771.  * libwrap would hang since we'd already read the packet and it
  772.  * wants to peek itself.
  773.  * We only peek enough to get the source but this still involves
  774.  * an extra systemcall.  Can we find a better/faster way to do it?
  775.  */
  776. if (FD_ISSET(io->out.s, rset) && FD_ISSET(io->in.s, wset)) {
  777. const int lflags = flags & ~MSG_OOB;
  778. struct connectionstate_t state;
  779. struct sockaddr from;
  780. struct sockshost_t srcsh;
  781. char *newbuf;
  782. /* MSG_PEEK because of libwrap, see above. */
  783. fromlen = sizeof(from);
  784. if ((r = recvfrom(io->out.s, buf, 1, lflags | MSG_PEEK, &from,
  785. &fromlen)) == -1) {
  786. delete_io(mother, io, io->out.s, r);
  787. return;
  788. }
  789. UDPFROMLENCHECK(io->out.s, fromlen);
  790. /*
  791.  * We can get some problems here in the case that
  792.  * the client sends a hostname for destination.
  793.  * If it does it probably means it can't resolve and if
  794.  * we then send it a ipaddress as source, the client
  795.  * wont be able to match our source as it's destination,
  796.  * even if they are the same.
  797.  * We check for this case specifically, though we only catch
  798.  * the last case, which may not always be good enough.
  799.  * We could expand the below check, using addressmatch()
  800.  * instead, but that need not always be right.
  801.  * Better safe than sorry for now.
  802.  */
  803. /* LINTED possible pointer alignment problem */
  804. if (io->dst.atype == SOCKS_ADDR_DOMAIN
  805. && sockaddrareeq((struct sockaddr *)&io->out.raddr, &from))
  806. srcsh = io->dst;
  807. else
  808. sockaddr2sockshost(&from, &srcsh);
  809. /* only set temporary here for one replypacket at a time. */
  810. state = io->state;
  811. state.command = SOCKS_UDPREPLY;
  812. permit
  813. = rulespermit(io->out.s, &io->rule, &state, &srcsh, &io->src);
  814. /* read the peeked packet out of the buffer. */
  815. fromlen = sizeof(from);
  816. if ((r = recvfrom(io->out.s, buf, io->in.sndlowat, lflags, &from,
  817. &fromlen)) == -1) {
  818. delete_io(mother, io, io->out.s, r);
  819. return;
  820. }
  821. io->out.read += r;
  822. iolog(&io->rule, &state, OPERATION_IO, &srcsh, &io->src, buf,
  823. (size_t)r);
  824. if (!permit)
  825. break;
  826. /* add socks udpheader.  */
  827. /* LINTED pointer casts may be troublesome */
  828. newbuf = udpheader_add(&srcsh, buf, (size_t *)&r, sizeof(buf));
  829. SASSERTX(newbuf == buf);
  830. /*
  831.  * XXX socket must be connected but that should always be the
  832.  * case for now since binding udp addresses is not supported.
  833.  */
  834. if ((w = sendto(io->in.s, newbuf, (size_t)r, lflags, NULL, 0))
  835. != r)
  836. iolog(&io->rule, &state, OPERATION_ERROR, &srcsh, &io->src,
  837. NULL, 0);
  838. io->in.written += MAX(0, w);
  839. }
  840. break;
  841. }
  842. default:
  843. SERRX(io->state.protocol);
  844. }
  845. /*
  846.  * Only thing we expect from client's control connection is a eof.
  847.  * For commands that do not have a controlconnection, we
  848.  * set descriptor to -1 when receiving others.
  849.  */
  850. if (io->control.s != -1 && FD_ISSET(io->control.s, rset)) {
  851. if ((r = read(io->control.s, buf, sizeof(buf))) <= 0)
  852. delete_io(mother, io, io->control.s, r);
  853. else {
  854. char *unexpected, hmmread[MAXSOCKADDRSTRING];
  855. slog(LOG_NOTICE, "%s/control: %d unexpected bytes: %s",
  856. /* LINTED pointer casts may be troublesome */
  857. sockaddr2string((struct sockaddr *)&io->control.raddr, hmmread,
  858. sizeof(hmmread)), r, strcheck(unexpected = str2vis(buf, r)));
  859. free(unexpected);
  860. }
  861. }
  862. /* don't care what direction/descriptors i/o was done over. */
  863. time(&io->time);
  864. }
  865. static int
  866. io_rw(in, out, bad, buf, flag)
  867. struct sockd_io_direction_t *in;
  868. struct sockd_io_direction_t *out;
  869. int *bad;
  870. char *buf;
  871. int flag;
  872. {
  873. ssize_t r, w;
  874. size_t len;
  875. if (flag & MSG_OOB)
  876. if (sockatmark(in->s) != 1)
  877. flag &= ~MSG_OOB;
  878. /* we receive oob inline. */
  879. len = flag & MSG_OOB ? 1 : out->sndlowat;
  880. if ((r = recv(in->s, buf, len, flag & ~MSG_OOB)) <= 0) {
  881. *bad = in->s;
  882. return r;
  883. }
  884. in->read += r;
  885. if (flag & MSG_OOB)
  886. in->flags |= MSG_OOB; /* read oob data. */
  887. else
  888. in->flags &= ~MSG_OOB; /* did not read oob data. */
  889. if ((w = send(out->s, buf, (size_t)r, flag)) != r) {
  890. *bad = out->s;
  891. return w;
  892. }
  893. out->written += w;
  894. return w;
  895. }
  896. static void
  897. proctitleupdate(void)
  898. {
  899. setproctitle("iorelayer: %d/%d", allocated(), SOCKD_IOMAX);
  900. }
  901. static struct sockd_io_t *
  902. io_getset(set)
  903. fd_set *set;
  904. {
  905. int i;
  906. for (i = 0; i < ioc; ++i)
  907. if (iov[i].allocated) {
  908. if (FD_ISSET(iov[i].in.s, set))
  909. return &iov[i];
  910. if (FD_ISSET(iov[i].out.s, set))
  911. return &iov[i];
  912. switch (iov[i].state.command) {
  913. case SOCKS_BIND:
  914. case SOCKS_BINDREPLY:
  915. if (!iov[i].state.extension.bind)
  916. break;
  917. /* else: */ /* FALLTHROUGH */
  918. case SOCKS_UDPASSOCIATE:
  919. if (FD_ISSET(iov[i].control.s, set))
  920. return &iov[i];
  921. break;
  922. default:
  923. break;
  924. }
  925. }
  926. return NULL;
  927. }
  928. static struct sockd_io_t *
  929. io_finddescriptor(d)
  930. int d;
  931. {
  932. int i;
  933. for (i = 0; i < ioc; ++i)
  934. if (iov[i].allocated) {
  935. if (d == iov[i].in.s ||  d == iov[i].out.s)
  936. return &iov[i];
  937. switch (iov[i].state.command) {
  938. case SOCKS_BIND:
  939. case SOCKS_BINDREPLY:
  940. if (!iov[i].state.extension.bind)
  941. break;
  942. /* else: */ /* FALLTHROUGH */
  943. case SOCKS_UDPASSOCIATE:
  944. if (d == iov[i].control.s)
  945. return &iov[i];
  946. break;
  947. default:
  948. break;
  949. }
  950. }
  951. return NULL;
  952. }
  953. static int
  954. io_fillset(set, antiflags)
  955. fd_set *set;
  956. int antiflags;
  957. {
  958. int i, max;
  959. FD_ZERO(set);
  960. for (i = 0, max = -1; i < ioc; ++i)
  961. if (iov[i].allocated) {
  962. if (! (antiflags & iov[i].in.flags)) {
  963. FD_SET(iov[i].in.s, set);
  964. max = MAX(max, iov[i].in.s);
  965. }
  966. if (! (antiflags & iov[i].out.flags)) {
  967. FD_SET(iov[i].out.s, set);
  968. max = MAX(max, iov[i].out.s);
  969. }
  970. switch (iov[i].state.command) {
  971. case SOCKS_BIND:
  972. case SOCKS_BINDREPLY:
  973. if (!iov[i].state.extension.bind)
  974. break;
  975. /* else: */ /* FALLTHROUGH */
  976. case SOCKS_UDPASSOCIATE:
  977. if (! (antiflags & iov[i].control.flags)) {
  978. FD_SET(iov[i].control.s, set);
  979. max = MAX(max, iov[i].control.s);
  980. }
  981. break;
  982. default:
  983. break;
  984. }
  985. }
  986. return max;
  987. }
  988. static struct timeval *
  989. io_gettimeout(timeout)
  990. struct timeval *timeout;
  991. {
  992. time_t timenow;
  993. int i;
  994. if (allocated() == 0 || config.timeout.io == 0)
  995. return NULL;
  996. timeout->tv_sec = config.timeout.io;
  997. timeout->tv_usec = 0;
  998. time(&timenow);
  999. for (i = 0; i < ioc; ++i)
  1000. if (!iov[i].allocated)
  1001. continue;
  1002. else
  1003. timeout->tv_sec = MAX(0, MIN(timeout->tv_sec,
  1004. difftime(config.timeout.io, (time_t)difftime(timenow, iov[i].time))));
  1005. return timeout;
  1006. }
  1007. static struct sockd_io_t *
  1008. io_gettimedout(void)
  1009. {
  1010. int i;
  1011. time_t timenow;
  1012. if (config.timeout.io == 0)
  1013. return NULL;
  1014. time(&timenow);
  1015. for (i = 0; i < ioc; ++i)
  1016. if (!iov[i].allocated)
  1017. continue;
  1018. else
  1019. if (difftime(timenow, iov[i].time) >= config.timeout.io)
  1020. return &iov[i];
  1021. return NULL;
  1022. }
  1023. static void
  1024. checkmother(mother, readset)
  1025. struct sockd_mother_t *mother;
  1026. fd_set *readset;
  1027. {
  1028. if (mother->s != -1 && FD_ISSET(mother->s, readset)) {
  1029. FD_CLR(mother->s, readset);
  1030. if (recv_io(mother->s, NULL) != 0) {
  1031. close(mother->s);
  1032. close(mother->ack);
  1033. mother->s = mother->ack = -1;
  1034. }
  1035. else
  1036. proctitleupdate();
  1037. }
  1038. }
  1039. /* ARGSUSED */
  1040. static void
  1041. siginfo(sig)
  1042. int sig;
  1043. {
  1044. int i;
  1045. time_t timenow;
  1046. time(&timenow);
  1047. for (i = 0; i < ioc; ++i)
  1048. if (!iov[i].allocated)
  1049. continue;
  1050. else {
  1051. char srcstring[MAXSOCKSHOSTSTRING];
  1052. char dststring[MAXSOCKSHOSTSTRING];
  1053. slog(LOG_INFO, "%s <-> %s: idle %.0fs",
  1054. sockshost2string(&iov[i].src, srcstring, sizeof(srcstring)),
  1055. sockshost2string(&iov[i].dst, dststring, sizeof(dststring)),
  1056. difftime(timenow, iov[i].time));
  1057. }
  1058. }