1 /*
2 * Unix networking abstraction.
3 */
4
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <assert.h>
8 #include <errno.h>
9 #include <fcntl.h>
10 #include <unistd.h>
11 #include <sys/types.h>
12 #include <sys/socket.h>
13 #include <sys/ioctl.h>
14 #ifdef __FreeBSD__
15 #include <netinet/in.h>
16 #include <arpa/inet.h>
17 #else
18 #include <arpa/inet.h>
19 #include <netinet/in.h>
20 #endif
21 #include <netinet/tcp.h>
22 #include <netdb.h>
23 #include <sys/un.h>
24 #include <pwd.h>
25 #include <grp.h>
26
27 #include "putty.h"
28 #include "network.h"
29 #include "tree234.h"
30
31 /* Solaris needs <sys/sockio.h> for SIOCATMARK. */
32 #ifndef SIOCATMARK
33 #include <sys/sockio.h>
34 #endif
35
36 #ifndef X11_UNIX_PATH
37 # define X11_UNIX_PATH "/tmp/.X11-unix/X"
38 #endif
39
40 /*
41 * Access to sockaddr types without breaking C strict aliasing rules.
42 */
43 union sockaddr_union {
44 struct sockaddr_storage storage;
45 struct sockaddr sa;
46 struct sockaddr_in sin;
47 #ifndef NO_IPV6
48 struct sockaddr_in6 sin6;
49 #endif
50 struct sockaddr_un su;
51 };
52
53 /*
54 * Mutable state that goes with a SockAddr: stores information
55 * about where in the list of candidate IP(v*) addresses we've
56 * currently got to.
57 */
58 typedef struct SockAddrStep_tag SockAddrStep;
59 struct SockAddrStep_tag {
60 #ifndef NO_IPV6
61 struct addrinfo *ai; /* steps along addr->ais */
62 #endif
63 int curraddr;
64 };
65
66 typedef struct NetSocket NetSocket;
67 struct NetSocket {
68 const char *error;
69 int s;
70 Plug *plug;
71 bufchain output_data;
72 bool connected; /* irrelevant for listening sockets */
73 bool writable;
74 bool frozen; /* this causes readability notifications to be ignored */
75 bool localhost_only; /* for listening sockets */
76 char oobdata[1];
77 size_t sending_oob;
78 bool oobpending; /* is there OOB data available to read? */
79 bool oobinline;
80 enum { EOF_NO, EOF_PENDING, EOF_SENT } outgoingeof;
81 bool incomingeof;
82 int pending_error; /* in case send() returns error */
83 bool listener;
84 bool nodelay, keepalive; /* for connect()-type sockets */
85 bool privport;
86 int port; /* and again */
87 SockAddr *addr;
88 SockAddrStep step;
89 /*
90 * We sometimes need pairs of Socket structures to be linked:
91 * if we are listening on the same IPv6 and v4 port, for
92 * example. So here we define `parent' and `child' pointers to
93 * track this link.
94 */
95 NetSocket *parent, *child;
96
97 Socket sock;
98 };
99
100 struct SockAddr {
101 int refcount;
102 const char *error;
103 enum { UNRESOLVED, UNIX, IP } superfamily;
104 #ifndef NO_IPV6
105 struct addrinfo *ais; /* Addresses IPv6 style. */
106 #else
107 unsigned long *addresses; /* Addresses IPv4 style. */
108 int naddresses;
109 #endif
110 char hostname[512]; /* Store an unresolved host name. */
111 };
112
113 /*
114 * Which address family this address belongs to. AF_INET for IPv4;
115 * AF_INET6 for IPv6; AF_UNSPEC indicates that name resolution has
116 * not been done and a simple host name is held in this SockAddr
117 * structure.
118 */
119 #ifndef NO_IPV6
120 #define SOCKADDR_FAMILY(addr, step) \
121 ((addr)->superfamily == UNRESOLVED ? AF_UNSPEC : \
122 (addr)->superfamily == UNIX ? AF_UNIX : \
123 (step).ai ? (step).ai->ai_family : AF_INET)
124 #else
125 /* Here we gratuitously reference 'step' to avoid gcc warnings about
126 * 'set but not used' when compiling -DNO_IPV6 */
127 #define SOCKADDR_FAMILY(addr, step) \
128 ((addr)->superfamily == UNRESOLVED ? AF_UNSPEC : \
129 (addr)->superfamily == UNIX ? AF_UNIX : \
130 (step).curraddr ? AF_INET : AF_INET)
131 #endif
132
133 /*
134 * Start a SockAddrStep structure to step through multiple
135 * addresses.
136 */
137 #ifndef NO_IPV6
138 #define START_STEP(addr, step) \
139 ((step).ai = (addr)->ais, (step).curraddr = 0)
140 #else
141 #define START_STEP(addr, step) \
142 ((step).curraddr = 0)
143 #endif
144
145 static tree234 *sktree;
146
147 static void uxsel_tell(NetSocket *s);
148
cmpfortree(void * av,void * bv)149 static int cmpfortree(void *av, void *bv)
150 {
151 NetSocket *a = (NetSocket *) av, *b = (NetSocket *) bv;
152 int as = a->s, bs = b->s;
153 if (as < bs)
154 return -1;
155 if (as > bs)
156 return +1;
157 if (a < b)
158 return -1;
159 if (a > b)
160 return +1;
161 return 0;
162 }
163
cmpforsearch(void * av,void * bv)164 static int cmpforsearch(void *av, void *bv)
165 {
166 NetSocket *b = (NetSocket *) bv;
167 int as = *(int *)av, bs = b->s;
168 if (as < bs)
169 return -1;
170 if (as > bs)
171 return +1;
172 return 0;
173 }
174
sk_init(void)175 void sk_init(void)
176 {
177 sktree = newtree234(cmpfortree);
178 }
179
sk_cleanup(void)180 void sk_cleanup(void)
181 {
182 NetSocket *s;
183 int i;
184
185 if (sktree) {
186 for (i = 0; (s = index234(sktree, i)) != NULL; i++) {
187 close(s->s);
188 }
189 }
190 }
191
sk_namelookup(const char * host,char ** canonicalname,int address_family)192 SockAddr *sk_namelookup(const char *host, char **canonicalname, int address_family)
193 {
194 if (host[0] == '/') {
195 *canonicalname = dupstr(host);
196 return unix_sock_addr(host);
197 }
198
199 SockAddr *ret = snew(SockAddr);
200 #ifndef NO_IPV6
201 struct addrinfo hints;
202 int err;
203 #else
204 unsigned long a;
205 struct hostent *h = NULL;
206 int n;
207 #endif
208 strbuf *realhost = strbuf_new();
209
210 /* Clear the structure and default to IPv4. */
211 memset(ret, 0, sizeof(SockAddr));
212 ret->superfamily = UNRESOLVED;
213 ret->error = NULL;
214 ret->refcount = 1;
215
216 #ifndef NO_IPV6
217 hints.ai_flags = AI_CANONNAME;
218 hints.ai_family = (address_family == ADDRTYPE_IPV4 ? AF_INET :
219 address_family == ADDRTYPE_IPV6 ? AF_INET6 :
220 AF_UNSPEC);
221 hints.ai_socktype = SOCK_STREAM;
222 hints.ai_protocol = 0;
223 hints.ai_addrlen = 0;
224 hints.ai_addr = NULL;
225 hints.ai_canonname = NULL;
226 hints.ai_next = NULL;
227 {
228 char *trimmed_host = host_strduptrim(host); /* strip [] on literals */
229 err = getaddrinfo(trimmed_host, NULL, &hints, &ret->ais);
230 sfree(trimmed_host);
231 }
232 if (err != 0) {
233 ret->error = gai_strerror(err);
234 strbuf_free(realhost);
235 return ret;
236 }
237 ret->superfamily = IP;
238
239 if (ret->ais->ai_canonname != NULL)
240 strbuf_catf(realhost, "%s", ret->ais->ai_canonname);
241 else
242 strbuf_catf(realhost, "%s", host);
243 #else
244 if ((a = inet_addr(host)) == (unsigned long)(in_addr_t)(-1)) {
245 /*
246 * Otherwise use the IPv4-only gethostbyname... (NOTE:
247 * we don't use gethostbyname as a fallback!)
248 */
249 if (ret->superfamily == UNRESOLVED) {
250 /*debug("Resolving \"%s\" with gethostbyname() (IPv4 only)...\n", host); */
251 if ( (h = gethostbyname(host)) )
252 ret->superfamily = IP;
253 }
254 if (ret->superfamily == UNRESOLVED) {
255 ret->error = (h_errno == HOST_NOT_FOUND ||
256 h_errno == NO_DATA ||
257 h_errno == NO_ADDRESS ? "Host does not exist" :
258 h_errno == TRY_AGAIN ?
259 "Temporary name service failure" :
260 "gethostbyname: unknown error");
261 strbuf_free(realhost);
262 return ret;
263 }
264 /* This way we are always sure the h->h_name is valid :) */
265 strbuf_clear(realhost);
266 strbuf_catf(realhost, "%s", h->h_name);
267 for (n = 0; h->h_addr_list[n]; n++);
268 ret->addresses = snewn(n, unsigned long);
269 ret->naddresses = n;
270 for (n = 0; n < ret->naddresses; n++) {
271 memcpy(&a, h->h_addr_list[n], sizeof(a));
272 ret->addresses[n] = ntohl(a);
273 }
274 } else {
275 /*
276 * This must be a numeric IPv4 address because it caused a
277 * success return from inet_addr.
278 */
279 ret->superfamily = IP;
280 strbuf_clear(realhost);
281 strbuf_catf(realhost, "%s", host);
282 ret->addresses = snew(unsigned long);
283 ret->naddresses = 1;
284 ret->addresses[0] = ntohl(a);
285 }
286 #endif
287 *canonicalname = strbuf_to_str(realhost);
288 return ret;
289 }
290
sk_nonamelookup(const char * host)291 SockAddr *sk_nonamelookup(const char *host)
292 {
293 SockAddr *ret = snew(SockAddr);
294 ret->error = NULL;
295 ret->superfamily = UNRESOLVED;
296 strncpy(ret->hostname, host, lenof(ret->hostname));
297 ret->hostname[lenof(ret->hostname)-1] = '\0';
298 #ifndef NO_IPV6
299 ret->ais = NULL;
300 #else
301 ret->addresses = NULL;
302 #endif
303 ret->refcount = 1;
304 return ret;
305 }
306
sk_nextaddr(SockAddr * addr,SockAddrStep * step)307 static bool sk_nextaddr(SockAddr *addr, SockAddrStep *step)
308 {
309 #ifndef NO_IPV6
310 if (step->ai && step->ai->ai_next) {
311 step->ai = step->ai->ai_next;
312 return true;
313 } else
314 return false;
315 #else
316 if (step->curraddr+1 < addr->naddresses) {
317 step->curraddr++;
318 return true;
319 } else {
320 return false;
321 }
322 #endif
323 }
324
sk_getaddr(SockAddr * addr,char * buf,int buflen)325 void sk_getaddr(SockAddr *addr, char *buf, int buflen)
326 {
327 if (addr->superfamily == UNRESOLVED || addr->superfamily == UNIX) {
328 strncpy(buf, addr->hostname, buflen);
329 buf[buflen-1] = '\0';
330 } else {
331 #ifndef NO_IPV6
332 if (getnameinfo(addr->ais->ai_addr, addr->ais->ai_addrlen, buf, buflen,
333 NULL, 0, NI_NUMERICHOST) != 0) {
334 buf[0] = '\0';
335 strncat(buf, "<unknown>", buflen - 1);
336 }
337 #else
338 struct in_addr a;
339 SockAddrStep step;
340 START_STEP(addr, step);
341 assert(SOCKADDR_FAMILY(addr, step) == AF_INET);
342 a.s_addr = htonl(addr->addresses[0]);
343 strncpy(buf, inet_ntoa(a), buflen);
344 buf[buflen-1] = '\0';
345 #endif
346 }
347 }
348
349 /*
350 * This constructs a SockAddr that points at one specific sub-address
351 * of a parent SockAddr. The returned SockAddr does not own all its
352 * own memory: it points into the old one's data structures, so it
353 * MUST NOT be used after the old one is freed, and it MUST NOT be
354 * passed to sk_addr_free. (The latter is why it's returned by value
355 * rather than dynamically allocated - that should clue in anyone
356 * writing a call to it that something is weird about it.)
357 */
sk_extractaddr_tmp(SockAddr * addr,const SockAddrStep * step)358 static SockAddr sk_extractaddr_tmp(
359 SockAddr *addr, const SockAddrStep *step)
360 {
361 SockAddr toret;
362 toret = *addr; /* structure copy */
363 toret.refcount = 1;
364
365 if (addr->superfamily == IP) {
366 #ifndef NO_IPV6
367 toret.ais = step->ai;
368 #else
369 assert(SOCKADDR_FAMILY(addr, *step) == AF_INET);
370 toret.addresses += step->curraddr;
371 #endif
372 }
373
374 return toret;
375 }
376
sk_addr_needs_port(SockAddr * addr)377 bool sk_addr_needs_port(SockAddr *addr)
378 {
379 if (addr->superfamily == UNRESOLVED || addr->superfamily == UNIX) {
380 return false;
381 } else {
382 return true;
383 }
384 }
385
sk_hostname_is_local(const char * name)386 bool sk_hostname_is_local(const char *name)
387 {
388 return !strcmp(name, "localhost") ||
389 !strcmp(name, "::1") ||
390 !strncmp(name, "127.", 4);
391 }
392
393 #define ipv4_is_loopback(addr) \
394 (((addr).s_addr & htonl(0xff000000)) == htonl(0x7f000000))
395
sockaddr_is_loopback(struct sockaddr * sa)396 static bool sockaddr_is_loopback(struct sockaddr *sa)
397 {
398 union sockaddr_union *u = (union sockaddr_union *)sa;
399 switch (u->sa.sa_family) {
400 case AF_INET:
401 return ipv4_is_loopback(u->sin.sin_addr);
402 #ifndef NO_IPV6
403 case AF_INET6:
404 return IN6_IS_ADDR_LOOPBACK(&u->sin6.sin6_addr);
405 #endif
406 case AF_UNIX:
407 return true;
408 default:
409 return false;
410 }
411 }
412
sk_address_is_local(SockAddr * addr)413 bool sk_address_is_local(SockAddr *addr)
414 {
415 if (addr->superfamily == UNRESOLVED)
416 return false; /* we don't know; assume not */
417 else if (addr->superfamily == UNIX)
418 return true;
419 else {
420 #ifndef NO_IPV6
421 return sockaddr_is_loopback(addr->ais->ai_addr);
422 #else
423 struct in_addr a;
424 SockAddrStep step;
425 START_STEP(addr, step);
426 assert(SOCKADDR_FAMILY(addr, step) == AF_INET);
427 a.s_addr = htonl(addr->addresses[0]);
428 return ipv4_is_loopback(a);
429 #endif
430 }
431 }
432
sk_address_is_special_local(SockAddr * addr)433 bool sk_address_is_special_local(SockAddr *addr)
434 {
435 return addr->superfamily == UNIX;
436 }
437
sk_addrtype(SockAddr * addr)438 int sk_addrtype(SockAddr *addr)
439 {
440 SockAddrStep step;
441 int family;
442 START_STEP(addr, step);
443 family = SOCKADDR_FAMILY(addr, step);
444
445 return (family == AF_INET ? ADDRTYPE_IPV4 :
446 #ifndef NO_IPV6
447 family == AF_INET6 ? ADDRTYPE_IPV6 :
448 #endif
449 ADDRTYPE_NAME);
450 }
451
sk_addrcopy(SockAddr * addr,char * buf)452 void sk_addrcopy(SockAddr *addr, char *buf)
453 {
454 SockAddrStep step;
455 int family;
456 START_STEP(addr, step);
457 family = SOCKADDR_FAMILY(addr, step);
458
459 #ifndef NO_IPV6
460 if (family == AF_INET)
461 memcpy(buf, &((struct sockaddr_in *)step.ai->ai_addr)->sin_addr,
462 sizeof(struct in_addr));
463 else if (family == AF_INET6)
464 memcpy(buf, &((struct sockaddr_in6 *)step.ai->ai_addr)->sin6_addr,
465 sizeof(struct in6_addr));
466 else
467 unreachable("bad address family in sk_addrcopy");
468 #else
469 struct in_addr a;
470
471 assert(family == AF_INET);
472 a.s_addr = htonl(addr->addresses[step.curraddr]);
473 memcpy(buf, (char*) &a.s_addr, 4);
474 #endif
475 }
476
sk_addr_free(SockAddr * addr)477 void sk_addr_free(SockAddr *addr)
478 {
479 if (--addr->refcount > 0)
480 return;
481 #ifndef NO_IPV6
482 if (addr->ais != NULL)
483 freeaddrinfo(addr->ais);
484 #else
485 sfree(addr->addresses);
486 #endif
487 sfree(addr);
488 }
489
sk_addr_dup(SockAddr * addr)490 SockAddr *sk_addr_dup(SockAddr *addr)
491 {
492 addr->refcount++;
493 return addr;
494 }
495
sk_net_plug(Socket * sock,Plug * p)496 static Plug *sk_net_plug(Socket *sock, Plug *p)
497 {
498 NetSocket *s = container_of(sock, NetSocket, sock);
499 Plug *ret = s->plug;
500 if (p)
501 s->plug = p;
502 return ret;
503 }
504
505 static void sk_net_close(Socket *s);
506 static size_t sk_net_write(Socket *s, const void *data, size_t len);
507 static size_t sk_net_write_oob(Socket *s, const void *data, size_t len);
508 static void sk_net_write_eof(Socket *s);
509 static void sk_net_set_frozen(Socket *s, bool is_frozen);
510 static SocketPeerInfo *sk_net_peer_info(Socket *s);
511 static const char *sk_net_socket_error(Socket *s);
512
513 static const SocketVtable NetSocket_sockvt = {
514 .plug = sk_net_plug,
515 .close = sk_net_close,
516 .write = sk_net_write,
517 .write_oob = sk_net_write_oob,
518 .write_eof = sk_net_write_eof,
519 .set_frozen = sk_net_set_frozen,
520 .socket_error = sk_net_socket_error,
521 .peer_info = sk_net_peer_info,
522 };
523
sk_net_accept(accept_ctx_t ctx,Plug * plug)524 static Socket *sk_net_accept(accept_ctx_t ctx, Plug *plug)
525 {
526 int sockfd = ctx.i;
527 NetSocket *ret;
528
529 /*
530 * Create NetSocket structure.
531 */
532 ret = snew(NetSocket);
533 ret->sock.vt = &NetSocket_sockvt;
534 ret->error = NULL;
535 ret->plug = plug;
536 bufchain_init(&ret->output_data);
537 ret->writable = true; /* to start with */
538 ret->sending_oob = 0;
539 ret->frozen = true;
540 ret->localhost_only = false; /* unused, but best init anyway */
541 ret->pending_error = 0;
542 ret->oobpending = false;
543 ret->outgoingeof = EOF_NO;
544 ret->incomingeof = false;
545 ret->listener = false;
546 ret->parent = ret->child = NULL;
547 ret->addr = NULL;
548 ret->connected = true;
549
550 ret->s = sockfd;
551
552 if (ret->s < 0) {
553 ret->error = strerror(errno);
554 return &ret->sock;
555 }
556
557 ret->oobinline = false;
558
559 uxsel_tell(ret);
560 add234(sktree, ret);
561
562 return &ret->sock;
563 }
564
try_connect(NetSocket * sock)565 static int try_connect(NetSocket *sock)
566 {
567 int s;
568 union sockaddr_union u;
569 const union sockaddr_union *sa;
570 int err = 0;
571 short localport;
572 int salen, family;
573
574 /*
575 * Remove the socket from the tree before we overwrite its
576 * internal socket id, because that forms part of the tree's
577 * sorting criterion. We'll add it back before exiting this
578 * function, whether we changed anything or not.
579 */
580 del234(sktree, sock);
581
582 if (sock->s >= 0)
583 close(sock->s);
584
585 {
586 SockAddr thisaddr = sk_extractaddr_tmp(
587 sock->addr, &sock->step);
588 plug_log(sock->plug, PLUGLOG_CONNECT_TRYING,
589 &thisaddr, sock->port, NULL, 0);
590 }
591
592 /*
593 * Open socket.
594 */
595 family = SOCKADDR_FAMILY(sock->addr, sock->step);
596 assert(family != AF_UNSPEC);
597 s = socket(family, SOCK_STREAM, 0);
598 sock->s = s;
599
600 if (s < 0) {
601 err = errno;
602 goto ret;
603 }
604
605 cloexec(s);
606
607 if (sock->oobinline) {
608 int b = 1;
609 if (setsockopt(s, SOL_SOCKET, SO_OOBINLINE,
610 (void *) &b, sizeof(b)) < 0) {
611 err = errno;
612 close(s);
613 goto ret;
614 }
615 }
616
617 if (sock->nodelay && family != AF_UNIX) {
618 int b = 1;
619 if (setsockopt(s, IPPROTO_TCP, TCP_NODELAY,
620 (void *) &b, sizeof(b)) < 0) {
621 err = errno;
622 close(s);
623 goto ret;
624 }
625 }
626
627 if (sock->keepalive) {
628 int b = 1;
629 if (setsockopt(s, SOL_SOCKET, SO_KEEPALIVE,
630 (void *) &b, sizeof(b)) < 0) {
631 err = errno;
632 close(s);
633 goto ret;
634 }
635 }
636
637 /*
638 * Bind to local address.
639 */
640 if (sock->privport)
641 localport = 1023; /* count from 1023 downwards */
642 else
643 localport = 0; /* just use port 0 (ie kernel picks) */
644
645 /* BSD IP stacks need sockaddr_in zeroed before filling in */
646 memset(&u,'\0',sizeof(u));
647
648 /* We don't try to bind to a local address for UNIX domain sockets. (Why
649 * do we bother doing the bind when localport == 0 anyway?) */
650 if (family != AF_UNIX) {
651 /* Loop round trying to bind */
652 while (1) {
653 int retcode;
654
655 #ifndef NO_IPV6
656 if (family == AF_INET6) {
657 /* XXX use getaddrinfo to get a local address? */
658 u.sin6.sin6_family = AF_INET6;
659 u.sin6.sin6_addr = in6addr_any;
660 u.sin6.sin6_port = htons(localport);
661 retcode = bind(s, &u.sa, sizeof(u.sin6));
662 } else
663 #endif
664 {
665 assert(family == AF_INET);
666 u.sin.sin_family = AF_INET;
667 u.sin.sin_addr.s_addr = htonl(INADDR_ANY);
668 u.sin.sin_port = htons(localport);
669 retcode = bind(s, &u.sa, sizeof(u.sin));
670 }
671 if (retcode >= 0) {
672 err = 0;
673 break; /* done */
674 } else {
675 err = errno;
676 if (err != EADDRINUSE) /* failed, for a bad reason */
677 break;
678 }
679
680 if (localport == 0)
681 break; /* we're only looping once */
682 localport--;
683 if (localport == 0)
684 break; /* we might have got to the end */
685 }
686
687 if (err)
688 goto ret;
689 }
690
691 /*
692 * Connect to remote address.
693 */
694 switch(family) {
695 #ifndef NO_IPV6
696 case AF_INET:
697 /* XXX would be better to have got getaddrinfo() to fill in the port. */
698 ((struct sockaddr_in *)sock->step.ai->ai_addr)->sin_port =
699 htons(sock->port);
700 sa = (const union sockaddr_union *)sock->step.ai->ai_addr;
701 salen = sock->step.ai->ai_addrlen;
702 break;
703 case AF_INET6:
704 ((struct sockaddr_in *)sock->step.ai->ai_addr)->sin_port =
705 htons(sock->port);
706 sa = (const union sockaddr_union *)sock->step.ai->ai_addr;
707 salen = sock->step.ai->ai_addrlen;
708 break;
709 #else
710 case AF_INET:
711 u.sin.sin_family = AF_INET;
712 u.sin.sin_addr.s_addr = htonl(sock->addr->addresses[sock->step.curraddr]);
713 u.sin.sin_port = htons((short) sock->port);
714 sa = &u;
715 salen = sizeof u.sin;
716 break;
717 #endif
718 case AF_UNIX:
719 assert(strlen(sock->addr->hostname) < sizeof u.su.sun_path);
720 u.su.sun_family = AF_UNIX;
721 strcpy(u.su.sun_path, sock->addr->hostname);
722 sa = &u;
723 salen = sizeof u.su;
724 break;
725
726 default:
727 unreachable("unknown address family");
728 exit(1); /* XXX: GCC doesn't understand assert() on some systems. */
729 }
730
731 nonblock(s);
732
733 if ((connect(s, &(sa->sa), salen)) < 0) {
734 if ( errno != EINPROGRESS ) {
735 err = errno;
736 goto ret;
737 }
738 } else {
739 /*
740 * If we _don't_ get EWOULDBLOCK, the connect has completed
741 * and we should set the socket as connected and writable.
742 */
743 sock->connected = true;
744 sock->writable = true;
745
746 SockAddr thisaddr = sk_extractaddr_tmp(sock->addr, &sock->step);
747 plug_log(sock->plug, PLUGLOG_CONNECT_SUCCESS,
748 &thisaddr, sock->port, NULL, 0);
749 }
750
751 uxsel_tell(sock);
752
753 ret:
754
755 /*
756 * No matter what happened, put the socket back in the tree.
757 */
758 add234(sktree, sock);
759
760 if (err) {
761 SockAddr thisaddr = sk_extractaddr_tmp(
762 sock->addr, &sock->step);
763 plug_log(sock->plug, PLUGLOG_CONNECT_FAILED,
764 &thisaddr, sock->port, strerror(err), err);
765 }
766 return err;
767 }
768
sk_new(SockAddr * addr,int port,bool privport,bool oobinline,bool nodelay,bool keepalive,Plug * plug)769 Socket *sk_new(SockAddr *addr, int port, bool privport, bool oobinline,
770 bool nodelay, bool keepalive, Plug *plug)
771 {
772 NetSocket *ret;
773 int err;
774
775 /*
776 * Create NetSocket structure.
777 */
778 ret = snew(NetSocket);
779 ret->sock.vt = &NetSocket_sockvt;
780 ret->error = NULL;
781 ret->plug = plug;
782 bufchain_init(&ret->output_data);
783 ret->connected = false; /* to start with */
784 ret->writable = false; /* to start with */
785 ret->sending_oob = 0;
786 ret->frozen = false;
787 ret->localhost_only = false; /* unused, but best init anyway */
788 ret->pending_error = 0;
789 ret->parent = ret->child = NULL;
790 ret->oobpending = false;
791 ret->outgoingeof = EOF_NO;
792 ret->incomingeof = false;
793 ret->listener = false;
794 ret->addr = addr;
795 START_STEP(ret->addr, ret->step);
796 ret->s = -1;
797 ret->oobinline = oobinline;
798 ret->nodelay = nodelay;
799 ret->keepalive = keepalive;
800 ret->privport = privport;
801 ret->port = port;
802
803 do {
804 err = try_connect(ret);
805 } while (err && sk_nextaddr(ret->addr, &ret->step));
806
807 if (err)
808 ret->error = strerror(err);
809
810 return &ret->sock;
811 }
812
sk_newlistener(const char * srcaddr,int port,Plug * plug,bool local_host_only,int orig_address_family)813 Socket *sk_newlistener(const char *srcaddr, int port, Plug *plug,
814 bool local_host_only, int orig_address_family)
815 {
816 int s;
817 #ifndef NO_IPV6
818 struct addrinfo hints, *ai = NULL;
819 char portstr[6];
820 #endif
821 union sockaddr_union u;
822 union sockaddr_union *addr;
823 int addrlen;
824 NetSocket *ret;
825 int retcode;
826 int address_family;
827 int on = 1;
828
829 /*
830 * Create NetSocket structure.
831 */
832 ret = snew(NetSocket);
833 ret->sock.vt = &NetSocket_sockvt;
834 ret->error = NULL;
835 ret->plug = plug;
836 bufchain_init(&ret->output_data);
837 ret->writable = false; /* to start with */
838 ret->sending_oob = 0;
839 ret->frozen = false;
840 ret->localhost_only = local_host_only;
841 ret->pending_error = 0;
842 ret->parent = ret->child = NULL;
843 ret->oobpending = false;
844 ret->outgoingeof = EOF_NO;
845 ret->incomingeof = false;
846 ret->listener = true;
847 ret->addr = NULL;
848 ret->s = -1;
849
850 /*
851 * Translate address_family from platform-independent constants
852 * into local reality.
853 */
854 address_family = (orig_address_family == ADDRTYPE_IPV4 ? AF_INET :
855 #ifndef NO_IPV6
856 orig_address_family == ADDRTYPE_IPV6 ? AF_INET6 :
857 #endif
858 AF_UNSPEC);
859
860 #ifndef NO_IPV6
861 /* Let's default to IPv6.
862 * If the stack doesn't support IPv6, we will fall back to IPv4. */
863 if (address_family == AF_UNSPEC) address_family = AF_INET6;
864 #else
865 /* No other choice, default to IPv4 */
866 if (address_family == AF_UNSPEC) address_family = AF_INET;
867 #endif
868
869 /*
870 * Open socket.
871 */
872 s = socket(address_family, SOCK_STREAM, 0);
873
874 #ifndef NO_IPV6
875 /* If the host doesn't support IPv6 try fallback to IPv4. */
876 if (s < 0 && address_family == AF_INET6) {
877 address_family = AF_INET;
878 s = socket(address_family, SOCK_STREAM, 0);
879 }
880 #endif
881
882 if (s < 0) {
883 ret->error = strerror(errno);
884 return &ret->sock;
885 }
886
887 cloexec(s);
888
889 ret->oobinline = false;
890
891 if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
892 (const char *)&on, sizeof(on)) < 0) {
893 ret->error = strerror(errno);
894 close(s);
895 return &ret->sock;
896 }
897
898 retcode = -1;
899 addr = NULL; addrlen = -1; /* placate optimiser */
900
901 if (srcaddr != NULL) {
902 #ifndef NO_IPV6
903 hints.ai_flags = AI_NUMERICHOST;
904 hints.ai_family = address_family;
905 hints.ai_socktype = SOCK_STREAM;
906 hints.ai_protocol = 0;
907 hints.ai_addrlen = 0;
908 hints.ai_addr = NULL;
909 hints.ai_canonname = NULL;
910 hints.ai_next = NULL;
911 assert(port >= 0 && port <= 99999);
912 sprintf(portstr, "%d", port);
913 {
914 char *trimmed_addr = host_strduptrim(srcaddr);
915 retcode = getaddrinfo(trimmed_addr, portstr, &hints, &ai);
916 sfree(trimmed_addr);
917 }
918 if (retcode == 0) {
919 addr = (union sockaddr_union *)ai->ai_addr;
920 addrlen = ai->ai_addrlen;
921 }
922 #else
923 memset(&u,'\0',sizeof u);
924 u.sin.sin_family = AF_INET;
925 u.sin.sin_port = htons(port);
926 u.sin.sin_addr.s_addr = inet_addr(srcaddr);
927 if (u.sin.sin_addr.s_addr != (in_addr_t)(-1)) {
928 /* Override localhost_only with specified listen addr. */
929 ret->localhost_only = ipv4_is_loopback(u.sin.sin_addr);
930 }
931 addr = &u;
932 addrlen = sizeof(u.sin);
933 retcode = 0;
934 #endif
935 }
936
937 if (retcode != 0) {
938 memset(&u,'\0',sizeof u);
939 #ifndef NO_IPV6
940 if (address_family == AF_INET6) {
941 u.sin6.sin6_family = AF_INET6;
942 u.sin6.sin6_port = htons(port);
943 if (local_host_only)
944 u.sin6.sin6_addr = in6addr_loopback;
945 else
946 u.sin6.sin6_addr = in6addr_any;
947 addr = &u;
948 addrlen = sizeof(u.sin6);
949 } else
950 #endif
951 {
952 u.sin.sin_family = AF_INET;
953 u.sin.sin_port = htons(port);
954 if (local_host_only)
955 u.sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
956 else
957 u.sin.sin_addr.s_addr = htonl(INADDR_ANY);
958 addr = &u;
959 addrlen = sizeof(u.sin);
960 }
961 }
962
963 retcode = bind(s, &addr->sa, addrlen);
964
965 #ifndef NO_IPV6
966 if (ai)
967 freeaddrinfo(ai);
968 #endif
969
970 if (retcode < 0) {
971 close(s);
972 ret->error = strerror(errno);
973 return &ret->sock;
974 }
975
976 if (listen(s, SOMAXCONN) < 0) {
977 close(s);
978 ret->error = strerror(errno);
979 return &ret->sock;
980 }
981
982 #ifndef NO_IPV6
983 /*
984 * If we were given ADDRTYPE_UNSPEC, we must also create an
985 * IPv4 listening socket and link it to this one.
986 */
987 if (address_family == AF_INET6 && orig_address_family == ADDRTYPE_UNSPEC) {
988 NetSocket *other;
989
990 other = container_of(
991 sk_newlistener(srcaddr, port, plug,
992 local_host_only, ADDRTYPE_IPV4),
993 NetSocket, sock);
994
995 if (other) {
996 if (!other->error) {
997 other->parent = ret;
998 ret->child = other;
999 } else {
1000 /* If we couldn't create a listening socket on IPv4 as well
1001 * as IPv6, we must return an error overall. */
1002 close(s);
1003 sfree(ret);
1004 return &other->sock;
1005 }
1006 }
1007 }
1008 #endif
1009
1010 ret->s = s;
1011
1012 uxsel_tell(ret);
1013 add234(sktree, ret);
1014
1015 return &ret->sock;
1016 }
1017
sk_net_close(Socket * sock)1018 static void sk_net_close(Socket *sock)
1019 {
1020 NetSocket *s = container_of(sock, NetSocket, sock);
1021
1022 if (s->child)
1023 sk_net_close(&s->child->sock);
1024
1025 bufchain_clear(&s->output_data);
1026
1027 del234(sktree, s);
1028 if (s->s >= 0) {
1029 uxsel_del(s->s);
1030 close(s->s);
1031 }
1032 if (s->addr)
1033 sk_addr_free(s->addr);
1034 delete_callbacks_for_context(s);
1035 sfree(s);
1036 }
1037
sk_getxdmdata(Socket * sock,int * lenp)1038 void *sk_getxdmdata(Socket *sock, int *lenp)
1039 {
1040 NetSocket *s;
1041 union sockaddr_union u;
1042 socklen_t addrlen;
1043 char *buf;
1044 static unsigned int unix_addr = 0xFFFFFFFF;
1045
1046 /*
1047 * We must check that this socket really _is_ a NetSocket before
1048 * downcasting it.
1049 */
1050 if (sock->vt != &NetSocket_sockvt)
1051 return NULL; /* failure */
1052 s = container_of(sock, NetSocket, sock);
1053
1054 addrlen = sizeof(u);
1055 if (getsockname(s->s, &u.sa, &addrlen) < 0)
1056 return NULL;
1057 switch(u.sa.sa_family) {
1058 case AF_INET:
1059 *lenp = 6;
1060 buf = snewn(*lenp, char);
1061 PUT_32BIT_MSB_FIRST(buf, ntohl(u.sin.sin_addr.s_addr));
1062 PUT_16BIT_MSB_FIRST(buf+4, ntohs(u.sin.sin_port));
1063 break;
1064 #ifndef NO_IPV6
1065 case AF_INET6:
1066 *lenp = 6;
1067 buf = snewn(*lenp, char);
1068 if (IN6_IS_ADDR_V4MAPPED(&u.sin6.sin6_addr)) {
1069 memcpy(buf, u.sin6.sin6_addr.s6_addr + 12, 4);
1070 PUT_16BIT_MSB_FIRST(buf+4, ntohs(u.sin6.sin6_port));
1071 } else
1072 /* This is stupid, but it's what XLib does. */
1073 memset(buf, 0, 6);
1074 break;
1075 #endif
1076 case AF_UNIX:
1077 *lenp = 6;
1078 buf = snewn(*lenp, char);
1079 PUT_32BIT_MSB_FIRST(buf, unix_addr--);
1080 PUT_16BIT_MSB_FIRST(buf+4, getpid());
1081 break;
1082
1083 /* XXX IPV6 */
1084
1085 default:
1086 return NULL;
1087 }
1088
1089 return buf;
1090 }
1091
1092 /*
1093 * Deal with socket errors detected in try_send().
1094 */
socket_error_callback(void * vs)1095 static void socket_error_callback(void *vs)
1096 {
1097 NetSocket *s = (NetSocket *)vs;
1098
1099 /*
1100 * Just in case other socket work has caused this socket to vanish
1101 * or become somehow non-erroneous before this callback arrived...
1102 */
1103 if (!find234(sktree, s, NULL) || !s->pending_error)
1104 return;
1105
1106 /*
1107 * An error has occurred on this socket. Pass it to the plug.
1108 */
1109 plug_closing(s->plug, strerror(s->pending_error), s->pending_error, 0);
1110 }
1111
1112 /*
1113 * The function which tries to send on a socket once it's deemed
1114 * writable.
1115 */
try_send(NetSocket * s)1116 void try_send(NetSocket *s)
1117 {
1118 while (s->sending_oob || bufchain_size(&s->output_data) > 0) {
1119 int nsent;
1120 int err;
1121 const void *data;
1122 size_t len;
1123 int urgentflag;
1124
1125 if (s->sending_oob) {
1126 urgentflag = MSG_OOB;
1127 len = s->sending_oob;
1128 data = &s->oobdata;
1129 } else {
1130 urgentflag = 0;
1131 ptrlen bufdata = bufchain_prefix(&s->output_data);
1132 data = bufdata.ptr;
1133 len = bufdata.len;
1134 }
1135 nsent = send(s->s, data, len, urgentflag);
1136 noise_ultralight(NOISE_SOURCE_IOLEN, nsent);
1137 if (nsent <= 0) {
1138 err = (nsent < 0 ? errno : 0);
1139 if (err == EWOULDBLOCK) {
1140 /*
1141 * Perfectly normal: we've sent all we can for the moment.
1142 */
1143 s->writable = false;
1144 return;
1145 } else {
1146 /*
1147 * We unfortunately can't just call plug_closing(),
1148 * because it's quite likely that we're currently
1149 * _in_ a call from the code we'd be calling back
1150 * to, so we'd have to make half the SSH code
1151 * reentrant. Instead we flag a pending error on
1152 * the socket, to be dealt with (by calling
1153 * plug_closing()) at some suitable future moment.
1154 */
1155 s->pending_error = err;
1156 /*
1157 * Immediately cease selecting on this socket, so that
1158 * we don't tight-loop repeatedly trying to do
1159 * whatever it was that went wrong.
1160 */
1161 uxsel_tell(s);
1162 /*
1163 * Arrange to be called back from the top level to
1164 * deal with the error condition on this socket.
1165 */
1166 queue_toplevel_callback(socket_error_callback, s);
1167 return;
1168 }
1169 } else {
1170 if (s->sending_oob) {
1171 if (nsent < len) {
1172 memmove(s->oobdata, s->oobdata+nsent, len-nsent);
1173 s->sending_oob = len - nsent;
1174 } else {
1175 s->sending_oob = 0;
1176 }
1177 } else {
1178 bufchain_consume(&s->output_data, nsent);
1179 }
1180 }
1181 }
1182
1183 /*
1184 * If we reach here, we've finished sending everything we might
1185 * have needed to send. Send EOF, if we need to.
1186 */
1187 if (s->outgoingeof == EOF_PENDING) {
1188 shutdown(s->s, SHUT_WR);
1189 s->outgoingeof = EOF_SENT;
1190 }
1191
1192 /*
1193 * Also update the select status, because we don't need to select
1194 * for writing any more.
1195 */
1196 uxsel_tell(s);
1197 }
1198
sk_net_write(Socket * sock,const void * buf,size_t len)1199 static size_t sk_net_write(Socket *sock, const void *buf, size_t len)
1200 {
1201 NetSocket *s = container_of(sock, NetSocket, sock);
1202
1203 assert(s->outgoingeof == EOF_NO);
1204
1205 /*
1206 * Add the data to the buffer list on the socket.
1207 */
1208 bufchain_add(&s->output_data, buf, len);
1209
1210 /*
1211 * Now try sending from the start of the buffer list.
1212 */
1213 if (s->writable)
1214 try_send(s);
1215
1216 /*
1217 * Update the select() status to correctly reflect whether or
1218 * not we should be selecting for write.
1219 */
1220 uxsel_tell(s);
1221
1222 return bufchain_size(&s->output_data);
1223 }
1224
sk_net_write_oob(Socket * sock,const void * buf,size_t len)1225 static size_t sk_net_write_oob(Socket *sock, const void *buf, size_t len)
1226 {
1227 NetSocket *s = container_of(sock, NetSocket, sock);
1228
1229 assert(s->outgoingeof == EOF_NO);
1230
1231 /*
1232 * Replace the buffer list on the socket with the data.
1233 */
1234 bufchain_clear(&s->output_data);
1235 assert(len <= sizeof(s->oobdata));
1236 memcpy(s->oobdata, buf, len);
1237 s->sending_oob = len;
1238
1239 /*
1240 * Now try sending from the start of the buffer list.
1241 */
1242 if (s->writable)
1243 try_send(s);
1244
1245 /*
1246 * Update the select() status to correctly reflect whether or
1247 * not we should be selecting for write.
1248 */
1249 uxsel_tell(s);
1250
1251 return s->sending_oob;
1252 }
1253
sk_net_write_eof(Socket * sock)1254 static void sk_net_write_eof(Socket *sock)
1255 {
1256 NetSocket *s = container_of(sock, NetSocket, sock);
1257
1258 assert(s->outgoingeof == EOF_NO);
1259
1260 /*
1261 * Mark the socket as pending outgoing EOF.
1262 */
1263 s->outgoingeof = EOF_PENDING;
1264
1265 /*
1266 * Now try sending from the start of the buffer list.
1267 */
1268 if (s->writable)
1269 try_send(s);
1270
1271 /*
1272 * Update the select() status to correctly reflect whether or
1273 * not we should be selecting for write.
1274 */
1275 uxsel_tell(s);
1276 }
1277
net_select_result(int fd,int event)1278 static void net_select_result(int fd, int event)
1279 {
1280 int ret;
1281 char buf[20480]; /* nice big buffer for plenty of speed */
1282 NetSocket *s;
1283 bool atmark = true;
1284
1285 /* Find the Socket structure */
1286 s = find234(sktree, &fd, cmpforsearch);
1287 if (!s)
1288 return; /* boggle */
1289
1290 noise_ultralight(NOISE_SOURCE_IOID, fd);
1291
1292 switch (event) {
1293 case SELECT_X: /* exceptional */
1294 if (!s->oobinline) {
1295 /*
1296 * On a non-oobinline socket, this indicates that we
1297 * can immediately perform an OOB read and get back OOB
1298 * data, which we will send to the back end with
1299 * type==2 (urgent data).
1300 */
1301 ret = recv(s->s, buf, sizeof(buf), MSG_OOB);
1302 noise_ultralight(NOISE_SOURCE_IOLEN, ret);
1303 if (ret <= 0) {
1304 plug_closing(s->plug,
1305 ret == 0 ? "Internal networking trouble" :
1306 strerror(errno), errno, 0);
1307 } else {
1308 /*
1309 * Receiving actual data on a socket means we can
1310 * stop falling back through the candidate
1311 * addresses to connect to.
1312 */
1313 if (s->addr) {
1314 sk_addr_free(s->addr);
1315 s->addr = NULL;
1316 }
1317 plug_receive(s->plug, 2, buf, ret);
1318 }
1319 break;
1320 }
1321
1322 /*
1323 * If we reach here, this is an oobinline socket, which
1324 * means we should set s->oobpending and then deal with it
1325 * when we get called for the readability event (which
1326 * should also occur).
1327 */
1328 s->oobpending = true;
1329 break;
1330 case SELECT_R: /* readable; also acceptance */
1331 if (s->listener) {
1332 /*
1333 * On a listening socket, the readability event means a
1334 * connection is ready to be accepted.
1335 */
1336 union sockaddr_union su;
1337 socklen_t addrlen = sizeof(su);
1338 accept_ctx_t actx;
1339 int t; /* socket of connection */
1340
1341 memset(&su, 0, addrlen);
1342 t = accept(s->s, &su.sa, &addrlen);
1343 if (t < 0) {
1344 break;
1345 }
1346
1347 nonblock(t);
1348 actx.i = t;
1349
1350 if ((!s->addr || s->addr->superfamily != UNIX) &&
1351 s->localhost_only && !sockaddr_is_loopback(&su.sa)) {
1352 close(t); /* someone let nonlocal through?! */
1353 } else if (plug_accepting(s->plug, sk_net_accept, actx)) {
1354 close(t); /* denied or error */
1355 }
1356 break;
1357 }
1358
1359 /*
1360 * If we reach here, this is not a listening socket, so
1361 * readability really means readability.
1362 */
1363
1364 /* In the case the socket is still frozen, we don't even bother */
1365 if (s->frozen)
1366 break;
1367
1368 /*
1369 * We have received data on the socket. For an oobinline
1370 * socket, this might be data _before_ an urgent pointer,
1371 * in which case we send it to the back end with type==1
1372 * (data prior to urgent).
1373 */
1374 if (s->oobinline && s->oobpending) {
1375 int atmark_from_ioctl;
1376 if (ioctl(s->s, SIOCATMARK, &atmark_from_ioctl) == 0) {
1377 atmark = atmark_from_ioctl;
1378 if (atmark)
1379 s->oobpending = false; /* clear this indicator */
1380 }
1381 } else
1382 atmark = true;
1383
1384 ret = recv(s->s, buf, s->oobpending ? 1 : sizeof(buf), 0);
1385 noise_ultralight(NOISE_SOURCE_IOLEN, ret);
1386 if (ret < 0) {
1387 if (errno == EWOULDBLOCK) {
1388 break;
1389 }
1390 }
1391 if (ret < 0) {
1392 plug_closing(s->plug, strerror(errno), errno, 0);
1393 } else if (0 == ret) {
1394 s->incomingeof = true; /* stop trying to read now */
1395 uxsel_tell(s);
1396 plug_closing(s->plug, NULL, 0, 0);
1397 } else {
1398 /*
1399 * Receiving actual data on a socket means we can
1400 * stop falling back through the candidate
1401 * addresses to connect to.
1402 */
1403 if (s->addr) {
1404 sk_addr_free(s->addr);
1405 s->addr = NULL;
1406 }
1407 plug_receive(s->plug, atmark ? 0 : 1, buf, ret);
1408 }
1409 break;
1410 case SELECT_W: /* writable */
1411 if (!s->connected) {
1412 /*
1413 * select/poll reports a socket as _writable_ when an
1414 * asynchronous connect() attempt either completes or
1415 * fails. So first we must find out which.
1416 */
1417 {
1418 int err;
1419 socklen_t errlen = sizeof(err);
1420 char *errmsg = NULL;
1421 if (getsockopt(s->s, SOL_SOCKET, SO_ERROR, &err, &errlen)<0) {
1422 errmsg = dupprintf("getsockopt(SO_ERROR): %s",
1423 strerror(errno));
1424 err = errno; /* got to put something in here */
1425 } else if (err != 0) {
1426 errmsg = dupstr(strerror(err));
1427 }
1428 if (errmsg) {
1429 /*
1430 * The asynchronous connection attempt failed.
1431 * Report the problem via plug_log, and try again
1432 * with the next candidate address, if we have
1433 * more than one.
1434 */
1435 SockAddr thisaddr;
1436 assert(s->addr);
1437
1438 thisaddr = sk_extractaddr_tmp(s->addr, &s->step);
1439 plug_log(s->plug, PLUGLOG_CONNECT_FAILED,
1440 &thisaddr, s->port, errmsg, err);
1441
1442 while (err && s->addr && sk_nextaddr(s->addr, &s->step)) {
1443 err = try_connect(s);
1444 }
1445 if (err) {
1446 plug_closing(s->plug, strerror(err), err, 0);
1447 return; /* socket is now presumably defunct */
1448 }
1449 if (!s->connected)
1450 return; /* another async attempt in progress */
1451 } else {
1452 /*
1453 * The connection attempt succeeded.
1454 */
1455 SockAddr thisaddr = sk_extractaddr_tmp(s->addr, &s->step);
1456 plug_log(s->plug, PLUGLOG_CONNECT_SUCCESS,
1457 &thisaddr, s->port, NULL, 0);
1458 }
1459 }
1460
1461 /*
1462 * If we get here, we've managed to make a connection.
1463 */
1464 if (s->addr) {
1465 sk_addr_free(s->addr);
1466 s->addr = NULL;
1467 }
1468 s->connected = true;
1469 s->writable = true;
1470 uxsel_tell(s);
1471 } else {
1472 size_t bufsize_before, bufsize_after;
1473 s->writable = true;
1474 bufsize_before = s->sending_oob + bufchain_size(&s->output_data);
1475 try_send(s);
1476 bufsize_after = s->sending_oob + bufchain_size(&s->output_data);
1477 if (bufsize_after < bufsize_before)
1478 plug_sent(s->plug, bufsize_after);
1479 }
1480 break;
1481 }
1482 }
1483
1484 /*
1485 * Special error values are returned from sk_namelookup and sk_new
1486 * if there's a problem. These functions extract an error message,
1487 * or return NULL if there's no problem.
1488 */
sk_addr_error(SockAddr * addr)1489 const char *sk_addr_error(SockAddr *addr)
1490 {
1491 return addr->error;
1492 }
sk_net_socket_error(Socket * sock)1493 static const char *sk_net_socket_error(Socket *sock)
1494 {
1495 NetSocket *s = container_of(sock, NetSocket, sock);
1496 return s->error;
1497 }
1498
sk_net_set_frozen(Socket * sock,bool is_frozen)1499 static void sk_net_set_frozen(Socket *sock, bool is_frozen)
1500 {
1501 NetSocket *s = container_of(sock, NetSocket, sock);
1502 if (s->frozen == is_frozen)
1503 return;
1504 s->frozen = is_frozen;
1505 uxsel_tell(s);
1506 }
1507
sk_net_peer_info(Socket * sock)1508 static SocketPeerInfo *sk_net_peer_info(Socket *sock)
1509 {
1510 NetSocket *s = container_of(sock, NetSocket, sock);
1511 union sockaddr_union addr;
1512 socklen_t addrlen = sizeof(addr);
1513 #ifndef NO_IPV6
1514 char buf[INET6_ADDRSTRLEN];
1515 #endif
1516 SocketPeerInfo *pi;
1517
1518 if (getpeername(s->s, &addr.sa, &addrlen) < 0)
1519 return NULL;
1520
1521 pi = snew(SocketPeerInfo);
1522 pi->addressfamily = ADDRTYPE_UNSPEC;
1523 pi->addr_text = NULL;
1524 pi->port = -1;
1525 pi->log_text = NULL;
1526
1527 if (addr.storage.ss_family == AF_INET) {
1528 pi->addressfamily = ADDRTYPE_IPV4;
1529 memcpy(pi->addr_bin.ipv4, &addr.sin.sin_addr, 4);
1530 pi->port = ntohs(addr.sin.sin_port);
1531 pi->addr_text = dupstr(inet_ntoa(addr.sin.sin_addr));
1532 pi->log_text = dupprintf("%s:%d", pi->addr_text, pi->port);
1533
1534 #ifndef NO_IPV6
1535 } else if (addr.storage.ss_family == AF_INET6) {
1536 pi->addressfamily = ADDRTYPE_IPV6;
1537 memcpy(pi->addr_bin.ipv6, &addr.sin6.sin6_addr, 16);
1538 pi->port = ntohs(addr.sin6.sin6_port);
1539 pi->addr_text = dupstr(
1540 inet_ntop(AF_INET6, &addr.sin6.sin6_addr, buf, sizeof(buf)));
1541 pi->log_text = dupprintf("[%s]:%d", pi->addr_text, pi->port);
1542 #endif
1543
1544 } else if (addr.storage.ss_family == AF_UNIX) {
1545 pi->addressfamily = ADDRTYPE_LOCAL;
1546
1547 /*
1548 * For Unix sockets, the source address is unlikely to be
1549 * helpful, so we leave addr_txt NULL (and we certainly can't
1550 * fill in port, obviously). Instead, we try SO_PEERCRED and
1551 * try to get the source pid, and put that in the log text.
1552 */
1553 int pid, uid, gid;
1554 if (so_peercred(s->s, &pid, &uid, &gid)) {
1555 char uidbuf[64], gidbuf[64];
1556 sprintf(uidbuf, "%d", uid);
1557 sprintf(gidbuf, "%d", gid);
1558 struct passwd *pw = getpwuid(uid);
1559 struct group *gr = getgrgid(gid);
1560 pi->log_text = dupprintf("pid %d (%s:%s)", pid,
1561 pw ? pw->pw_name : uidbuf,
1562 gr ? gr->gr_name : gidbuf);
1563 }
1564 } else {
1565 sfree(pi);
1566 return NULL;
1567 }
1568
1569 return pi;
1570 }
1571
sk_net_get_fd(Socket * sock)1572 int sk_net_get_fd(Socket *sock)
1573 {
1574 /* This function is not fully general: it only works on NetSocket */
1575 if (sock->vt != &NetSocket_sockvt)
1576 return -1; /* failure */
1577 NetSocket *s = container_of(sock, NetSocket, sock);
1578 return s->s;
1579 }
1580
uxsel_tell(NetSocket * s)1581 static void uxsel_tell(NetSocket *s)
1582 {
1583 int rwx = 0;
1584 if (!s->pending_error) {
1585 if (s->listener) {
1586 rwx |= SELECT_R; /* read == accept */
1587 } else {
1588 if (!s->connected)
1589 rwx |= SELECT_W; /* write == connect */
1590 if (s->connected && !s->frozen && !s->incomingeof)
1591 rwx |= SELECT_R | SELECT_X;
1592 if (bufchain_size(&s->output_data))
1593 rwx |= SELECT_W;
1594 }
1595 }
1596 uxsel_set(s->s, rwx, net_select_result);
1597 }
1598
net_service_lookup(char * service)1599 int net_service_lookup(char *service)
1600 {
1601 struct servent *se;
1602 se = getservbyname(service, NULL);
1603 if (se != NULL)
1604 return ntohs(se->s_port);
1605 else
1606 return 0;
1607 }
1608
get_hostname(void)1609 char *get_hostname(void)
1610 {
1611 size_t size = 0;
1612 char *hostname = NULL;
1613 do {
1614 sgrowarray(hostname, size, size);
1615 if ((gethostname(hostname, size) < 0) && (errno != ENAMETOOLONG)) {
1616 sfree(hostname);
1617 hostname = NULL;
1618 break;
1619 }
1620 } while (strlen(hostname) >= size-1);
1621 return hostname;
1622 }
1623
platform_get_x11_unix_address(const char * sockpath,int displaynum)1624 SockAddr *platform_get_x11_unix_address(const char *sockpath, int displaynum)
1625 {
1626 SockAddr *ret = snew(SockAddr);
1627 int n;
1628
1629 memset(ret, 0, sizeof *ret);
1630 ret->superfamily = UNIX;
1631 /*
1632 * In special circumstances (notably Mac OS X Leopard), we'll
1633 * have been passed an explicit Unix socket path.
1634 */
1635 if (sockpath) {
1636 n = snprintf(ret->hostname, sizeof ret->hostname,
1637 "%s", sockpath);
1638 } else {
1639 n = snprintf(ret->hostname, sizeof ret->hostname,
1640 "%s%d", X11_UNIX_PATH, displaynum);
1641 }
1642
1643 if (n < 0)
1644 ret->error = "snprintf failed";
1645 else if (n >= sizeof ret->hostname)
1646 ret->error = "X11 UNIX name too long";
1647
1648 #ifndef NO_IPV6
1649 ret->ais = NULL;
1650 #else
1651 ret->addresses = NULL;
1652 ret->naddresses = 0;
1653 #endif
1654 ret->refcount = 1;
1655 return ret;
1656 }
1657
unix_sock_addr(const char * path)1658 SockAddr *unix_sock_addr(const char *path)
1659 {
1660 SockAddr *ret = snew(SockAddr);
1661 int n;
1662
1663 memset(ret, 0, sizeof *ret);
1664 ret->superfamily = UNIX;
1665 n = snprintf(ret->hostname, sizeof ret->hostname, "%s", path);
1666
1667 if (n < 0)
1668 ret->error = "snprintf failed";
1669 else if (n >= sizeof ret->hostname ||
1670 n >= sizeof(((struct sockaddr_un *)0)->sun_path))
1671 ret->error = "socket pathname too long";
1672
1673 #ifndef NO_IPV6
1674 ret->ais = NULL;
1675 #else
1676 ret->addresses = NULL;
1677 ret->naddresses = 0;
1678 #endif
1679 ret->refcount = 1;
1680 return ret;
1681 }
1682
new_unix_listener(SockAddr * listenaddr,Plug * plug)1683 Socket *new_unix_listener(SockAddr *listenaddr, Plug *plug)
1684 {
1685 int s;
1686 union sockaddr_union u;
1687 union sockaddr_union *addr;
1688 int addrlen;
1689 NetSocket *ret;
1690 int retcode;
1691
1692 /*
1693 * Create NetSocket structure.
1694 */
1695 ret = snew(NetSocket);
1696 ret->sock.vt = &NetSocket_sockvt;
1697 ret->error = NULL;
1698 ret->plug = plug;
1699 bufchain_init(&ret->output_data);
1700 ret->writable = false; /* to start with */
1701 ret->sending_oob = 0;
1702 ret->frozen = false;
1703 ret->localhost_only = true;
1704 ret->pending_error = 0;
1705 ret->parent = ret->child = NULL;
1706 ret->oobpending = false;
1707 ret->outgoingeof = EOF_NO;
1708 ret->incomingeof = false;
1709 ret->listener = true;
1710 ret->addr = listenaddr;
1711 ret->s = -1;
1712
1713 assert(listenaddr->superfamily == UNIX);
1714
1715 /*
1716 * Open socket.
1717 */
1718 s = socket(AF_UNIX, SOCK_STREAM, 0);
1719 if (s < 0) {
1720 ret->error = strerror(errno);
1721 return &ret->sock;
1722 }
1723
1724 cloexec(s);
1725
1726 ret->oobinline = false;
1727
1728 memset(&u, '\0', sizeof(u));
1729 u.su.sun_family = AF_UNIX;
1730 #if __GNUC__ >= 8
1731 # pragma GCC diagnostic push
1732 # pragma GCC diagnostic ignored "-Wstringop-truncation"
1733 #endif // __GNUC__ >= 8
1734 strncpy(u.su.sun_path, listenaddr->hostname, sizeof(u.su.sun_path)-1);
1735 #if __GNUC__ >= 8
1736 # pragma GCC diagnostic pop
1737 #endif // __GNUC__ >= 8
1738 addr = &u;
1739 addrlen = sizeof(u.su);
1740
1741 if (unlink(u.su.sun_path) < 0 && errno != ENOENT) {
1742 close(s);
1743 ret->error = strerror(errno);
1744 return &ret->sock;
1745 }
1746
1747 retcode = bind(s, &addr->sa, addrlen);
1748 if (retcode < 0) {
1749 close(s);
1750 ret->error = strerror(errno);
1751 return &ret->sock;
1752 }
1753
1754 if (listen(s, SOMAXCONN) < 0) {
1755 close(s);
1756 ret->error = strerror(errno);
1757 return &ret->sock;
1758 }
1759
1760 ret->s = s;
1761
1762 uxsel_tell(ret);
1763 add234(sktree, ret);
1764
1765 return &ret->sock;
1766 }
1767