1 /*
2 * Copyright (c) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008,
3 * 2009, 2010, 2011, 2012, 2013, 2014, 2016
4 * Inferno Nettverk A/S, Norway. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. The above copyright notice, this list of conditions and the following
10 * disclaimer must appear in all copies of the software, derivative works
11 * or modified versions, and any portions thereof, aswell as in all
12 * supporting documentation.
13 * 2. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by
16 * Inferno Nettverk A/S, Norway.
17 * 3. The name of the author may not be used to endorse or promote products
18 * derived from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 *
31 * Inferno Nettverk A/S requests users of this software to return to
32 *
33 * Software Distribution Coordinator or sdc@inet.no
34 * Inferno Nettverk A/S
35 * Oslo Research Park
36 * Gaustadall�en 21
37 * NO-0349 Oslo
38 * Norway
39 *
40 * any improvements or extensions that they make and grant Inferno Nettverk A/S
41 * the rights to redistribute these changes.
42 *
43 */
44
45 #include "common.h"
46
47 static const char rcsid[] =
48 "$Id: io.c,v 1.342.4.7.2.3 2017/01/31 08:17:38 karls Exp $";
49
50 static void
51 print_selectfds(const char *preamble, const int docheck, const int nfds,
52 fd_set *rset, fd_set *bufrset, fd_set *buffwset,
53 fd_set *wset, fd_set *xset,
54 const struct timespec *timeout);
55
56 ssize_t
socks_recvfromn(s,buf,len,minread,flags,from,fromlen,recvflags,auth)57 socks_recvfromn(s, buf, len, minread, flags, from, fromlen, recvflags, auth)
58 const int s;
59 void *buf;
60 const size_t len;
61 const size_t minread;
62 const int flags;
63 struct sockaddr_storage *from;
64 socklen_t *fromlen;
65 recvfrom_info_t *recvflags;
66 authmethod_t *auth;
67 {
68 const char *function = "socks_recvfromn()";
69 static fd_set *rset;
70 ssize_t p;
71 size_t left;
72
73 if (rset == NULL)
74 rset = allocate_maxsize_fdset();
75
76 left = len;
77 do {
78 #if SOCKS_CLIENT
79 /*
80 * If this changes between now and the return of socks_recvfrom(),
81 * the change must have been done in the signal handler. We then
82 * assume it's due to us receiving a signal from our connectchild
83 * process.
84 */
85 sockscf.state.handledsignal = 0;
86 #endif /* SOCKS_CLIENT */
87
88 if ((p = socks_recvfrom(s,
89 &((char *)buf)[len - left],
90 left,
91 flags,
92 from,
93 fromlen,
94 recvflags,
95 auth)) == -1) {
96 #if !SOCKS_CLIENT
97
98 if (errno == EINTR) {
99 errno = 0;
100 continue; /* just retry directly. */
101 }
102
103 if (ERRNOISTMP(errno) && len - left < minread) {
104 /*
105 * Some other error, also non-fatal though, so also retry.
106 */
107
108 errno = 0;
109 FD_ZERO(rset);
110 FD_SET(s, rset);
111
112 if (select(s + 1, rset, NULL, NULL, NULL) == 1)
113 continue;
114
115 if (errno == EINTR)
116 continue;
117
118 SWARNX(errno); /* unexpected error. */
119 break;
120 }
121 else {
122 slog(LOG_DEBUG, "%s: non-temporary read error: %s",
123 function, strerror(errno));
124
125 break;
126 }
127
128 #else /* SOCKS_CLIENT */
129
130 if (errno == EINTR) {
131 if (sockscf.state.handledsignal) {
132 /*
133 * Can't know for sure, but assume we were interrupted due
134 * to a signal from our own non-blocking connect child,
135 * presumably signalling a connect(2) unrelated to this socket
136 * has completed.
137 */
138 slog(LOG_DEBUG,
139 "%s: read was interrupted, but looks like it could be due "
140 "to our own signal (signal #%d/%s), so assume we should "
141 "retry",
142 function,
143 (int)sockscf.state.handledsignal,
144 signal2string(sockscf.state.handledsignal));
145
146 sockscf.state.handledsignal = 0;
147 continue;
148 }
149 }
150
151 /*
152 * Else: not a signal related to us. Break out and let client retry
153 * itself if it wants to.
154 */
155 break;
156 #endif /* SOCKS_CLIENT */
157 }
158 else if (p == 0)
159 break;
160
161 SASSERTX(p > 0);
162
163 left -= (size_t)p;
164 } while (len - left < minread);
165
166 if (left == len)
167 return p; /* nothing read. */
168
169 return len - left;
170 }
171
172 ssize_t
socks_sendton(s,buf,len,minwrite,flags,to,tolen,sendtoflags,auth)173 socks_sendton(s, buf, len, minwrite, flags, to, tolen, sendtoflags, auth)
174 int s;
175 const void *buf;
176 size_t len;
177 const size_t minwrite;
178 int flags;
179 const struct sockaddr_storage *to;
180 socklen_t tolen;
181 sendto_info_t *sendtoflags;
182 authmethod_t *auth;
183 {
184 const char *function = "socks_sendton()";
185 static fd_set *wset;
186 ssize_t p;
187 size_t left = len;
188
189 if (wset == NULL)
190 wset = allocate_maxsize_fdset();
191
192 SASSERTX(minwrite <= len);
193
194 do {
195 if ((p = socks_sendto(s,
196 &((const char *)buf)[len - left],
197 left,
198 flags,
199 to,
200 tolen,
201 sendtoflags,
202 auth)) == -1) {
203 #if !SOCKS_CLIENT
204 if (errno == EINTR)
205 continue;
206 #endif /* !SOCKS_CLIENT */
207
208 if ((errno == EAGAIN || errno == EWOULDBLOCK) && minwrite > 0) {
209 errno = 0;
210
211 FD_ZERO(wset);
212 FD_SET(s, wset);
213 if (selectn(s + 1, NULL, NULL, NULL, wset, NULL, NULL) == -1) {
214 if (errno != EINTR)
215 swarn("%s: select()", function);
216
217 return -1;
218 }
219
220 continue;
221 }
222
223 break;
224 }
225
226 left -= (size_t)p;
227
228 if (sendtoflags != NULL)
229 sendtoflags->tosocket += p;
230 } while ((len - left) < minwrite);
231
232 return len - left;
233 }
234
235 ssize_t
socks_recvfrom(s,buf,len,flags,from,fromlen,recvflags,auth)236 socks_recvfrom(s, buf, len, flags, from, fromlen, recvflags, auth)
237 int s;
238 void *buf;
239 size_t len;
240 int flags;
241 struct sockaddr_storage *from;
242 socklen_t *fromlen;
243 recvfrom_info_t *recvflags;
244 authmethod_t *auth;
245 {
246 const char *function = "socks_recvfrom()";
247 ssize_t r;
248 #if !SOCKS_CLIENT
249 size_t toread, tocaller, tobuf;
250 ssize_t readfrombuf;
251 char tmpbuf[MAX(sizeof(sockd_io_t), SOCKD_BUFSIZE)];
252 #endif /* !SOCKS_CLIENT */
253
254 if (sockscf.option.debug >= DEBUG_VERBOSE)
255 slog(LOG_DEBUG, "%s: fd %d, len %lu, flags %d",
256 function, s, (unsigned long)len, flags);
257
258 if (auth != NULL)
259 SASSERTX(authmethodisknown(auth->method));
260
261 if (recvflags != NULL) {
262 recvflags->flags = 0;
263 recvflags->fromsocket = 0;
264 timerclear(&recvflags->ts);
265 }
266
267 #if HAVE_GSSAPI
268 if (auth != NULL
269 && auth->method == AUTHMETHOD_GSSAPI && auth->mdata.gssapi.state.wrap)
270 return gssapi_decode_read(s,
271 buf,
272 len,
273 flags,
274 from,
275 fromlen,
276 recvflags,
277 &auth->mdata.gssapi.state);
278 #endif /* HAVE_GSSAPI */
279
280 #if SOCKS_CLIENT
281 SASSERTX(recvflags == NULL);
282
283 /*
284 * no buffering is provided by us for the client, except if using gssapi,
285 * and that is handled in the above function.
286 */
287 if (from == NULL && flags == 0)
288 /* may not be a socket and read(2) will work just as well then. */
289 r = read(s, buf, len);
290 else
291 r = recvfrom(s, buf, len, flags, TOSA(from), fromlen);
292
293 if (sockscf.option.debug >= DEBUG_VERBOSE)
294 slog(LOG_DEBUG, "%s: read %ld byte%s, errno = %d (%s)",
295 function, (long)r, r == 1 ? "" : "s", errno, strerror(errno));
296
297 if (r >= 0)
298 /*
299 * Some systems return bytes read, yet still set errno. In particular,
300 * OpenBSD 4.5's thread implementation does this sometimes.
301 * Clearly wrong, but what can we do. :-/
302 */
303 errno = 0;
304
305 return r;
306
307 #else /* SOCKS_SERVER */
308
309 /*
310 * Return data from the buffer first, if non-empty, then read data from
311 * socket if needed.
312 */
313
314 /*
315 * mother does not use iobuf's, so don't waste time scanning through
316 * a static array of iobuf's looking for something that is not there.
317 */
318 if (sockscf.state.type == PROC_MOTHER) {
319 SASSERTX(flags == 0);
320 SASSERTX(from == NULL);
321 SASSERTX(fromlen == NULL);
322 SASSERTX(auth == NULL);
323 SASSERTX(recvflags == NULL);
324
325 return read(s, buf, len);
326 }
327
328 /*
329 * else; child. Sockd children use iobufs, but mother does not.
330 */
331
332 if ((readfrombuf = socks_getfrombuffer(s, flags, READ_BUF, 0, buf, len)) > 0)
333 {
334 if (sockscf.option.debug >= DEBUG_VERBOSE) {
335 slog(LOG_DEBUG, "%s: read %lu byte from buf, %lu bytes left in buf",
336 function,
337 (unsigned long)readfrombuf,
338 (unsigned long)socks_bytesinbuffer(s, READ_BUF, 0));
339 }
340 }
341
342 if ((size_t)readfrombuf >= len)
343 return readfrombuf;
344
345 /*
346 * If we have a buffer allocated, assume it's safe to read
347 * as much as it can hold, as it make things much more efficient
348 * to do subsequent reads from the buffer (i.e., like fread()).
349 */
350 if (socks_getbuffer(s) == NULL)
351 r = len;
352 else
353 r = MIN(socks_freeinbuffer(s, READ_BUF), sizeof(tmpbuf));
354
355 if (r <= 0)
356 return readfrombuf;
357
358 /*
359 * Now read as much as we can into the tmpbuf, and later check what
360 * can be copied back to caller this time, and what needs to be stored
361 * in iobuf for later.
362 */
363
364 toread = (size_t)r;
365
366 if (from == NULL && flags == 0 && recvflags == NULL)
367 /*
368 * may not be a socket and read(2) will work just as well then,
369 * while recvfrom(2) will fail if not a socket.
370 */
371 r = read(s, tmpbuf, toread);
372 else {
373 const socklen_t passed_fromlen = (fromlen == NULL ? 0 : *fromlen);
374 static int failures, failed_socket;
375 struct msghdr msg;
376 struct iovec iov = { tmpbuf, toread };
377 CMSG_AALLOC(cmsg, sizeof(recvflags->ts));
378
379 bzero(&msg, sizeof(msg));
380 msg.msg_name = from;
381 msg.msg_namelen = passed_fromlen;
382 msg.msg_iov = &iov;
383 msg.msg_iovlen = 1;
384
385 CMSG_SETHDR_RECV(msg, cmsg, CMSG_MEMSIZE(cmsg));
386
387 if ((r = recvmsgn(s, &msg, flags)) == -1) {
388 slog(LOG_DEBUG, "%s: recvmsgn() on fd %d failed (%s)",
389 function, s, strerror(errno));
390
391 #if HAVE_LINUX_BUGS
392 if (errno == 0) {
393 const int errno_s = errno;
394 int isudpsocket;
395
396 if (recvflags != NULL)
397 isudpsocket = recvflags->type == SOCK_DGRAM;
398 else {
399 iobuffer_t *iobuf;
400
401 if ((iobuf = socks_getbuffer(s)) != NULL)
402 isudpsocket = (iobuf->stype == SOCK_DGRAM);
403 else {
404 int type;
405 socklen_t typelen = sizeof(type);
406
407 if (getsockopt(s, SOL_SOCKET, SO_TYPE, &type, &typelen) == 0
408 && type == SOCK_DGRAM)
409 isudpsocket = 1;
410 else
411 isudpsocket = 0;
412 }
413 }
414
415 if (isudpsocket) {
416 swarnx("%s: trying to work around Linux bug. recvmsg(2) "
417 "returned -1, but did not set errno so we can't know "
418 "the reason for the failure. Setting to EAGAIN and "
419 "hoping the best",
420 function);
421
422 errno = EAGAIN;
423 }
424 else
425 errno = errno_s;
426 }
427 #endif
428 }
429 else {
430 if (socks_msghaserrors(function, &msg))
431 r = -1;
432 else if (msg.msg_namelen < sizeof(struct sockaddr_in)
433 && passed_fromlen >= sizeof(struct sockaddr_in)) {
434 /*
435 * Solaris, at least 2.5.1, sometimes fails to return the
436 * srcaddress in recvfrom(2).
437 * More recently it has also been seen at least once on
438 * OS X, Kernel Version 10.8.0, at a point where recvmsg(2)
439 * returned 0.
440 */
441
442 swarnx("%s: kernel/system error: did not get a valid src "
443 "address from recvfrom(2) on fd %d. Got a fromlen "
444 "of %ld for a %ld byte packet",
445 function, s, (long)*fromlen, (long)r);
446
447 if (failures++ >= 4) {
448 /*
449 * don't know if it's the same socket that has failed each
450 * time, but this is a kernel error and should never happen
451 * anyway, so go along like this for now.
452 */
453 swarnx("%s: giving up after %d recvfrom(2) failures",
454 function, failures);
455
456 /* reset. */
457 failures = 0;
458 errno = 0;
459
460 return -1;
461 }
462 else {
463 failed_socket = s;
464
465 errno = EAGAIN;
466 return -1;
467 }
468 }
469 else {
470 if (failed_socket == s)
471 failures = 0; /* reset on first success. */
472
473 if (recvflags != NULL) {
474 recvflags->flags = msg.msg_flags;
475
476 #if HAVE_SO_TIMESTAMP
477 if (CMSG_TOTLEN(msg) != 0) {
478 if (!CMSG_RCPTLEN_ISOK(msg, sizeof(struct timeval))) {
479 swarnx("%s: did not receive a timestamp for packet "
480 "of length %lu (cmsglen is %lu)",
481 function,
482 (unsigned long)r,
483 (unsigned long)CMSG_TOTLEN(msg));
484
485 timerclear(&recvflags->ts);
486 }
487 else {
488 SASSERTX(cmsg->cmsg_level == SOL_SOCKET);
489 SASSERTX(cmsg->cmsg_type == SCM_TIMESTAMP);
490
491 CMSG_GETOBJECT(recvflags->ts, cmsg, 0);
492 }
493 }
494 else
495 timerclear(&recvflags->ts);
496
497 #else /* !HAVE_SO_TIMESTAMP */
498 timerclear(&recvflags->ts);
499
500 #endif /* !HAVE_SO_TIMESTAMP */
501 }
502 }
503 }
504 }
505
506 if (r == -1 && recvflags != NULL && recvflags->type == SOCK_DGRAM)
507 if (ERRNOISPREVIOUSPACKET(errno))
508 log_writefailed(recvflags->side == INTERNALIF ?
509 EXTERNALIF : INTERNALIF,
510 s,
511 &recvflags->peer);
512
513 if (sockscf.option.debug >= DEBUG_VERBOSE)
514 slog(LOG_DEBUG,
515 "%s: read %ld/%lu bytes from socket, fd %d, errno = %d (%s)",
516 function,
517 (long)r,
518 (unsigned long)toread,
519 s,
520 errno,
521 strerror(errno));
522
523 if (r <= 0) {
524 if (readfrombuf <= 0)
525 return r;
526 /*
527 * Else: even if read from socket failed, read from buf did not.
528 */
529 errno = 0;
530 return readfrombuf;
531 }
532 else {
533 if (recvflags != NULL)
534 recvflags->fromsocket += r;
535 }
536
537 tocaller = MIN((size_t)r, len - readfrombuf);
538
539 if (flags & MSG_PEEK)
540 /*
541 * nothing to add to buffer now; will still be in socket next time
542 * and we will add it then.
543 */
544 tobuf = 0;
545 else
546 /*
547 * Add to buffer what we are not returning to caller now.
548 */
549 tobuf = (size_t)r - tocaller;
550
551 memcpy((char *)buf + readfrombuf, tmpbuf, tocaller);
552
553 if (tobuf > 0)
554 socks_addtobuffer(s, READ_BUF, 0, tmpbuf + tocaller, tobuf);
555
556 return readfrombuf + tocaller;
557 #endif /* SOCKS_SERVER */
558 }
559
560 ssize_t
socks_sendto(s,msg,len,flags,to,tolen,sendtoflags,auth)561 socks_sendto(s, msg, len, flags, to, tolen, sendtoflags, auth)
562 int s;
563 const void *msg;
564 size_t len;
565 int flags;
566 const struct sockaddr_storage *to;
567 socklen_t tolen;
568 sendto_info_t *sendtoflags;
569 authmethod_t *auth;
570 {
571 const char *function = "socks_sendto()";
572 ssize_t written;
573 #if !SOCKS_CLIENT
574 ssize_t towrite, written_fb, p;
575 char buf[MAX(sizeof(sockd_io_t), SOCKD_BUFSIZE)];
576 #endif /* !SOCKS_CLIENT */
577
578 if (sockscf.option.debug >= DEBUG_VERBOSE)
579 slog(LOG_DEBUG, "%s: fd %d, len %lu, flags %d, to = %s",
580 function,
581 s,
582 (long unsigned)len,
583 flags,
584 to == NULL ? "NULL" : sockaddr2string(to, NULL, 0));
585
586 if (to != NULL && tolen != 0)
587 tolen = salen(to->ss_family);
588
589 if (auth != NULL)
590 SASSERTX(authmethodisknown(auth->method));
591
592 if (sendtoflags != NULL) {
593 sendtoflags->tosocket = 0;
594
595 #if !SOCKS_CLIENT
596 SASSERTX(sendtoflags->side != NONESETIF);
597 #endif /* !SOCKS_CLIENT */
598 }
599
600 #if HAVE_GSSAPI
601 if (auth != NULL
602 && auth->method == AUTHMETHOD_GSSAPI && auth->mdata.gssapi.state.wrap) {
603 written = gssapi_encode_write(s,
604 msg,
605 len,
606 flags,
607 to,
608 tolen,
609 sendtoflags,
610 &auth->mdata.gssapi.state);
611
612 if (written == -1 && sendtoflags != NULL)
613 log_writefailed(sendtoflags->side, s, to);
614
615 slog(LOG_DEBUG, "%s: gssapi-written on fd %d: %ld (%s)",
616 function, s, (long)written, strerror(errno));
617
618 return written;
619 }
620 #endif
621
622 #if SOCKS_CLIENT
623 /*
624 * no buffering is provided by us for the client, except if using gssapi,
625 * and that is handled in the above function.
626 */
627 if (to == NULL && flags == 0)
628 /* may not be a socket; write(2) will work just as well then. */
629 written = write(s, msg, len);
630 else
631 written = sendto(s, msg, len, flags, TOCSA(to), tolen);
632
633 if (written != -1 && sendtoflags != NULL)
634 sendtoflags->tosocket = written;
635
636 slog(LOG_DEBUG, "%s: written on fd %d: %ld", function, s, (long)written);
637
638 return written;
639 #else /* !SOCKS_CLIENT */
640
641 if ((towrite = socks_getfrombuffer(s, 0, WRITE_BUF, 0, buf, len)) > 0) {
642 /*
643 * already have data for write buffered. Write that first, then
644 * append the new data, then possibly write the new data, but never
645 * write more than "len", even if we could due to data already
646 * buffered. The reason not to write more includes fair sharing
647 * amongst clients.
648 *
649 * Also note that for the data buffered, we have already returned
650 * the byte count as written, so don't return it again, only return
651 * the count for new bytes added to the buffer.
652 */
653
654 if (sockscf.option.debug >= DEBUG_VERBOSE)
655 slog(LOG_DEBUG,
656 "%s: got %lu byte%s from buffer, %lu bytes left in buffer",
657 function,
658 (unsigned long)towrite, towrite == 1 ? "" : "s",
659 (unsigned long)socks_bytesinbuffer(s, WRITE_BUF, 0));
660
661 written_fb = sendto(s, buf, (size_t)towrite, flags, TOCSA(to), tolen);
662
663 if (sendtoflags != NULL) {
664 if (written_fb == -1)
665 log_writefailed(sendtoflags->side, s, to);
666 else
667 sendtoflags->tosocket += written_fb;
668 }
669
670 if (written_fb < towrite) {
671 /*
672 * need to add at least some back in the buffer.
673 */
674 const ssize_t addback = written_fb > 0 ?
675 towrite - written_fb : towrite;
676
677 if ((p = socks_addtobuffer(s,
678 WRITE_BUF,
679 0,
680 buf + (towrite - addback),
681 (size_t)addback)) != addback)
682 SERRX(p);
683 }
684
685 /* can we write more on this call? */
686 if (written_fb == -1) { /* no. */
687 if (!ERRNOISTMP(errno))
688 return -1;
689
690 /* else; non-fatal error. Try to buffer the rest. */
691 towrite = 0;
692 }
693 else { /* yes. */
694 towrite = len - written_fb;
695 }
696 }
697 else /* nothing buffered. */
698 towrite = len;
699
700 if (towrite >= 0) { /* >= 0 because udp packets can be zero. */
701 /*
702 * try to also write some of the data passed us now.
703 */
704
705 if ((written = sendto(s, msg, (size_t)towrite, flags, TOCSA(to), tolen))
706 == -1) {
707 iobuffer_t *iobuf;
708
709 if (sendtoflags != NULL)
710 log_writefailed(sendtoflags->side, s, to);
711
712 slog(LOG_DEBUG, "%s: %s(2) failed: %s",
713 function,
714 to == NULL && flags == 0 ? "write" : "sendto",
715 strerror(errno));
716
717 /*
718 * If not permanent error, try to buffer the data, unless it's a
719 * udp socket, in which case we do not buffer.
720 */
721 if (!ERRNOISTMP(errno)
722 || (iobuf = socks_getbuffer(s)) == NULL
723 || iobuf->stype == SOCK_DGRAM)
724 return written;
725
726 written = 0;
727 }
728 }
729 else
730 written = 0;
731
732 if (sendtoflags != NULL)
733 sendtoflags->tosocket += written;
734
735 SASSERTX(written <= (ssize_t)len);
736
737 towrite = len - written;
738 if (towrite > 0) {
739 iobuffer_t *iobuf;
740 ssize_t written_tb;
741 int dobuffer;
742
743 if ((iobuf = socks_getbuffer(s)) != NULL
744 && iobuf->stype != SOCK_DGRAM)
745 dobuffer = 1;
746 else
747 dobuffer = 0;
748
749 if (sockscf.option.debug >= DEBUG_VERBOSE)
750 slog(LOG_DEBUG, "%s: %lu byte%s unwritten to socket. %s",
751 function,
752 (unsigned long)towrite,
753 towrite == 1 ? "" : "s",
754 dobuffer ? "Adding to buffer" : "");
755
756 if (!dobuffer)
757 return written;
758
759 written_tb = socks_addtobuffer(s,
760 WRITE_BUF,
761 0,
762 (const char *)msg + written,
763 (size_t)towrite);
764 towrite -= written_tb;
765 }
766
767 SASSERTX(towrite == 0);
768
769 return len;
770 #endif /* !SOCKS_CLIENT */
771 }
772
773 ssize_t
recvmsgn(s,msg,flags)774 recvmsgn(s, msg, flags)
775 int s;
776 struct msghdr *msg;
777 int flags;
778 {
779 const char *function = "recvmsgn()";
780 ssize_t received;
781
782 if ((received = recvmsg(s, msg, flags)) == -1)
783 slog(LOG_DEBUG, "%s: recvmsg() on fd %d failed, received %ld bytes%s %s",
784 function,
785 s, (long)received,
786 sockscf.state.insignal ? "" : ":",
787 sockscf.state.insignal ? "" : strerror(errno));
788
789 return received;
790
791 #if 0
792 /*
793 * below code should not be used any longer since we only do recvmsg(2)
794 * on datagram sockets now.
795 */
796
797 if (received <= 0)
798 return received;
799 left = len - (size_t)received;
800
801 if (left > 0) {
802 size_t i, count, done;
803
804 /*
805 * Can't call recvmsg() again since we could be getting ancillary data,
806 * read the elements one by one.
807 */
808
809 SASSERTX(received >= 0);
810
811 done = (size_t)received;
812 i = count = received = 0;
813 while (i < (size_t)msg->msg_iovlen && left > 0) {
814 const struct iovec *io = &msg->msg_iov[i];
815
816 count += io->iov_len;
817 if (count > done) { /* didn't read all of this iovec. */
818 if ((received = socks_recvfromn(s,
819 &((char *)(io->iov_base))[io->iov_len - (count - done)],
820 count - done,
821 count - done,
822 0,
823 NULL,
824 NULL,
825 NULL,
826 NULL,
827 NULL,
828 NULL))
829 != ((ssize_t)(count - done))) {
830 /*
831 * Failed to read all data, close any descriptors we
832 * may have gotten then.
833 */
834 size_t leaked;
835 int d;
836
837 swarn("%s: %ld byte%s left",
838 function, (long)left, left == 1 ? "" : "s");
839
840 for (leaked = 0;
841 CMSG_SPACE(leaked * sizeof(d)) < (size_t)CMSG_TOTLEN(*msg);
842 ++leaked) {
843 CMSG_GETOBJECT(d, CMSG_CONTROLDATA(*msg), leaked * sizeof(d));
844 close(d);
845 }
846
847 break;
848 }
849
850 left -= received;
851 done += received;
852 }
853
854 ++i;
855 }
856 }
857
858 if (left == len)
859 return received; /* nothing read. */
860 return len - left;
861 #endif
862
863 }
864
865 ssize_t
sendmsgn(s,msg,flags,timeoutms)866 sendmsgn(s, msg, flags, timeoutms)
867 int s;
868 const struct msghdr *msg;
869 int flags;
870 const time_t timeoutms;
871 {
872 const char *function = "sendmsgn()";
873 static fd_set *wset;
874 const int maxfailures = 10;
875 struct timeval timestart;
876 ssize_t p, sent;
877 size_t len;
878 int failedcount, sendmsg_errno;
879
880 #if !SOCKS_CLIENT
881 if (sockscf.state.type == PROC_MOTHER)
882 /*
883 * if not, we may end up calling selectn(), and if a SIGCHLD is
884 * pending, we might end up trying to use the descriptor of a child
885 * that was removed by the sigchld handler, or worse.
886 */
887 SASSERTX(timeoutms == 0);
888 #endif /* !SOCKS_CLIENT */
889
890 if (wset == NULL)
891 wset = allocate_maxsize_fdset();
892
893
894 failedcount = len = 0;
895 while ((sent = sendmsg(s, msg, flags)) == -1) {
896 struct timeval timeleft;
897 int doretry = ( ERRNOISTMP(errno)
898 && ++failedcount < maxfailures
899 && timeoutms != 0);
900
901 sendmsg_errno = errno;
902
903 if (len == 0)
904 for (p = 0; p < (ssize_t)msg->msg_iovlen; ++p)
905 len += msg->msg_iov[p].iov_len;
906
907 if (doretry) {
908 const struct timeval max_timetouse = { 0, timeoutms * 1000 };
909 struct timeval timenow;
910
911 if (failedcount == 1)
912 gettimeofday_monotonic(×tart);
913
914 if (timeoutms != -1) {
915 struct timeval timeused;
916
917 gettimeofday_monotonic(&timenow);
918 timersub(&timenow, ×tart, &timeused);
919
920 SASSERTX(timeused.tv_sec >= 0);
921
922 timersub(&max_timetouse, &timeused, &timeleft);
923 if (timeleft.tv_sec < 0)
924 doretry = 0;
925 }
926 }
927
928 slog(LOG_DEBUG,
929 "%s: sendmsg() of %ld bytes on fd %d failed on try #%d (%s)%s",
930 function,
931 (long)len,
932 s,
933 failedcount,
934 strerror(errno),
935 doretry ? ". Will block and retry" : ". Giving up on this one");
936
937 if (!doretry) {
938 if (errno == 0)
939 errno = sendmsg_errno;
940
941 return -1;
942 }
943
944 if (failedcount + 1 >= maxfailures) {
945 if (timeoutms == -1) {
946 /*
947 * even if there is no timeout, we don't want to block forever.
948 * Report the error and go to the next message.
949 */
950 timeleft.tv_sec = 1;
951 timeleft.tv_usec = 0;
952 }
953
954 slog(LOG_DEBUG,
955 "%s: failed %d times already. Next retry is the last one, "
956 "so pausing for %ld.%06lds, hoping the message will get "
957 "through afterwards",
958 function,
959 failedcount,
960 (long)timeleft.tv_sec,
961 (long)timeleft.tv_usec);
962
963 if ((p = selectn(0, NULL, NULL, NULL, NULL, NULL, &timeleft)) <= 0) {
964 slog(LOG_DEBUG, "%s: select() returned %ld, with time %ld.%06ld",
965 function,
966 (long)p,
967 (long)timeleft.tv_sec,
968 (long)timeleft.tv_usec);
969
970 if (errno == 0)
971 errno = sendmsg_errno;
972
973 return -1;
974 }
975
976 continue;
977 }
978
979 FD_ZERO(wset);
980 FD_SET(s, wset);
981 p = selectn(s + 1,
982 NULL,
983 NULL,
984 NULL,
985 wset,
986 NULL,
987 timeoutms == -1 ? NULL : &timeleft);
988
989 if (timeoutms == -1)
990 slog(LOG_DEBUG, "%s: select() returned %d", function, (int)p);
991 else
992 slog(LOG_DEBUG, "%s: select() returned %d, with time %ld.%06ld",
993 function, (int)p, (long)timeleft.tv_sec, (long)timeleft.tv_usec);
994
995 if (p <= 0) {
996 #if SOCKS_CLIENT
997 if (errno == EINTR) {
998 if (sockscf.state.handledsignal) {
999 /*
1000 * Can't know for sure, but assume we were interrupted due
1001 * to a signal from our own non-blocking connect child,
1002 * presumably signalling a connect(2) unrelated to this socket
1003 * has completed.
1004 */
1005 slog(LOG_DEBUG,
1006 "%s: select(2) was interrupted, but looks like it could "
1007 "be due to our own signal (signal #%d/%s), so assume we "
1008 "should retry",
1009 function,
1010 (int)sockscf.state.handledsignal,
1011 signal2string(sockscf.state.handledsignal));
1012
1013 sockscf.state.handledsignal = 0;
1014 continue;
1015 }
1016 }
1017 #endif /* SOCKS_CLIENT */
1018
1019 if (errno == 0)
1020 errno = sendmsg_errno;
1021
1022 return -1;
1023 }
1024 }
1025
1026 return sent;
1027 }
1028
1029 int
selectn(nfds,rset,bufrset,buffwset,wset,xset,_timeout)1030 selectn(nfds, rset, bufrset, buffwset, wset, xset, _timeout)
1031 int nfds;
1032 fd_set *rset;
1033 fd_set *bufrset;
1034 fd_set *buffwset;
1035 fd_set *wset;
1036 fd_set *xset;
1037 struct timeval *_timeout;
1038 {
1039 const char *function = "selectn()";
1040 struct timespec *timeout, timeout_mem, zerotimeout = { 0, 0 };
1041 int i, rc, bufset_nfds;
1042 #if !SOCKS_CLIENT
1043 sigset_t fullmask;
1044 #endif /* !SOCKS_CLIENT */
1045 sigset_t oldmask;
1046
1047 #if DIAGNOSTIC && !SOCKS_CLIENT
1048 static struct timeval tfirstshortsleep;
1049 static size_t shortsleepc;
1050 static fd_set *zeroset;
1051 /*
1052 * These constants are undoubtedly too lenient for some cpus, and
1053 * too strict for other cpu's, but this is what there is for now.
1054 */
1055 const struct timeval tshortsleep = { 0, 2 },
1056 tshorttimelapse = { 0, 100000 };
1057 const size_t maxshortsleepc = 1000;
1058 struct timeval tstart, tend, tdiff;
1059
1060 if (zeroset == NULL) {
1061 zeroset = allocate_maxsize_fdset();
1062 FD_ZERO(zeroset);
1063 }
1064
1065 SASSERTX (_timeout != NULL
1066 || (rset != NULL && FD_CMP(zeroset, rset) != 0)
1067 || (wset != NULL && FD_CMP(zeroset, wset) != 0)
1068 || (xset != NULL && FD_CMP(zeroset, xset) != 0));
1069 #endif /* DIAGNOSTIC && !SOCKS_CLIENT */
1070
1071 #if DO_SHMEMCHECK
1072 shmemcheck();
1073 #endif /* DO_SHMEMCHECK */
1074
1075 /* convert form select(2) timeval to pselect(3) timespec. */
1076 if (_timeout == NULL)
1077 timeout = NULL;
1078 else {
1079 #if HAVE_SELECT_MAXTIMEOUT
1080 struct timeval maxtimeout = { HAVE_SELECT_MAXTIMEOUT, 0 };
1081
1082 if (timercmp(_timeout, &maxtimeout, >))
1083 *_timeout = maxtimeout;
1084 #endif /* HAVE_SELECT_MAXTIMEOUT */
1085
1086 #if !SOCKS_CLIENT
1087 if (_timeout->tv_sec < 0) {
1088 SWARNX(_timeout->tv_sec);
1089 _timeout->tv_sec = 0;
1090 }
1091
1092 if (_timeout->tv_usec < 0) {
1093 SWARNX(_timeout->tv_usec);
1094 _timeout->tv_usec = 0;
1095 }
1096 #endif /* !SOCKS_CLIENT */
1097
1098 timeout = &timeout_mem;
1099 timeout->tv_sec = _timeout->tv_sec;
1100 timeout->tv_nsec = _timeout->tv_usec * 1000;
1101 }
1102
1103 #if SOCKS_CLIENT
1104 if (sockscf.connectchild != 0) { /* we are the mother process. */
1105 /*
1106 * Once there was a bug,
1107 * and SIGIO was blocked,
1108 * but we need SIGIO,
1109 * need it for non-blocking connects,
1110 * and the bug,
1111 * it made us fall asleep,
1112 * and no-one woke us up,
1113 * never ever again.
1114 */
1115
1116
1117 if (sigprocmask(SIG_SETMASK, NULL, &oldmask) != 0)
1118 serr("%s: sigprocmask() failed", function);
1119
1120 SASSERTX(!sigismember(&oldmask, SIGIO));
1121 }
1122
1123 #else /* !SOCKS_CLIENT */
1124
1125 sigfillset(&fullmask);
1126
1127 /*
1128 * Block any new signals until we call pselect(2) to avoid race conditions
1129 * between checking for pending signals with sockd_handledsignals()
1130 * and the pselect(2) call. If not, signals received in that timeframe
1131 * will not be handled till after the pselect(2) returns naturally, but we
1132 * want to them to interrupt pselect(2) instead.
1133 */
1134 if (sigprocmask(SIG_BLOCK, &fullmask, &oldmask) != 0)
1135 SERR(errno);
1136
1137 if (sockd_handledsignals() != 0) {
1138 /*
1139 * When mother gets a signal (e.g., SIGHUP or SIGCHLD), it's possible
1140 * to add or remove descriptors. It is thus not safe to continue with
1141 * the descriptor set we get passed (could get e.g, EBADF); we must
1142 * return and let caller regenerate the fd_set's.
1143 */
1144
1145 if (sigprocmask(SIG_SETMASK, &oldmask, NULL) != 0)
1146 SERR(errno);
1147
1148 errno = EINTR;
1149 return -1;
1150 }
1151 #endif /* !SOCKS_CLIENT */
1152
1153 if (sockscf.option.debug >= DEBUG_VERBOSE) {
1154 char buf[1024];
1155 size_t bufused;
1156 int i;
1157
1158 bufused = 0;
1159 for (i = 1, bufused = 0; i < SOCKS_NSIG; ++i) {
1160 if ((rc = sigismember(&oldmask, i)) == 1)
1161 bufused += snprintf(&buf[bufused], sizeof(buf) - bufused,
1162 "%d, ", i);
1163 else if (rc == -1)
1164 /*
1165 * May happen if SOCKS_NSIG is overdimensioned to accommodate
1166 * possible future increases in the kernel, without an
1167 * accompanying Dante recompile.
1168 */
1169 break; /* no more valid signals in range. */
1170 }
1171
1172 if (bufused != 0)
1173 slog(LOG_DEBUG, "%s: signals blocked in oldmask: %s", function, buf);
1174
1175 print_selectfds("pre-select:",
1176 SOCKS_CLIENT ? 0 : 1,
1177 nfds,
1178 rset,
1179 bufrset,
1180 buffwset,
1181 wset,
1182 xset,
1183 timeout);
1184 }
1185
1186 bufset_nfds = 0;
1187 if (bufrset != NULL || buffwset != NULL) {
1188 /*
1189 * We need to go through each descriptor and see if it
1190 * has data buffered ready for reading. If so, that descriptor
1191 * needs to also be set on return from the below select(2),
1192 * and the timeout must be zero (already have at least one
1193 * descriptor readable).
1194 */
1195 for (i = 0; i < nfds; ++i) {
1196 /*
1197 * Does the fd has data buffered for reading?
1198 * Should only check for decoded data on read. If it's not
1199 * decoded, it means we were unable to read the whole token
1200 * last time, which means there is no data we can fetch from
1201 * the buffer until the rest of the token has been read from
1202 * the socket.
1203 */
1204 if (bufrset != NULL) {
1205 if (FD_ISSET(i, bufrset)
1206 && socks_bytesinbuffer(i, READ_BUF, 0) > 0) {
1207 if (sockscf.option.debug >= DEBUG_VERBOSE)
1208 slog(LOG_DEBUG,
1209 "%s: marking fd %d as having data buffered for read; "
1210 "%lu + %lu bytes buffered for read, %lu + %lu for write",
1211 function, i,
1212 (long unsigned)socks_bytesinbuffer(i, READ_BUF, 0),
1213 (long unsigned)socks_bytesinbuffer(i, READ_BUF, 1),
1214 (long unsigned)socks_bytesinbuffer(i, WRITE_BUF, 0),
1215 (long unsigned)socks_bytesinbuffer(i, WRITE_BUF, 1));
1216
1217 FD_SET(i, bufrset);
1218 bufset_nfds = MAX(bufset_nfds, i + 1);
1219 timeout = &zerotimeout;
1220 }
1221 else
1222 FD_CLR(i, bufrset);
1223 }
1224
1225 /*
1226 * does the fd have data buffered for write?
1227 */
1228 if (buffwset != NULL) {
1229 if (FD_ISSET(i, buffwset)
1230 && socks_bufferhasbytes(i, WRITE_BUF) > 0) {
1231 if (sockscf.option.debug >= DEBUG_VERBOSE)
1232 slog(LOG_DEBUG,
1233 "%s: marking fd %d as having data buffered for write; "
1234 "%lu + %lu bytes buffered for read, %lu + %lu for write",
1235 function, i,
1236 (long unsigned)socks_bytesinbuffer(i, READ_BUF, 0),
1237 (long unsigned)socks_bytesinbuffer(i, READ_BUF, 1),
1238 (long unsigned)socks_bytesinbuffer(i, WRITE_BUF, 0),
1239 (long unsigned)socks_bytesinbuffer(i, WRITE_BUF, 1));
1240
1241 FD_SET(i, buffwset);
1242 bufset_nfds = MAX(bufset_nfds, i + 1);
1243 timeout = &zerotimeout;
1244 }
1245 else
1246 FD_CLR(i, buffwset);
1247 }
1248 }
1249 }
1250
1251 #if DO_SHMEMCHECK
1252 shmemcheck();
1253 #endif /* DO_SHMEMCHECK */
1254
1255 errno = 0; /* clear any old garbage. */
1256
1257
1258 #if DIAGNOSTIC && !SOCKS_CLIENT
1259 gettimeofday(&tstart, NULL);
1260 #endif /* DIAGNOSTIC && !SOCKS_CLIENT */
1261
1262 rc = pselect(nfds,
1263 rset,
1264 wset,
1265 xset,
1266 timeout,
1267 #if SOCKS_CLIENT
1268 NULL
1269 #else /* !SOCKS_CLIENT */
1270 &oldmask
1271 #endif /* !SOCKS_CLIENT */
1272 );
1273
1274 #if DIAGNOSTIC && !SOCKS_CLIENT
1275 gettimeofday(&tend, NULL);
1276
1277 timersub(&tend, &tstart, &tdiff);
1278
1279 if (timercmp(&tdiff, &tshortsleep, >)) {
1280 #if 0
1281 if (shortsleepc > 0)
1282 slog(LOG_NOTICE,
1283 "%s: line %d. resetting shortsleepc, currently %lu",
1284 function, __LINE__, (unsigned long)shortsleepc);
1285 #endif
1286
1287 shortsleepc = 0;
1288 }
1289 else {
1290 if (shortsleepc++ == 0)
1291 tfirstshortsleep = tend;
1292 }
1293
1294 if (shortsleepc >= maxshortsleepc) {
1295 timersub(&tend, &tfirstshortsleep, &tdiff);
1296
1297 if (timercmp(&tdiff, &tshorttimelapse, <)) {
1298 swarnx("%s: pselect(2) blocked for less than %ld.%06lds %lu times "
1299 "during last %ld.%06lds. Looks like a busyloop-bug",
1300 function,
1301 (long)tshortsleep.tv_sec,
1302 (long)tshortsleep.tv_usec,
1303 (unsigned long)shortsleepc,
1304 (long)tdiff.tv_sec,
1305 (long)tdiff.tv_usec);
1306
1307 SERRX(0);
1308 }
1309 else {
1310 #if 0
1311 if (shortsleepc > 0)
1312 slog(LOG_NOTICE,
1313 "%s: line %d. resetting shortsleepc, currently %lu",
1314 function, __LINE__, (unsigned long)shortsleepc);
1315 #endif
1316 shortsleepc = 0;
1317 }
1318 }
1319 #endif /* DIAGNOSTIC && !SOCKS_CLIENT */
1320
1321 if (sockscf.option.debug >= DEBUG_VERBOSE) {
1322 const int errno_s = errno;
1323 char pfix[256];
1324
1325 snprintf(pfix, sizeof(pfix), "post-select returned %d (errno: %s)",
1326 rc, strerror(errno));
1327
1328 SASSERTX(errno_s == errno);
1329 print_selectfds(pfix,
1330 SOCKS_CLIENT ? 0 : 1,
1331 nfds,
1332 rset,
1333 bufrset,
1334 buffwset,
1335 wset,
1336 xset,
1337 timeout);
1338 SASSERTX(errno_s == errno);
1339 }
1340
1341 #if !SOCKS_CLIENT
1342 if (rc == -1 && errno == EINTR)
1343 (void)sockd_handledsignals();
1344
1345 if (sigprocmask(SIG_SETMASK, &oldmask, NULL) != 0)
1346 SERR(errno);
1347 #endif /* !SOCKS_CLIENT */
1348
1349 #if DO_SHMEMCHECK
1350 shmemcheck();
1351 #endif /* DO_SHMEMCHECK */
1352
1353 if (rc == -1)
1354 return rc;
1355
1356 return MAX(rc, bufset_nfds);
1357 }
1358
1359
1360 static void
print_selectfds(preamble,docheck,nfds,rset,bufrset,buffwset,wset,xset,timeout)1361 print_selectfds(preamble, docheck,
1362 nfds, rset, bufrset, buffwset, wset, xset, timeout)
1363 const char *preamble;
1364 const int docheck;
1365 const int nfds;
1366 fd_set *rset, *bufrset, *buffwset;
1367 fd_set *wset;
1368 fd_set *xset;
1369 const struct timespec *timeout;
1370 {
1371 const char *function = "print_selectfds()";
1372 const int errno_s = errno;
1373 char buf[32],
1374 rsetfd[8192 * sizeof("65535") - 1], bufrsetfd[sizeof(rsetfd)],
1375 buffwsetfd[sizeof(rsetfd)], wsetfd[sizeof(rsetfd)],
1376 xsetfd[sizeof(rsetfd)];
1377 size_t rsetfdi, bufrsetfdi, buffwsetfdi, wsetfdi, xsetfdi, rc;
1378 int i;
1379
1380 if (timeout != NULL)
1381 snprintf(buf, sizeof(buf),
1382 "%ld.%06lds",
1383 (long)timeout->tv_sec, (long)timeout->tv_nsec);
1384 else
1385 snprintf(buf, sizeof(buf), "0x0");
1386
1387 rsetfdi = bufrsetfdi = buffwsetfdi = wsetfdi = xsetfdi = 0;
1388 *rsetfd = *bufrsetfd = *buffwsetfd = *wsetfd = *xsetfd = NUL;
1389
1390 for (i = 0; i < nfds; ++i) {
1391 if (rset != NULL && FD_ISSET(i, rset)) {
1392 rc = snprintf(&rsetfd[rsetfdi], sizeof(rsetfd) - rsetfdi,
1393 "%d%s, ",
1394 i, docheck ? (fdisopen(i) ? "" : "-invalid") : "");
1395 rsetfdi += rc;
1396 }
1397
1398 if (bufrset != NULL && FD_ISSET(i, bufrset)) {
1399 rc = snprintf(&bufrsetfd[bufrsetfdi],
1400 sizeof(bufrsetfd) - bufrsetfdi,
1401 "%d%s, ",
1402 i, docheck ? (fdisopen(i) ? "" : "-invalid") : "");
1403 bufrsetfdi += rc;
1404 }
1405
1406 if (buffwset != NULL && FD_ISSET(i, buffwset)) {
1407 rc = snprintf(&buffwsetfd[buffwsetfdi],
1408 sizeof(buffwsetfd) - buffwsetfdi,
1409 "%d%s, ",
1410 i, docheck ? (fdisopen(i) ? "" : "-invalid") : "");
1411
1412 buffwsetfdi += rc;
1413 }
1414
1415
1416 if (wset != NULL && FD_ISSET(i, wset)) {
1417 rc = snprintf(&wsetfd[wsetfdi], sizeof(wsetfd) - wsetfdi,
1418 "%d%s, ",
1419 i, docheck ? (fdisopen(i) ? "" : "-invalid") : "");
1420
1421 wsetfdi += rc;
1422 }
1423
1424 if (xset != NULL && FD_ISSET(i, xset)) {
1425 rc = snprintf(&xsetfd[xsetfdi], sizeof(xsetfd) - xsetfdi,
1426 "%d%s, ",
1427 i, docheck ? (fdisopen(i) ? "" : "-invalid") : "");
1428
1429 xsetfdi += rc;
1430 }
1431 }
1432
1433 slog(LOG_DEBUG,
1434 "%s nfds = %d, "
1435 "rset = %p (%s), "
1436 "bufrset = %p (%s), "
1437 "buffwset = %p (%s), "
1438 "wset = %p (%s), "
1439 "xset = %p (%s), "
1440 "timeout = %s",
1441 preamble, nfds,
1442 rset, rsetfd,
1443 bufrset, bufrsetfd,
1444 buffwset, buffwsetfd,
1445 wset, wsetfd,
1446 xset, xsetfd,
1447 buf);
1448
1449 if (errno != errno_s) {
1450 swarnx("%s: strange ... errno changed from %d to %d",
1451 function, errno_s, errno);
1452
1453 errno = errno_s;
1454 }
1455 }
1456