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