1 /*
2 * Copyright (c) 1997, 1998, 1999, 2001, 2005, 2008, 2009, 2010, 2011, 2012,
3 * 2013, 2014, 2016, 2017, 2020
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: socket.c,v 1.218.4.7.2.7.4.3 2020/11/11 16:11:54 karls Exp $";
49
50 int
socks_connecthost(s,side,host,laddr,raddr,timeout,emsg,emsglen)51 socks_connecthost(s,
52 #if !SOCKS_CLIENT
53 side,
54 #endif /* !SOCKS_CLIENT */
55 host,
56 laddr,
57 raddr,
58 timeout,
59 emsg,
60 emsglen)
61 int s;
62 #if !SOCKS_CLIENT
63 const interfaceside_t side;
64 #endif /* !SOCKS_CLIENT */
65 const sockshost_t *host;
66 struct sockaddr_storage *laddr;
67 struct sockaddr_storage *raddr;
68 const long timeout;
69 char *emsg;
70 const size_t emsglen;
71 {
72 const char *function = "socks_connecthost()";
73 static fd_set *wset;
74 #if SOCKS_CLIENT
75 interfaceside_t side = EXTERNALIF; /* doesn't matter. */
76 #endif
77 dnsinfo_t resmem;
78 struct sockaddr_storage laddr_mem, raddr_mem;
79 struct addrinfo hints, *res, *next;
80 socklen_t len;
81 char addrstr[MAXSOCKADDRSTRING], hoststr[MAXSOCKSHOSTSTRING],
82 laddrstr[MAXSOCKADDRSTRING];
83 int failed, rc;
84
85 /*
86 * caller depends on errno to know whether the connect(2) failed
87 * permanently, or whether things are now in progress, so make sure
88 * errno is correct upon return, and definitely not some old residue.
89 */
90 errno = 0;
91
92 if (wset == NULL)
93 wset = allocate_maxsize_fdset();
94
95 if (laddr == NULL)
96 laddr = &laddr_mem;
97
98 if (raddr == NULL)
99 raddr = &raddr_mem;
100
101 len = sizeof(*laddr);
102 if (getsockname(s, TOSA(laddr), &len) == -1) {
103 snprintf(emsg, emsglen, "getsockname(2) failed: %s", strerror(errno));
104 return -1;
105 }
106
107 sockaddr2string(laddr, laddrstr, sizeof(laddrstr));
108
109 slog(LOG_NEGOTIATE,
110 "%s: connect to %s on %s side from %s, fd %d. Timeout is %ld\n",
111 function,
112 sockshost2string(host, hoststr, sizeof(hoststr)),
113
114 #if !SOCKS_CLIENT
115
116 interfaceside2string(side),
117
118 #else /* SOCKS_CLIENT */
119
120 "<N/A>",
121
122 #endif /* SOCKS_CLIENT */
123
124 laddrstr,
125 s,
126 timeout);
127
128 bzero(raddr, sizeof(*raddr));
129
130 switch (host->atype) {
131 case SOCKS_ADDR_IPV4:
132 case SOCKS_ADDR_IPV6: {
133 int connect_errno, flags, changed_to_nonblocking;
134
135 changed_to_nonblocking = 0;
136 flags = -1;
137
138 if (timeout != -1) {
139 if ((flags = fcntl(s, F_GETFL, 0)) == -1) {
140 snprintf(emsg, emsglen, "fcntl(F_GETFL) failed: %s",
141 strerror(errno));
142
143 return -1;
144 }
145
146 if (!(flags & O_NONBLOCK)) {
147 slog(LOG_DEBUG,
148 "%s: temporarily changing fd %d to nonblocking in order "
149 "to facilitate the specified connect timeout (%ld)",
150 function, s, timeout);
151
152 if (fcntl(s, F_SETFL, flags | O_NONBLOCK) == -1) {
153 snprintf(emsg, emsglen,
154 "could not change fd %d to nonblocking: %s",
155 s, strerror(errno));
156
157 return -1;
158 }
159
160 changed_to_nonblocking = 1;
161 }
162 }
163
164 switch (host->atype) {
165 case SOCKS_ADDR_IPV4:
166 SET_SOCKADDR(raddr, AF_INET);
167 TOIN(raddr)->sin_addr = host->addr.ipv4;
168 break;
169
170 case SOCKS_ADDR_IPV6:
171 SET_SOCKADDR(raddr, AF_INET6);
172 TOIN6(raddr)->sin6_addr = host->addr.ipv6.ip;
173 TOIN6(raddr)->sin6_scope_id = host->addr.ipv6.scopeid;
174 break;
175
176 default:
177 SERRX(host->atype);
178 }
179
180 SET_SOCKADDRPORT(raddr, host->port);
181
182 rc = connect(s, TOSA(raddr), salen(raddr->ss_family));
183 connect_errno = errno;
184
185 if (rc == 0 || errno == EINPROGRESS) {
186 /*
187 * if local addr was incomplete before, it should be complete now.
188 */
189 if (!IPADDRISBOUND(laddr)) {
190 len = sizeof(*laddr);
191 if (getsockname(s, TOSA(laddr), &len) == -1) {
192 snprintf(emsg, emsglen,
193 "getsockname(2) after connect(2) failed: %s",
194 strerror(errno));
195
196 return -1;
197 }
198
199 sockaddr2string(laddr, laddrstr, sizeof(laddrstr));
200 }
201 }
202
203 snprintf(emsg, emsglen,
204 "connect(2) to %s from %s on fd %d returned %ld (%s)",
205 hoststr, laddrstr, s, (long)rc, strerror(errno));
206
207 slog(LOG_DEBUG, "%s: %s", function, emsg);
208
209 if (changed_to_nonblocking) {
210 SASSERTX(flags != -1);
211
212 if (fcntl(s, F_SETFL, flags & ~O_NONBLOCK) == -1)
213 swarn("%s: failed reverting fd %d back to blocking",
214 function, s);
215 }
216
217 if (rc == 0)
218 /*
219 * OpenBSD 4.5 sometimes sets errno even though the
220 * connect was successful. Seems to be an artifact of the
221 * buggy threads library, where it does a select(2)/poll(2)
222 * after making the socket non-blocking, but forgets to
223 * reset errno.
224 */
225 connect_errno = 0;
226
227 errno = connect_errno;
228
229 #if SOCKS_CLIENT
230 /*
231 * if errno is EINTR, it may be due to the client having set up an
232 * alarm for this. We can't know for sure, so better not
233 * retry in that case.
234 */
235 if (rc == -1) {
236 if (errno == EINTR) {
237 snprintf(emsg, emsglen, "connect(2) to %s from %s failed: %s",
238 sockaddr2string(raddr, NULL, 0),
239 laddrstr,
240 strerror(errno));
241
242 return rc;
243 }
244
245 if (!changed_to_nonblocking) {
246 /*
247 * was passed a non-blocking fd by the client, so client does
248 * not want to wait for the connect to complete. Let the
249 * connect child handle this then, if applicable.
250 */
251 snprintf(emsg, emsglen,
252 "non-blocking connect(2): %s", strerror(errno));
253
254 return rc;
255 }
256 }
257 #endif /* SOCKS_CLIENT */
258
259 while (timeout != 0
260 && rc == -1
261 && ( errno == EINPROGRESS
262 #if !SOCKS_CLIENT
263 || errno == EINTR
264 #endif /* !SOCKS_CLIENT */
265 )) {
266 struct timeval tval = { timeout, (long)0 };
267
268 FD_ZERO(wset);
269 FD_SET(s, wset);
270
271 rc = selectn(s + 1,
272 NULL,
273 NULL,
274 NULL,
275 wset,
276 NULL,
277 timeout >= 0 ? &tval : NULL);
278
279 switch (rc) {
280 case -1:
281 if (ERRNOISTMP(errno))
282 continue;
283 else {
284 snprintf(emsg, emsglen, "select(2) on fd %d failed: %s",
285 s, strerror(errno));
286
287 return -1;
288 }
289
290 case 0:
291 errno = ETIMEDOUT;
292 break;
293
294 default:
295 len = sizeof(errno);
296 getsockopt(s, SOL_SOCKET, SO_ERROR, &errno, &len);
297 }
298
299 if (errno == 0)
300 rc = 0;
301 else
302 /*
303 * connect(2)-attempt finished, but failed.
304 */
305 rc = -1;
306 }
307
308 slog(LOG_NEGOTIATE, "%s: connect to %s from %s on fd %d %s (%s)",
309 function,
310 sockaddr2string(raddr, addrstr, sizeof(addrstr)),
311 laddrstr,
312 s,
313 rc == 0 ? "ok"
314 : errno == EINPROGRESS ? "in progress" : "failed",
315 strerror(errno));
316
317 if (rc == -1) {
318 log_connectfailed(side, addrstr);
319
320 snprintf(emsg, emsglen, "connect(2) to %s from %s %s: %s",
321 sockaddr2string(raddr, NULL, 0),
322 laddrstr,
323 errno == EINPROGRESS ? "is in progress" : "failed",
324 strerror(errno));
325 }
326
327 return rc;
328 }
329
330 case SOCKS_ADDR_DOMAIN: {
331 socklen_t len;
332 char visbuf[MAXHOSTNAMELEN * 4];
333
334 bzero(&hints, sizeof(hints));
335
336 /*
337 * We'd like to set ai_family to laddr->ss_family, but
338 * IPv4-mapped IPv6 addresses screw that up since if laddr
339 * is an IPv4 address (and thus 's' is an IPv4 socket),
340 * we can connect to the IPv4-mapped IPv6 address, but we need to
341 * include IPv6 in the hints.ai_family in order to get those
342 * IPv4-mapped IPv6 addresses from getaddrinfo(3).
343 * (cgetaddrinfo() converts them to regular IPv4-addresses for us,
344 * but in order for it to get them in the first place ...).
345 *
346 * A defect in the getaddrinfo() api, not having a flag for us
347 * to request it includes IPv4-mapped IPv6 addresses, converted to
348 * regular IPv4 addresses.
349 */
350 if (laddr->ss_family == AF_INET)
351 hints.ai_family = 0; /* or we will not get the IPv4-mapped IPv6. */
352 else {
353 SASSERTX(laddr->ss_family == AF_INET6);
354 hints.ai_family = laddr->ss_family;
355 }
356
357 len = sizeof(hints.ai_socktype);
358 if (getsockopt(s, SOL_SOCKET, SO_TYPE, &hints.ai_socktype, &len) != 0){
359 snprintf(emsg, emsglen,
360 "could not determine type of socket for fd %d "
361 "- getsockopt(SO_TYPE) failed: %s",
362 s, strerror(errno));
363
364 return -1;
365 }
366
367 if ((rc = cgetaddrinfo(host->addr.domain, NULL, &hints, &res, &resmem))
368 != 0) {
369 snprintf(emsg, emsglen,
370 "could not resolve hostname \"%s\": %s",
371 str2vis(host->addr.domain,
372 strlen(host->addr.domain),
373 visbuf,
374 sizeof(visbuf)),
375 gai_strerror(rc));
376
377 errno = EHOSTUNREACH; /* anything but EINPROGRESS. */
378 return -1;
379 }
380
381 #if DIAGNOSTIC
382 SASSERTX(hints.ai_family == 0 || res->ai_family == hints.ai_family);
383 SASSERTX(res->ai_socktype == hints.ai_socktype);
384 #endif /* DIAGNOSTIC */
385
386 break;
387 }
388
389 default:
390 SERRX(host->atype);
391 }
392
393 SASSERTX(host->atype == SOCKS_ADDR_DOMAIN);
394 SASSERTX(res->ai_addr != NULL);
395
396 /*
397 * try all ipaddresses hostname resolved to.
398 */
399
400 failed = 0;
401 next = res;
402 do {
403 sockshost_t newhost;
404
405 if (next->ai_family != laddr->ss_family) {
406 snprintf(emsg, emsglen,
407 "can not attempt connect to address %s (resolved from %s) "
408 "from our %s-socket on the external side",
409 sockaddr2string(TOSS(next->ai_addr), NULL, 0),
410 hoststr,
411 safamily2string(laddr->ss_family));
412 errno = EAFNOSUPPORT;
413
414 next = next->ai_next;
415 continue;
416 }
417
418 if (failed) { /* previously failed, need to create a new socket. */
419 int new_s;
420
421 if ((new_s = socketoptdup(s, -1)) == -1) {
422 snprintf(emsg, emsglen, "socketoptdup() failed: %s",
423 strerror(errno));
424
425 return -1;
426 }
427
428 if (dup2(new_s, s) == -1) {
429 snprintf(emsg, emsglen, "dup2() failed: %s", strerror(errno));
430 close(new_s);
431
432 return -1;
433 }
434 close(new_s); /* s is now a new socket but keeps the same index. */
435
436 /*
437 * try to bind the same address/port on the new socket.
438 */
439
440 if (socks_bind(s, laddr, 1) != 0) {
441 snprintf(emsg, emsglen, "socks_bind() failed: %s", strerror(errno));
442 return -1;
443 }
444 }
445
446 /*
447 * Convert next address to sockshost_t and call ourselves again.
448 */
449
450 sockaddrcpy(raddr, TOSS(next->ai_addr), sizeof(*raddr));
451 SET_SOCKADDRPORT(raddr, host->port);
452
453 sockaddr2sockshost(raddr, &newhost);
454
455 if (next->ai_next == NULL) {
456 /*
457 * no more ip addresses to try. That means we can simply call
458 * socks_connecthost() with the timeout as received.
459 * If not, we will need to disregard the passed in timeout and
460 * connect to one address at a time and await the result. :-/
461 *
462 * XXX improve this by keeping track of how much time we've used
463 * so far, so we can decrement the timeout on each connecthost()
464 * call?
465 */
466 rc = socks_connecthost(s,
467 #if !SOCKS_CLIENT
468 side,
469 #endif /* !SOCKS_CLIENT */
470 &newhost,
471 laddr,
472 raddr,
473 timeout,
474 emsg,
475 emsglen);
476 }
477 else
478 rc = socks_connecthost(s,
479 #if !SOCKS_CLIENT
480 side,
481 #endif /* !SOCKS_CLIENT */
482 &newhost,
483 laddr,
484 raddr,
485 sockscf.timeout.connect ?
486 (long)sockscf.timeout.connect : (long)-1,
487 emsg,
488 emsglen);
489
490 if (rc == 0) {
491 errno = 0;
492
493 if (emsg != NULL)
494 *emsg = NUL;
495
496 return 0;
497 }
498
499 /*
500 * Only retry/try next address if errno indicates server/network error.
501 */
502 switch (errno) {
503 case ETIMEDOUT:
504 case EINVAL:
505 case ECONNREFUSED:
506 case ENETUNREACH:
507 case EHOSTUNREACH:
508 break;
509
510 default:
511 return -1;
512 }
513
514 failed = 1;
515 next = next->ai_next;
516 } while (next != NULL);
517
518 /*
519 * list exhausted, no successful connect.
520 */
521
522 SASSERTX(errno != 0);
523
524 if (emsg != NULL)
525 SASSERTX(*emsg != NUL);
526
527 return -1;
528 }
529
530 #undef socket
531 int
socks_socket(domain,type,protocol)532 socks_socket(domain, type, protocol)
533 const int domain;
534 const int type;
535 const int protocol;
536 {
537 const char *function = "socks_socket()";
538 int s;
539
540 if ((s = socket(domain, type, protocol)) == -1)
541 return -1;
542
543 #if !SOCKS_CLIENT
544 if (domain == AF_INET6) {
545 socklen_t len;
546 int value;
547
548 value = 1;
549 len = sizeof(value);
550
551 if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &value, len) != 0)
552 swarn("%s: setsockopt(IPV6_V6ONLY) on fd %d failed", function, s);
553 }
554 #endif /* !SOCKS_CLIENT */
555
556 return s;
557 }
558
559
560 int
acceptn(s,addr,addrlen)561 acceptn(s, addr, addrlen)
562 int s;
563 struct sockaddr_storage *addr;
564 socklen_t *addrlen;
565 {
566 const char *function = "acceptn()";
567 struct sockaddr_storage fulladdr;
568 socklen_t fulladdrlen = sizeof(fulladdr);
569 int rc;
570
571 #if DEBUG /* for occasional internal debugging/analysis. */
572
573 #ifdef SO_LISTENQLEN
574 if (sockscf.option.debug) {
575 socklen_t len;
576 int listenqlen, listeninqclen, failed;
577
578 failed = 0;
579
580 len = sizeof(listenqlen);
581 if (getsockopt(s, SOL_SOCKET, SO_LISTENQLEN, &listenqlen, &len) == -1) {
582 swarn("%s: getsockopt(SO_LISTENQLEN) failed", function);
583 failed = 1;
584 }
585
586 len = sizeof(listeninqclen);
587 if (getsockopt(s, SOL_SOCKET, SO_LISTENINCQLEN, &listeninqclen, &len)
588 == -1) {
589 swarn("%s: getsockopt(SO_LISTENINCQLEN) failed", function);
590 failed = 1;
591 }
592
593 if (!failed)
594 slog(LOG_DEBUG, "%s: fd %d. listenqlen: %d, listeninqclen: %d",
595 function, s, listenqlen, listeninqclen);
596 }
597 #endif /* SO_LISTENQLEN */
598
599 #endif /* DEBUG */
600
601 while ((rc = accept(s, TOSA(&fulladdr), &fulladdrlen)) == -1
602 && errno == EINTR)
603 #if !SOCKS_CLIENT
604 /*
605 * XXX only here because request children block on accept(2).
606 * Remove it if we some day improve the request children so they no
607 * longer do that.
608 */
609 (void)sockd_handledsignals();
610 #else /* SOCKS_CLIENT */
611 ;
612 #endif /* SOCKS_CLIENT */
613
614 #if !SOCKS_CLIENT && HAVE_LINUX_BUGS
615 if (rc != -1) {
616 /*
617 * On Linux fd-flags are not inherited by accept(2) for some reason.
618 */
619 if (fcntl(rc, F_SETFL, fcntl(s, F_GETFL, 0)) != 0) {
620 swarn("%s: attempt to work around Linux bug via fcntl(2) failed",
621 function);
622
623 close(rc);
624 return -1;
625 }
626 }
627 #endif /* !SOCKS_CLIENT && HAVE_LINUX_BUGS */
628
629 if (rc != -1)
630 /*
631 * Avoids Valgrind complaining about us sendmsg(2)-ing uninitialized
632 * parts of the sockaddr_storage struct accept(2)-ed above.
633 */
634 sockaddrcpy(addr, &fulladdr, (size_t)*addrlen);
635
636 *addrlen = MIN(*addrlen, (socklen_t)fulladdrlen);
637
638 return rc;
639 }
640
641 int
setnonblocking(fd,ctx)642 setnonblocking(fd, ctx)
643 const int fd;
644 const char *ctx;
645 {
646 const char *function = "setnonblocking()";
647 int flags;
648
649 SASSERTX(ctx != NULL);
650
651 if ((flags = fcntl(fd, F_GETFL, 0)) != -1
652 && fcntl(fd, F_SETFL, flags | O_NONBLOCK) != -1) {
653 slog(LOG_DEBUG, "%s: fd %d: %s", function, fd, ctx);
654 return flags;
655 }
656 else {
657 swarn("failed to make fd %d, used for %s, non-blocking", fd, ctx);
658 return -1;
659 }
660 }
661
662 int
setblocking(fd,ctx)663 setblocking(fd, ctx)
664 const int fd;
665 const char *ctx;
666 {
667 const char *function = "setblocking()";
668 int flags;
669
670 SASSERTX(ctx != NULL);
671
672 if ((flags = fcntl(fd, F_GETFL, 0)) != -1
673 && fcntl(fd, F_SETFL, flags & ~O_NONBLOCK) != -1) {
674 slog(LOG_DEBUG, "%s: fd %d: %s", function, fd, ctx);
675 return flags;
676 }
677 else {
678 swarn("failed to make fd %d, used for %s, blocking", fd, ctx);
679 return -1;
680 }
681 }
682
683 int
socks_socketisforlan(s)684 socks_socketisforlan(s)
685 const int s;
686 {
687 const char *function = "socks_socketisforlan()";
688 struct in_addr addr;
689 socklen_t len;
690 unsigned char ttl;
691 const int errno_s = errno;
692
693 /*
694 * make an educated guess as to whether the socket is intended for
695 * lan-only use or not.
696 */
697
698 len = sizeof(addr);
699 if (getsockopt(s, IPPROTO_IP, IP_MULTICAST_IF, &addr, &len) != 0) {
700 slog(LOG_DEBUG, "%s: getsockopt(IP_MULTICAST_IF) failed: %s",
701 function, strerror(errno));
702
703 errno = errno_s;
704 return 0;
705 }
706
707 if (addr.s_addr == htonl(INADDR_ANY))
708 return 0;
709
710 len = sizeof(ttl);
711 if (getsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, &len) != 0) {
712 swarn("%s: getsockopt(IP_MULTICAST_TTL)", function);
713
714 errno = errno_s;
715 return 0;
716 }
717
718 return ttl == 1;
719 }
720
721 struct sockaddr_storage *
socketisconnected(s,addr,addrlen)722 socketisconnected(s, addr, addrlen)
723 const int s;
724 struct sockaddr_storage *addr;
725 socklen_t addrlen;
726 {
727 const char *function = "socketisconnected()";
728 socklen_t len;
729 int err;
730
731 if (addr == NULL || addrlen == 0) {
732 static struct sockaddr_storage addrmem;
733
734 addr = &addrmem;
735 }
736
737 len = sizeof(err);
738 (void)getsockopt(s, SOL_SOCKET, SO_ERROR, &err, &len);
739
740 if (err == 0) {
741 if (getpeername(s, TOSA(addr), &len) == -1) { /* strange. */
742 /*
743 * presumably a timing issue; connection failed between
744 * our getsockopt(2) call and now.
745 */
746 return NULL;
747 }
748 }
749 else
750 return NULL;
751
752 return addr;
753 }
754
755 int
socks_rebind(s,protocol,from,to,emsg,emsglen)756 socks_rebind(s, protocol, from, to, emsg, emsglen)
757 int s;
758 int protocol;
759 struct sockaddr_storage *from;
760 const struct ruleaddr_t *to;
761 char *emsg;
762 const size_t emsglen;
763 {
764 const char *function = "socks_rebind()";
765 struct sockaddr_storage tobind;
766
767 slog(LOG_NEGOTIATE, "%s: fd %d, protocol %s, from %s, to %s",
768 function,
769 s,
770 protocol2string(protocol),
771 sockaddr2string(from, NULL, 0),
772 ruleaddr2string(to, ADDRINFO_PORT, NULL, 0));
773
774 ruleaddr2sockaddr(to, &tobind, protocol);
775 if (!IPADDRISBOUND(&tobind)) {
776 snprintf(emsg, emsglen, "could not convert %s to an IP-address",
777 ruleaddr2string(to, 0, NULL, 0));
778 swarnx("%s: %s", function, emsg);
779
780 errno = EADDRNOTAVAIL;
781 return -1;
782 }
783
784 if (IPADDRISBOUND(from) || PORTISBOUND(from)) {
785 #if SOCKS_CLIENT
786
787 rlim_t maxofiles;
788 int i;
789
790 #endif /* SOCKS_CLIENT */
791
792 int new_s, rc;
793
794 /*
795 * bound locally already. Does it by coincidence match what we
796 * want, or do we need to create a new socket and bind that instead?
797 */
798 if (addrmatch(to, sockaddr2sockshost(from, NULL), NULL, protocol, 0))
799 return 0; /* matches already. */
800
801 /*
802 * Nope, need to create a new socket so we can bind wanted address.
803 */
804
805 if ((new_s = socketoptdup(s, -1)) == -1) {
806 snprintf(emsg, emsglen,
807 "could not dup(2) fd %d with socketopdup(): %s",
808 s, strerror(errno));
809
810 swarnx("%s: %s", function, emsg);
811 return -1;
812 }
813
814 #if SOCKS_CLIENT
815
816 /*
817 * The problem now is that caller may also have created dup(2)'s
818 * of this socket, so us creating a new socket and assigning it the
819 * index of the old socket won't do much good if the caller keeps using
820 * his own dup(2)-ed version of the old socket.
821 * We try to handle this by searching through the fd index space
822 * for dups of 's', and dup2(2)'ing them too.
823 */
824 maxofiles = getmaxofiles(softlimit);
825 for (i = 0; i < (int)maxofiles; ++i) {
826 if (i == s)
827 continue;
828
829 if (fdisdup(i, s)) {
830 slog(LOG_INFO,
831 "%s: found socket duped by client, fd %d is dup of fd %d",
832 function, i, s);
833
834 if (dup2(new_s, i) == -1) {
835 snprintf(emsg, emsglen,
836 "could not dup2(2) fd %d to %d (for clients dup): %s",
837 new_s, i, strerror(errno));
838
839 swarnx("%s: %s", function, emsg);
840 close(new_s);
841
842 /*
843 * If we previously found sockets to dup2(), we are basically
844 * SOL and things will be screwed up for the client. Sorry. :-/
845 */
846 return -1;
847 }
848 }
849 }
850
851 #endif /* SOCKS_CLIENT */
852
853 rc = dup2(new_s, s);
854 close(new_s);
855
856 if (rc == -1) {
857 snprintf(emsg, emsglen, "could not dup2(2) fd %d to %d: %s",
858 new_s, s, strerror(errno));
859
860 swarnx("%s: %s", function, emsg);
861 return -1;
862 }
863
864 /*
865 * Fist try to close the old socket and rebind the new with the same
866 * portnumber as the old used, if the old portnumber matches what
867 * caller wants.
868 */
869
870 SET_SOCKADDRPORT(&tobind, GET_SOCKADDRPORT(from));
871 if (addrmatch(to, sockaddr2sockshost(&tobind, NULL), NULL, protocol, 0)) {
872 if (socks_bind(s, &tobind, 0) == 0)
873 return 0;
874 }
875 SET_SOCKADDRPORT(&tobind, htons(0));
876 }
877 /* else: socket is not bound, so can just bind it with the right address. */
878
879 if (socks_bindinrange(s,
880 &tobind,
881 protocol == SOCKS_TCP ? to->port.tcp : to->port.udp,
882 to->portend,
883 to->operator) != 0) {
884 snprintf(emsg, emsglen, "could not bind(2) fd %d in range %s: %s",
885 s, ruleaddr2string(to, ADDRINFO_PORT, NULL, 0), strerror(errno));
886
887 swarnx("%s: %s", function, emsg);
888
889 errno = EADDRNOTAVAIL;
890 return -1;
891 }
892
893 slog(LOG_NEGOTIATE, "%s: successfully rebound %s-fd %d. New address is %s",
894 function,
895 protocol2string(protocol),
896 s,
897 sockaddr2string(&tobind, NULL, 0));
898
899 return 0;
900 }
901
902 int
socks_bindinrange(s,addr,first,last,op)903 socks_bindinrange(s, addr, first, last, op)
904 int s;
905 struct sockaddr_storage *addr;
906 in_port_t first, last;
907 const enum operator_t op;
908 {
909 const char *function = "socks_bindinrange()";
910 in_port_t port;
911 int exhausted;
912
913 slog(LOG_DEBUG, "%s: %s %u %s %u",
914 function,
915 sockaddr2string(addr, NULL, 0),
916 ntohs(first),
917 operator2string(op),
918 ntohs(last));
919
920
921 /*
922 * use ports in host order to make it easier. Only convert before bind.
923 */
924
925 /* try this one first, if possible. */
926 port = 0;
927 first = ntohs(first);
928 last = ntohs(last);
929 exhausted = 0;
930
931 do {
932 if (port + 1 == 0) /* wrapped. */
933 exhausted = 1;
934
935 /* find next port to try. */
936 switch (op) {
937 case none:
938 port = 0; /* any port is good. */
939 break;
940
941 case eq:
942 port = first;
943 break;
944
945 case neq:
946 if (++port == first)
947 ++port;
948 break;
949
950 case ge:
951 if (port < first)
952 port = first;
953 else
954 ++port;
955 break;
956
957 case gt:
958 if (port <= first)
959 port = first + 1;
960 else
961 ++port;
962 break;
963
964 case le:
965 if (++port > first)
966 exhausted = 1;
967 break;
968
969 case lt:
970 if (++port >= first)
971 exhausted = 1;
972 break;
973
974 case range:
975 if (port < first)
976 port = first;
977 else
978 ++port;
979
980 if (port > last)
981 exhausted = 1;
982 break;
983
984 default:
985 SERRX(op);
986 }
987
988 if (exhausted) {
989 slog(LOG_NEGOTIATE,
990 "%s: exhausted search for port to bind in range %u %s %u",
991 function, first, operator2string(op), last);
992
993 return -1;
994 }
995
996 SET_SOCKADDRPORT(addr, htons(port));
997 if (socks_bind(s, addr, 0) == 0)
998 return 0;
999
1000 if (errno == EACCES) {
1001 if (op == gt || op == ge || op == range)
1002 port = 1023; /* short-circuit to first possibility - 1. */
1003 else if (op == lt || op == le)
1004 exhausted = 1; /* going down, will get same error for all. */
1005 }
1006
1007 if (op == eq || op == none)
1008 break; /* nothing to retry for these. */
1009 } while (!exhausted);
1010
1011 return -1;
1012 }
1013
1014 int
socks_bind(s,addr,retries)1015 socks_bind(s, addr, retries)
1016 int s;
1017 struct sockaddr_storage *addr;
1018 size_t retries;
1019 {
1020 const char *function = "socks_bind()";
1021 int p;
1022
1023 slog(LOG_DEBUG, "%s: trying to bind address %s on fd %d. Retries is %lu",
1024 function, sockaddr2string(addr, NULL, 0), s, (unsigned long)retries);
1025
1026 errno = 0;
1027 while (1) {
1028 #if !SOCKS_CLIENT
1029 if (PORTISRESERVED(GET_SOCKADDRPORT(addr)))
1030 sockd_priv(SOCKD_PRIV_NET_ADDR, PRIV_ON);
1031 #endif /* !SOCKS_CLIENT */
1032
1033 p = bind(s, TOSA(addr), salen(addr->ss_family));
1034
1035 #if !SOCKS_CLIENT
1036 if (PORTISRESERVED(GET_SOCKADDRPORT(addr)))
1037 sockd_priv(SOCKD_PRIV_NET_ADDR, PRIV_OFF);
1038 #endif /* !SOCKS_CLIENT */
1039
1040 if (p == 0) {
1041 socklen_t addrlen = sizeof(*addr);
1042 p = getsockname(s, TOSA(addr), &addrlen);
1043 break;
1044 }
1045
1046 slog(LOG_DEBUG, "%s: failed to bind %s (%s)",
1047 function, sockaddr2string(addr, NULL, 0), strerror(errno));
1048
1049 /*
1050 * else; non-fatal error and retry?
1051 */
1052 switch (errno) {
1053 case EINTR:
1054 continue; /* don't count this attempt. */
1055
1056 case EADDRINUSE:
1057 if (retries--) {
1058 sleep(1);
1059 continue;
1060 }
1061 break;
1062
1063 /* default: fatal error. */
1064 }
1065
1066 break;
1067 }
1068
1069 if (p == 0)
1070 slog(LOG_DEBUG, "%s: bound address %s on fd %d",
1071 function, sockaddr2string(addr, NULL, 0), s);
1072
1073 return p;
1074 }
1075
1076 int
fdisdup(fd1,fd2)1077 fdisdup(fd1, fd2)
1078 const int fd1;
1079 const int fd2;
1080 {
1081 const char *function = "fdisdup()";
1082 #if HAVE_UNIQUE_SOCKET_INODES
1083 struct stat sb1, sb2;
1084 #endif /* HAVE_UNIQUE_SOCKET_INODES */
1085 socklen_t len1, len2;
1086 int isdup, rc1, rc2, errno1, errno2, flags1, flags2, newflags1, newflags2,
1087 testflag = SO_REUSEADDR, setflag;
1088
1089 slog(LOG_DEBUG, "%s: fd %d, fd %d", function, fd1, fd2);
1090
1091 if (fd1 == fd2)
1092 return 1;
1093
1094 #if HAVE_UNIQUE_SOCKET_INODES
1095 rc1 = fstat(fd1, &sb1);
1096 errno1 = errno;
1097
1098 rc2 = fstat(fd2, &sb2);
1099 errno2 = errno;
1100
1101 if (rc1 != rc2 || errno1 != errno2) {
1102 if (sockscf.option.debug >= DEBUG_VERBOSE)
1103 slog(LOG_DEBUG, "%s: failed due to fstat() on line %d",
1104 function, __LINE__);
1105
1106 return 0;
1107 }
1108
1109 if (rc1 == -1) {
1110 SASSERTX(rc2 == -1 && errno1 == errno2);
1111
1112 if (sockscf.option.debug >= DEBUG_VERBOSE)
1113 slog(LOG_DEBUG, "%s: failed due to rc1 on line %d",
1114 function, __LINE__);
1115
1116 return 1; /* assume any failed socket is as good as any other. */
1117 }
1118
1119 if (sb1.st_ino == 0)
1120 slog(LOG_DEBUG, "%s: socket inode is 0. Assuming kernel does "
1121 "not support the inode field for (this) socket, so "
1122 "continuing with other tests",
1123 function);
1124 else if (sb1.st_dev != sb2.st_dev
1125 || sb1.st_ino != sb2.st_ino) {
1126 if (sockscf.option.debug >= DEBUG_VERBOSE)
1127 slog(LOG_DEBUG, "%s: failed due to inode-compare on line %d "
1128 "(sb1.st_dev = %d, sb2.st_dev = %d, "
1129 "sb1.st_ino = %d, sb2.st_ino = %d)",
1130 function, __LINE__,
1131 (int)sb1.st_dev, (int)sb2.st_dev,
1132 (int)sb1.st_ino, (int)sb2.st_ino);
1133
1134 return 0;
1135 }
1136 #endif /* HAVE_UNIQUE_SOCKET_INODES */
1137
1138 len1 = sizeof(flags1);
1139 rc1 = getsockopt(fd1, SOL_SOCKET, testflag, &flags1, &len1);
1140 errno1 = errno;
1141
1142 len2 = sizeof(flags2);
1143 rc2 = getsockopt(fd2, SOL_SOCKET, testflag, &flags2, &len2);
1144 errno2 = errno;
1145
1146 if (rc1 != rc2 || errno1 != errno2 || flags1 != flags2) {
1147 if (sockscf.option.debug >= DEBUG_VERBOSE)
1148 slog(LOG_DEBUG, "%s: failed due to flags/errno/len-compare on line %d",
1149 function, __LINE__);
1150
1151 return 0;
1152 }
1153
1154 /*
1155 * Test is to set a flag on fd1, and see if the same flag then gets set on
1156 * fd2. Note that this flag must be a flag we can set on a socket that
1157 * failed during connect(2), or where the peer has closed it's side
1158 * of the session, and which will be shared between descriptors that are
1159 * dup(2)'s of each other.
1160 *
1161 * File status flags are shared, but descriptor flags (e.g., FD_CLOEXEC),
1162 * are of course not. Also note that not all platforms let all F_SETFL
1163 * commands change the same flags, and not all platforms let us set
1164 * the flag on a "failed" socket (a socket where the connect(2) failed).
1165 * We however assume that if the socket failed, and we are getting the
1166 * same errno from the socket we are checking against, it is either the
1167 * socket, or any failed socket is as good as any other failed socket.
1168 *
1169 * XXX this does not work on OpenBSD if one of the descriptors were passed
1170 * us by another process (e.g., passed us by the connect child).
1171 * Need to sendbug this.
1172 * On OpenBSD 4.5, if we have a process A, and that process sends
1173 * a file descriptor to process B, and process B then send that
1174 * same descriptor back to process A, the file status flags, at
1175 * least O_NONBLOCK, is not shared.
1176 * Thus if process A sends descriptor k to process B, and
1177 * process B later sends that same descriptor back to process A,
1178 * the descriptor B sends to A is a dup of k, and gets allocated
1179 * a new index, e.g. k2. We then expect that if we change the
1180 * O_NONBLOCK flag on k2, it will be reflected on k, but the bug
1181 * is that it is not.
1182 *
1183 * The reason we do not do this test first is that if there are multiple
1184 * processes/threads using the same fd, we want to minimize the chance
1185 * of us changing the descriptor under their feet while they are using it.
1186 */
1187
1188 if (rc1 == -1 && rc2 == -1) {
1189 if (sockscf.option.debug >= DEBUG_VERBOSE)
1190 slog(LOG_DEBUG,
1191 "%s: succeeded due to getsockopt(2) failing (%s) on line %d",
1192 function, strerror(errno1), __LINE__);
1193
1194 return 1; /* assume any failed socket is as good as any other failed. */
1195 }
1196
1197 if (rc1 == -1 && errno1 == ENOTSOCK) {
1198 SWARNX(fd1); /* should not happen as we are only interested in sockets. */
1199
1200 if (sockscf.option.debug >= DEBUG_VERBOSE)
1201 slog(LOG_DEBUG, "%s: failed due to errno = ENOTSOCK on line %d",
1202 function, __LINE__);
1203
1204 return 0;
1205 }
1206
1207 slog(LOG_DEBUG, "%s: all looks equal so far, doing final test, flags = %d",
1208 function, flags1);
1209
1210 SASSERTX(flags1 == flags2);
1211
1212 if (flags1)
1213 /*
1214 * remove testflag from fd1 and see if it gets removed from fd2 too.
1215 */
1216 setflag = 0;
1217 else
1218 /*
1219 * add testflag to fd1 and see if it gets added to fd2 too.
1220 */
1221 setflag = 1;
1222
1223 if (setsockopt(fd1, SOL_SOCKET, testflag, &setflag, sizeof(setflag)) != 0) {
1224 if (setsockopt(fd2, SOL_SOCKET, testflag, &setflag, sizeof(setflag)) != 0)
1225 {
1226 slog(LOG_DEBUG, "%s: succeeded due to setsockopt() failing on line %d",
1227 function, __LINE__);
1228
1229 return 1;
1230 }
1231 else {
1232 if (setsockopt(fd2, SOL_SOCKET, testflag, &flags2, sizeof(flags2))
1233 != 0)
1234 slog(LOG_DEBUG, "%s: could not restore original flags on fd %d: %s",
1235 function, fd2, strerror(errno));
1236
1237 slog(LOG_DEBUG, "%s: failed due to setsockopt() failing on line %d",
1238 function, __LINE__);
1239
1240 return 0;
1241 }
1242 }
1243
1244 len1 = sizeof(newflags1);
1245 rc1 = getsockopt(fd1, SOL_SOCKET, testflag, &newflags1, &len1);
1246 errno1 = errno;
1247
1248 len2 = sizeof(newflags2);
1249 rc2 = getsockopt(fd2, SOL_SOCKET, testflag, &newflags2, &len2);
1250 errno2 = errno;
1251
1252 if (newflags1 == newflags2) {
1253 slog(LOG_DEBUG, "%s: newflags1 = newflags2 -> %d is a dup of %d",
1254 function, fd1, fd2);
1255
1256 isdup = 1;
1257 }
1258 else if (rc1 == -1 && rc2 == rc1
1259 && errno1 == errno2) {
1260 slog(LOG_DEBUG, "%s: flagcheck failed, but rc (%d) and errno (%d) is "
1261 "the same, so assuming %d is a dup of %d, or that "
1262 "any failed socket is as good as any other failed "
1263 "socket. Not many other choices",
1264 function, rc1, errno1, fd1, fd2);
1265 isdup = 1;
1266 }
1267 else
1268 isdup = 0;
1269
1270 /* restore flags back to original. */
1271 SASSERTX(flags1 == flags2);
1272 (void)setsockopt(fd1, SOL_SOCKET, testflag, &flags1, sizeof(flags1));
1273 (void)setsockopt(fd2, SOL_SOCKET, testflag, &flags2, sizeof(flags2));
1274
1275 slog(LOG_DEBUG, "%s: final test indicates fd %d %s of fd %d",
1276 function, fd1, isdup ? "is a dup" : "is not a dup", fd2);
1277
1278 return isdup;
1279 }
1280
1281 int
makedummyfd(_safamily,_socktype)1282 makedummyfd(_safamily, _socktype)
1283 const sa_family_t _safamily;
1284 const int _socktype;
1285 {
1286 const char *function = "makedummyfd()";
1287 struct sockaddr_storage addr;
1288 sa_family_t safamily;
1289 int socktype, s;
1290
1291 if (_safamily == 0)
1292 safamily = AF_INET;
1293 else
1294 safamily = _safamily;
1295
1296 if (_socktype == 0)
1297 socktype = SOCK_DGRAM;
1298 else
1299 socktype = _socktype;
1300
1301 if ((s = socket(safamily, socktype, 0)) == -1) {
1302 swarn("%s: failed to create dummysocket of type %s, socktype %s",
1303 function, safamily2string(safamily), socktype2string(socktype));
1304
1305 return -1;
1306 }
1307
1308 if (socktype == SOCK_DGRAM)
1309 return s;
1310
1311 /*
1312 * Else, need to do some more complex work, creating a genuine socket
1313 * that will not be marked ad readable or writable by select(2).
1314 */
1315
1316 /*
1317 * The below bind(2) and listen(2) is necessary for Linux not to mark
1318 * the socket as readable/writable. Under other UNIX systems, just a
1319 * socket(2) is enough. Judging from the Open Unix spec., Linux is the
1320 * one that is correct though.
1321 */
1322
1323 bzero(&addr, sizeof(addr));
1324 SET_SOCKADDR(&addr, safamily);
1325
1326 if (safamily == AF_INET)
1327 TOIN(&addr)->sin_addr.s_addr = htonl(INADDR_ANY);
1328 else {
1329 SASSERTX(safamily == AF_INET6);
1330 memcpy(&TOIN6(&addr)->sin6_addr, &in6addr_any, sizeof(in6addr_any));
1331 }
1332
1333 SET_SOCKADDRPORT(&addr, htons(0));
1334
1335 if (socks_bind(s, TOSS(&addr), 0) != 0) {
1336 swarn("%s: could not bind address (%s)",
1337 function, sockaddr2string(&addr, NULL, 0));
1338
1339 return s;
1340 }
1341
1342 if (listen(s, 1) != 0) {
1343 swarn("%s: could not listen(2) on socket", function);
1344 return s;
1345 }
1346
1347 return s;
1348
1349 }
1350
1351 #if SOCKS_CLIENT
1352
1353 int
fd_is_network_socket(fd)1354 fd_is_network_socket(fd)
1355 const int fd;
1356 {
1357 struct stat statbuf;
1358 struct sockaddr_storage addr;
1359 socklen_t addrlen = sizeof(addr);
1360
1361 if (fstat(fd, &statbuf) != 0)
1362 return 0;
1363
1364 if (S_ISSOCK(statbuf.st_mode) == 0)
1365 return 0;
1366
1367
1368 #if SOCKSLIBRARY_DYNAMIC
1369 /*
1370 * This function is used to decide whether to track a fd or not,
1371 * so be sure to not call ourselves again when figuring out
1372 * whether sys_getsockname() should track the fd or not.
1373 */
1374
1375 if (sys_getsockname_notracking(fd, TOSA(&addr), &addrlen) != 0)
1376 return 0;
1377
1378 #else /* !SOCKSLIBRARY_DYNAMIC */
1379
1380 if (getsockname(fd, TOSA(&addr), &addrlen) != 0)
1381 return 0;
1382
1383 #endif /* !SOCKSLIBRARY_DYNAMIC */
1384
1385 switch (addr.ss_family) {
1386 case AF_INET:
1387 case AF_INET6:
1388 return 1;
1389
1390 default:
1391 return 0;
1392 }
1393 }
1394
1395 #endif /* SOCKS_CLIENT */
1396