]> asedeno.scripts.mit.edu Git - PuTTY.git/blob - unix/uxnet.c
Avoid "dereferencing pointer 'sa' does break strict-aliasing rules" warnings
[PuTTY.git] / unix / uxnet.c
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 #include <arpa/inet.h>
15 #include <netinet/in.h>
16 #include <netinet/tcp.h>
17 #include <netdb.h>
18 #include <sys/un.h>
19
20 #define DEFINE_PLUG_METHOD_MACROS
21 #include "putty.h"
22 #include "network.h"
23 #include "tree234.h"
24
25 /* Solaris needs <sys/sockio.h> for SIOCATMARK. */
26 #ifndef SIOCATMARK
27 #include <sys/sockio.h>
28 #endif
29
30 #ifndef X11_UNIX_PATH
31 # define X11_UNIX_PATH "/tmp/.X11-unix/X"
32 #endif
33
34 /* 
35  * Access to sockaddr types without breaking C strict aliasing rules.
36  */
37 union sockaddr_union {
38 #ifdef NO_IPV6
39     struct sockaddr_in storage;
40 #else
41     struct sockaddr_storage storage;
42     struct sockaddr_in6 sin6;
43 #endif
44     struct sockaddr sa;
45     struct sockaddr_in sin;
46 };
47
48 /*
49  * We used to typedef struct Socket_tag *Socket.
50  *
51  * Since we have made the networking abstraction slightly more
52  * abstract, Socket no longer means a tcp socket (it could mean
53  * an ssl socket).  So now we must use Actual_Socket when we know
54  * we are talking about a tcp socket.
55  */
56 typedef struct Socket_tag *Actual_Socket;
57
58 /*
59  * Mutable state that goes with a SockAddr: stores information
60  * about where in the list of candidate IP(v*) addresses we've
61  * currently got to.
62  */
63 typedef struct SockAddrStep_tag SockAddrStep;
64 struct SockAddrStep_tag {
65 #ifndef NO_IPV6
66     struct addrinfo *ai;               /* steps along addr->ais */
67 #endif
68     int curraddr;
69 };
70
71 struct Socket_tag {
72     struct socket_function_table *fn;
73     /* the above variable absolutely *must* be the first in this structure */
74     const char *error;
75     int s;
76     Plug plug;
77     void *private_ptr;
78     bufchain output_data;
79     int connected;                     /* irrelevant for listening sockets */
80     int writable;
81     int frozen; /* this causes readability notifications to be ignored */
82     int frozen_readable; /* this means we missed at least one readability
83                           * notification while we were frozen */
84     int localhost_only;                /* for listening sockets */
85     char oobdata[1];
86     int sending_oob;
87     int oobpending;                    /* is there OOB data available to read? */
88     int oobinline;
89     int pending_error;                 /* in case send() returns error */
90     int listener;
91     int nodelay, keepalive;            /* for connect()-type sockets */
92     int privport, port;                /* and again */
93     SockAddr addr;
94     SockAddrStep step;
95     /*
96      * We sometimes need pairs of Socket structures to be linked:
97      * if we are listening on the same IPv6 and v4 port, for
98      * example. So here we define `parent' and `child' pointers to
99      * track this link.
100      */
101     Actual_Socket parent, child;
102 };
103
104 struct SockAddr_tag {
105     int refcount;
106     const char *error;
107     enum { UNRESOLVED, UNIX, IP } superfamily;
108 #ifndef NO_IPV6
109     struct addrinfo *ais;              /* Addresses IPv6 style. */
110 #else
111     unsigned long *addresses;          /* Addresses IPv4 style. */
112     int naddresses;
113 #endif
114     char hostname[512];                /* Store an unresolved host name. */
115 };
116
117 /*
118  * Which address family this address belongs to. AF_INET for IPv4;
119  * AF_INET6 for IPv6; AF_UNSPEC indicates that name resolution has
120  * not been done and a simple host name is held in this SockAddr
121  * structure.
122  */
123 #ifndef NO_IPV6
124 #define SOCKADDR_FAMILY(addr, step) \
125     ((addr)->superfamily == UNRESOLVED ? AF_UNSPEC : \
126      (addr)->superfamily == UNIX ? AF_UNIX : \
127      (step).ai ? (step).ai->ai_family : AF_INET)
128 #else
129 #define SOCKADDR_FAMILY(addr, step) \
130     ((addr)->superfamily == UNRESOLVED ? AF_UNSPEC : \
131      (addr)->superfamily == UNIX ? AF_UNIX : 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(Actual_Socket s);
149
150 static int cmpfortree(void *av, void *bv)
151 {
152     Actual_Socket a = (Actual_Socket) av, b = (Actual_Socket) 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
165 static int cmpforsearch(void *av, void *bv)
166 {
167     Actual_Socket b = (Actual_Socket) 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
176 void sk_init(void)
177 {
178     sktree = newtree234(cmpfortree);
179 }
180
181 void sk_cleanup(void)
182 {
183     Actual_Socket 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
193 SockAddr sk_namelookup(const char *host, char **canonicalname, int address_family)
194 {
195     SockAddr ret = snew(struct SockAddr_tag);
196 #ifndef NO_IPV6
197     struct addrinfo hints;
198     int err;
199 #else
200     unsigned long a;
201     struct hostent *h = NULL;
202     int n;
203 #endif
204     char realhost[8192];
205
206     /* Clear the structure and default to IPv4. */
207     memset(ret, 0, sizeof(struct SockAddr_tag));
208     ret->superfamily = UNRESOLVED;
209     *realhost = '\0';
210     ret->error = NULL;
211     ret->refcount = 1;
212
213 #ifndef NO_IPV6
214     hints.ai_flags = AI_CANONNAME;
215     hints.ai_family = (address_family == ADDRTYPE_IPV4 ? AF_INET :
216                        address_family == ADDRTYPE_IPV6 ? AF_INET6 :
217                        AF_UNSPEC);
218     hints.ai_socktype = SOCK_STREAM;
219     hints.ai_protocol = 0;
220     hints.ai_addrlen = 0;
221     hints.ai_addr = NULL;
222     hints.ai_canonname = NULL;
223     hints.ai_next = NULL;
224     err = getaddrinfo(host, NULL, &hints, &ret->ais);
225     if (err != 0) {
226         ret->error = gai_strerror(err);
227         return ret;
228     }
229     ret->superfamily = IP;
230     *realhost = '\0';
231     if (ret->ais->ai_canonname != NULL)
232         strncat(realhost, ret->ais->ai_canonname, sizeof(realhost) - 1);
233     else
234         strncat(realhost, host, sizeof(realhost) - 1);
235 #else
236     if ((a = inet_addr(host)) == (unsigned long)(in_addr_t)(-1)) {
237         /*
238          * Otherwise use the IPv4-only gethostbyname... (NOTE:
239          * we don't use gethostbyname as a fallback!)
240          */
241         if (ret->superfamily == UNRESOLVED) {
242             /*debug(("Resolving \"%s\" with gethostbyname() (IPv4 only)...\n", host)); */
243             if ( (h = gethostbyname(host)) )
244                 ret->superfamily = IP;
245         }
246         if (ret->superfamily == UNRESOLVED) {
247             ret->error = (h_errno == HOST_NOT_FOUND ||
248                           h_errno == NO_DATA ||
249                           h_errno == NO_ADDRESS ? "Host does not exist" :
250                           h_errno == TRY_AGAIN ?
251                           "Temporary name service failure" :
252                           "gethostbyname: unknown error");
253             return ret;
254         }
255         /* This way we are always sure the h->h_name is valid :) */
256         strncpy(realhost, h->h_name, sizeof(realhost));
257         for (n = 0; h->h_addr_list[n]; n++);
258         ret->addresses = snewn(n, unsigned long);
259         ret->naddresses = n;
260         for (n = 0; n < ret->naddresses; n++) {
261             memcpy(&a, h->h_addr_list[n], sizeof(a));
262             ret->addresses[n] = ntohl(a);
263         }
264     } else {
265         /*
266          * This must be a numeric IPv4 address because it caused a
267          * success return from inet_addr.
268          */
269         ret->superfamily = IP;
270         strncpy(realhost, host, sizeof(realhost));
271         ret->addresses = snew(unsigned long);
272         ret->naddresses = 1;
273         ret->addresses[0] = ntohl(a);
274     }
275 #endif
276     realhost[lenof(realhost)-1] = '\0';
277     *canonicalname = snewn(1+strlen(realhost), char);
278     strcpy(*canonicalname, realhost);
279     return ret;
280 }
281
282 SockAddr sk_nonamelookup(const char *host)
283 {
284     SockAddr ret = snew(struct SockAddr_tag);
285     ret->error = NULL;
286     ret->superfamily = UNRESOLVED;
287     strncpy(ret->hostname, host, lenof(ret->hostname));
288     ret->hostname[lenof(ret->hostname)-1] = '\0';
289 #ifndef NO_IPV6
290     ret->ais = NULL;
291 #else
292     ret->addresses = NULL;
293 #endif
294     ret->refcount = 1;
295     return ret;
296 }
297
298 static int sk_nextaddr(SockAddr addr, SockAddrStep *step)
299 {
300 #ifndef NO_IPV6
301     if (step->ai && step->ai->ai_next) {
302         step->ai = step->ai->ai_next;
303         return TRUE;
304     } else
305         return FALSE;
306 #else
307     if (step->curraddr+1 < addr->naddresses) {
308         step->curraddr++;
309         return TRUE;
310     } else {
311         return FALSE;
312     }
313 #endif    
314 }
315
316 void sk_getaddr(SockAddr addr, char *buf, int buflen)
317 {
318     /* XXX not clear what we should return for Unix-domain sockets; let's
319      * hope the question never arises */
320     assert(addr->superfamily != UNIX);
321     if (addr->superfamily == UNRESOLVED) {
322         strncpy(buf, addr->hostname, buflen);
323         buf[buflen-1] = '\0';
324     } else {
325 #ifndef NO_IPV6
326         if (getnameinfo(addr->ais->ai_addr, addr->ais->ai_addrlen, buf, buflen,
327                         NULL, 0, NI_NUMERICHOST) != 0) {
328             buf[0] = '\0';
329             strncat(buf, "<unknown>", buflen - 1);
330         }
331 #else
332         struct in_addr a;
333         SockAddrStep step;
334         START_STEP(addr, step);
335         assert(SOCKADDR_FAMILY(addr, step) == AF_INET);
336         a.s_addr = htonl(addr->addresses[0]);
337         strncpy(buf, inet_ntoa(a), buflen);
338         buf[buflen-1] = '\0';
339 #endif
340     }
341 }
342
343 int sk_hostname_is_local(char *name)
344 {
345     return !strcmp(name, "localhost") ||
346            !strcmp(name, "::1") ||
347            !strncmp(name, "127.", 4);
348 }
349
350 #define ipv4_is_loopback(addr) \
351     (((addr).s_addr & htonl(0xff000000)) == htonl(0x7f000000))
352
353 static int sockaddr_is_loopback(struct sockaddr *sa)
354 {
355     union sockaddr_union *u = (union sockaddr_union *)sa;
356     switch (u->sa.sa_family) {
357       case AF_INET:
358         return ipv4_is_loopback(u->sin.sin_addr);
359 #ifndef NO_IPV6
360       case AF_INET6:
361         return IN6_IS_ADDR_LOOPBACK(&u->sin6.sin6_addr);
362 #endif
363       case AF_UNIX:
364         return TRUE;
365       default:
366         return FALSE;
367     }
368 }
369
370 int sk_address_is_local(SockAddr addr)
371 {
372     if (addr->superfamily == UNRESOLVED)
373         return 0;                      /* we don't know; assume not */
374     else if (addr->superfamily == UNIX)
375         return 1;
376     else {
377 #ifndef NO_IPV6
378         return sockaddr_is_loopback(addr->ais->ai_addr);
379 #else
380         struct in_addr a;
381         SockAddrStep step;
382         START_STEP(addr, step);
383         assert(SOCKADDR_FAMILY(addr, step) == AF_INET);
384         a.s_addr = htonl(addr->addresses[0]);
385         return ipv4_is_loopback(a);
386 #endif
387     }
388 }
389
390 int sk_addrtype(SockAddr addr)
391 {
392     SockAddrStep step;
393     int family;
394     START_STEP(addr, step);
395     family = SOCKADDR_FAMILY(addr, step);
396
397     return (family == AF_INET ? ADDRTYPE_IPV4 :
398 #ifndef NO_IPV6
399             family == AF_INET6 ? ADDRTYPE_IPV6 :
400 #endif
401             ADDRTYPE_NAME);
402 }
403
404 void sk_addrcopy(SockAddr addr, char *buf)
405 {
406     SockAddrStep step;
407     int family;
408     START_STEP(addr, step);
409     family = SOCKADDR_FAMILY(addr, step);
410
411 #ifndef NO_IPV6
412     if (family == AF_INET)
413         memcpy(buf, &((struct sockaddr_in *)step.ai->ai_addr)->sin_addr,
414                sizeof(struct in_addr));
415     else if (family == AF_INET6)
416         memcpy(buf, &((struct sockaddr_in6 *)step.ai->ai_addr)->sin6_addr,
417                sizeof(struct in6_addr));
418     else
419         assert(FALSE);
420 #else
421     struct in_addr a;
422
423     assert(family == AF_INET);
424     a.s_addr = htonl(addr->addresses[step.curraddr]);
425     memcpy(buf, (char*) &a.s_addr, 4);
426 #endif
427 }
428
429 void sk_addr_free(SockAddr addr)
430 {
431     if (--addr->refcount > 0)
432         return;
433 #ifndef NO_IPV6
434     if (addr->ais != NULL)
435         freeaddrinfo(addr->ais);
436 #else
437     sfree(addr->addresses);
438 #endif
439     sfree(addr);
440 }
441
442 SockAddr sk_addr_dup(SockAddr addr)
443 {
444     addr->refcount++;
445     return addr;
446 }
447
448 static Plug sk_tcp_plug(Socket sock, Plug p)
449 {
450     Actual_Socket s = (Actual_Socket) sock;
451     Plug ret = s->plug;
452     if (p)
453         s->plug = p;
454     return ret;
455 }
456
457 static void sk_tcp_flush(Socket s)
458 {
459     /*
460      * We send data to the socket as soon as we can anyway,
461      * so we don't need to do anything here.  :-)
462      */
463 }
464
465 static void sk_tcp_close(Socket s);
466 static int sk_tcp_write(Socket s, const char *data, int len);
467 static int sk_tcp_write_oob(Socket s, const char *data, int len);
468 static void sk_tcp_set_private_ptr(Socket s, void *ptr);
469 static void *sk_tcp_get_private_ptr(Socket s);
470 static void sk_tcp_set_frozen(Socket s, int is_frozen);
471 static const char *sk_tcp_socket_error(Socket s);
472
473 static struct socket_function_table tcp_fn_table = {
474     sk_tcp_plug,
475     sk_tcp_close,
476     sk_tcp_write,
477     sk_tcp_write_oob,
478     sk_tcp_flush,
479     sk_tcp_set_private_ptr,
480     sk_tcp_get_private_ptr,
481     sk_tcp_set_frozen,
482     sk_tcp_socket_error
483 };
484
485 Socket sk_register(OSSocket sockfd, Plug plug)
486 {
487     Actual_Socket ret;
488
489     /*
490      * Create Socket structure.
491      */
492     ret = snew(struct Socket_tag);
493     ret->fn = &tcp_fn_table;
494     ret->error = NULL;
495     ret->plug = plug;
496     bufchain_init(&ret->output_data);
497     ret->writable = 1;                 /* to start with */
498     ret->sending_oob = 0;
499     ret->frozen = 1;
500     ret->frozen_readable = 0;
501     ret->localhost_only = 0;           /* unused, but best init anyway */
502     ret->pending_error = 0;
503     ret->oobpending = FALSE;
504     ret->listener = 0;
505     ret->parent = ret->child = NULL;
506     ret->addr = NULL;
507     ret->connected = 1;
508
509     ret->s = sockfd;
510
511     if (ret->s < 0) {
512         ret->error = strerror(errno);
513         return (Socket) ret;
514     }
515
516     ret->oobinline = 0;
517
518     uxsel_tell(ret);
519     add234(sktree, ret);
520
521     return (Socket) ret;
522 }
523
524 static int try_connect(Actual_Socket sock)
525 {
526     int s;
527 #ifndef NO_IPV6
528     struct sockaddr_in6 a6;
529 #endif
530     struct sockaddr_in a;
531     struct sockaddr_un au;
532     const struct sockaddr *sa;
533     int err = 0;
534     short localport;
535     int fl, salen, family;
536
537     /*
538      * Remove the socket from the tree before we overwrite its
539      * internal socket id, because that forms part of the tree's
540      * sorting criterion. We'll add it back before exiting this
541      * function, whether we changed anything or not.
542      */
543     del234(sktree, sock);
544
545     if (sock->s >= 0)
546         close(sock->s);
547
548     plug_log(sock->plug, 0, sock->addr, sock->port, NULL, 0);
549
550     /*
551      * Open socket.
552      */
553     family = SOCKADDR_FAMILY(sock->addr, sock->step);
554     assert(family != AF_UNSPEC);
555     s = socket(family, SOCK_STREAM, 0);
556     sock->s = s;
557
558     if (s < 0) {
559         err = errno;
560         goto ret;
561     }
562
563     cloexec(s);
564
565     if (sock->oobinline) {
566         int b = TRUE;
567         setsockopt(s, SOL_SOCKET, SO_OOBINLINE, (void *) &b, sizeof(b));
568     }
569
570     if (sock->nodelay) {
571         int b = TRUE;
572         setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (void *) &b, sizeof(b));
573     }
574
575     if (sock->keepalive) {
576         int b = TRUE;
577         setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (void *) &b, sizeof(b));
578     }
579
580     /*
581      * Bind to local address.
582      */
583     if (sock->privport)
584         localport = 1023;              /* count from 1023 downwards */
585     else
586         localport = 0;                 /* just use port 0 (ie kernel picks) */
587
588     /* BSD IP stacks need sockaddr_in zeroed before filling in */
589     memset(&a,'\0',sizeof(struct sockaddr_in));
590 #ifndef NO_IPV6
591     memset(&a6,'\0',sizeof(struct sockaddr_in6));
592 #endif
593
594     /* We don't try to bind to a local address for UNIX domain sockets.  (Why
595      * do we bother doing the bind when localport == 0 anyway?) */
596     if (family != AF_UNIX) {
597         /* Loop round trying to bind */
598         while (1) {
599             int retcode;
600
601 #ifndef NO_IPV6
602             if (family == AF_INET6) {
603                 /* XXX use getaddrinfo to get a local address? */
604                 a6.sin6_family = AF_INET6;
605                 a6.sin6_addr = in6addr_any;
606                 a6.sin6_port = htons(localport);
607                 retcode = bind(s, (struct sockaddr *) &a6, sizeof(a6));
608             } else
609 #endif
610             {
611                 assert(family == AF_INET);
612                 a.sin_family = AF_INET;
613                 a.sin_addr.s_addr = htonl(INADDR_ANY);
614                 a.sin_port = htons(localport);
615                 retcode = bind(s, (struct sockaddr *) &a, sizeof(a));
616             }
617             if (retcode >= 0) {
618                 err = 0;
619                 break;                 /* done */
620             } else {
621                 err = errno;
622                 if (err != EADDRINUSE) /* failed, for a bad reason */
623                   break;
624             }
625             
626             if (localport == 0)
627               break;                   /* we're only looping once */
628             localport--;
629             if (localport == 0)
630               break;                   /* we might have got to the end */
631         }
632         
633         if (err)
634             goto ret;
635     }
636
637     /*
638      * Connect to remote address.
639      */
640     switch(family) {
641 #ifndef NO_IPV6
642       case AF_INET:
643         /* XXX would be better to have got getaddrinfo() to fill in the port. */
644         ((struct sockaddr_in *)sock->step.ai->ai_addr)->sin_port =
645             htons(sock->port);
646         sa = (const struct sockaddr *)sock->step.ai->ai_addr;
647         salen = sock->step.ai->ai_addrlen;
648         break;
649       case AF_INET6:
650         ((struct sockaddr_in *)sock->step.ai->ai_addr)->sin_port =
651             htons(sock->port);
652         sa = (const struct sockaddr *)sock->step.ai->ai_addr;
653         salen = sock->step.ai->ai_addrlen;
654         break;
655 #else
656       case AF_INET:
657         a.sin_family = AF_INET;
658         a.sin_addr.s_addr = htonl(sock->addr->addresses[sock->step.curraddr]);
659         a.sin_port = htons((short) sock->port);
660         sa = (const struct sockaddr *)&a;
661         salen = sizeof a;
662         break;
663 #endif
664       case AF_UNIX:
665         assert(sock->port == 0);       /* to catch confused people */
666         assert(strlen(sock->addr->hostname) < sizeof au.sun_path);
667         memset(&au, 0, sizeof au);
668         au.sun_family = AF_UNIX;
669         strcpy(au.sun_path, sock->addr->hostname);
670         sa = (const struct sockaddr *)&au;
671         salen = sizeof au;
672         break;
673
674       default:
675         assert(0 && "unknown address family");
676         exit(1); /* XXX: GCC doesn't understand assert() on some systems. */
677     }
678
679     fl = fcntl(s, F_GETFL);
680     if (fl != -1)
681         fcntl(s, F_SETFL, fl | O_NONBLOCK);
682
683     if ((connect(s, sa, salen)) < 0) {
684         if ( errno != EINPROGRESS ) {
685             err = errno;
686             goto ret;
687         }
688     } else {
689         /*
690          * If we _don't_ get EWOULDBLOCK, the connect has completed
691          * and we should set the socket as connected and writable.
692          */
693         sock->connected = 1;
694         sock->writable = 1;
695     }
696
697     uxsel_tell(sock);
698
699     ret:
700
701     /*
702      * No matter what happened, put the socket back in the tree.
703      */
704     add234(sktree, sock);
705
706     if (err)
707         plug_log(sock->plug, 1, sock->addr, sock->port, strerror(err), err);
708     return err;
709 }
710
711 Socket sk_new(SockAddr addr, int port, int privport, int oobinline,
712               int nodelay, int keepalive, Plug plug)
713 {
714     Actual_Socket ret;
715     int err;
716
717     /*
718      * Create Socket structure.
719      */
720     ret = snew(struct Socket_tag);
721     ret->fn = &tcp_fn_table;
722     ret->error = NULL;
723     ret->plug = plug;
724     bufchain_init(&ret->output_data);
725     ret->connected = 0;                /* to start with */
726     ret->writable = 0;                 /* to start with */
727     ret->sending_oob = 0;
728     ret->frozen = 0;
729     ret->frozen_readable = 0;
730     ret->localhost_only = 0;           /* unused, but best init anyway */
731     ret->pending_error = 0;
732     ret->parent = ret->child = NULL;
733     ret->oobpending = FALSE;
734     ret->listener = 0;
735     ret->addr = addr;
736     START_STEP(ret->addr, ret->step);
737     ret->s = -1;
738     ret->oobinline = oobinline;
739     ret->nodelay = nodelay;
740     ret->keepalive = keepalive;
741     ret->privport = privport;
742     ret->port = port;
743
744     err = 0;
745     do {
746         err = try_connect(ret);
747     } while (err && sk_nextaddr(ret->addr, &ret->step));
748
749     if (err)
750         ret->error = strerror(err);
751
752     return (Socket) ret;
753 }
754
755 Socket sk_newlistener(char *srcaddr, int port, Plug plug, int local_host_only, int orig_address_family)
756 {
757     int s;
758 #ifndef NO_IPV6
759     struct addrinfo hints, *ai;
760     char portstr[6];
761     struct sockaddr_in6 a6;
762 #endif
763     struct sockaddr *addr;
764     int addrlen;
765     struct sockaddr_in a;
766     Actual_Socket ret;
767     int retcode;
768     int address_family;
769     int on = 1;
770
771     /*
772      * Create Socket structure.
773      */
774     ret = snew(struct Socket_tag);
775     ret->fn = &tcp_fn_table;
776     ret->error = NULL;
777     ret->plug = plug;
778     bufchain_init(&ret->output_data);
779     ret->writable = 0;                 /* to start with */
780     ret->sending_oob = 0;
781     ret->frozen = 0;
782     ret->frozen_readable = 0;
783     ret->localhost_only = local_host_only;
784     ret->pending_error = 0;
785     ret->parent = ret->child = NULL;
786     ret->oobpending = FALSE;
787     ret->listener = 1;
788     ret->addr = NULL;
789
790     /*
791      * Translate address_family from platform-independent constants
792      * into local reality.
793      */
794     address_family = (orig_address_family == ADDRTYPE_IPV4 ? AF_INET :
795 #ifndef NO_IPV6
796                       orig_address_family == ADDRTYPE_IPV6 ? AF_INET6 :
797 #endif
798                       AF_UNSPEC);
799
800 #ifndef NO_IPV6
801     /* Let's default to IPv6.
802      * If the stack doesn't support IPv6, we will fall back to IPv4. */
803     if (address_family == AF_UNSPEC) address_family = AF_INET6;
804 #else
805     /* No other choice, default to IPv4 */
806     if (address_family == AF_UNSPEC)  address_family = AF_INET;
807 #endif
808
809     /*
810      * Open socket.
811      */
812     s = socket(address_family, SOCK_STREAM, 0);
813
814 #ifndef NO_IPV6
815     /* If the host doesn't support IPv6 try fallback to IPv4. */
816     if (s < 0 && address_family == AF_INET6) {
817         address_family = AF_INET;
818         s = socket(address_family, SOCK_STREAM, 0);
819     }
820 #endif
821
822     if (s < 0) {
823         ret->error = strerror(errno);
824         return (Socket) ret;
825     }
826
827     cloexec(s);
828
829     ret->oobinline = 0;
830
831     setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const char *)&on, sizeof(on));
832
833     retcode = -1;
834     addr = NULL; addrlen = -1;         /* placate optimiser */
835
836     if (srcaddr != NULL) {
837 #ifndef NO_IPV6
838         hints.ai_flags = AI_NUMERICHOST;
839         hints.ai_family = address_family;
840         hints.ai_socktype = SOCK_STREAM;
841         hints.ai_protocol = 0;
842         hints.ai_addrlen = 0;
843         hints.ai_addr = NULL;
844         hints.ai_canonname = NULL;
845         hints.ai_next = NULL;
846         assert(port >= 0 && port <= 99999);
847         sprintf(portstr, "%d", port);
848         retcode = getaddrinfo(srcaddr, portstr, &hints, &ai);
849         if (retcode == 0) {
850             addr = ai->ai_addr;
851             addrlen = ai->ai_addrlen;
852         }
853 #else
854         memset(&a,'\0',sizeof(struct sockaddr_in));
855         a.sin_family = AF_INET;
856         a.sin_port = htons(port);
857         a.sin_addr.s_addr = inet_addr(srcaddr);
858         if (a.sin_addr.s_addr != (in_addr_t)(-1)) {
859             /* Override localhost_only with specified listen addr. */
860             ret->localhost_only = ipv4_is_loopback(a.sin_addr);
861         }
862         addr = (struct sockaddr *)&a;
863         addrlen = sizeof(a);
864         retcode = 0;
865 #endif
866     }
867
868     if (retcode != 0) {
869 #ifndef NO_IPV6
870         if (address_family == AF_INET6) {
871             memset(&a6,'\0',sizeof(struct sockaddr_in6));
872             a6.sin6_family = AF_INET6;
873             a6.sin6_port = htons(port);
874             if (local_host_only)
875                 a6.sin6_addr = in6addr_loopback;
876             else
877                 a6.sin6_addr = in6addr_any;
878             addr = (struct sockaddr *)&a6;
879             addrlen = sizeof(a6);
880         } else
881 #endif
882         {
883             memset(&a,'\0',sizeof(struct sockaddr_in));
884             a.sin_family = AF_INET;
885             a.sin_port = htons(port);
886             if (local_host_only)
887                 a.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
888             else
889                 a.sin_addr.s_addr = htonl(INADDR_ANY);
890             addr = (struct sockaddr *)&a;
891             addrlen = sizeof(a);
892         }
893     }
894
895     retcode = bind(s, addr, addrlen);
896     if (retcode < 0) {
897         close(s);
898         ret->error = strerror(errno);
899         return (Socket) ret;
900     }
901
902     if (listen(s, SOMAXCONN) < 0) {
903         close(s);
904         ret->error = strerror(errno);
905         return (Socket) ret;
906     }
907
908 #ifndef NO_IPV6
909     /*
910      * If we were given ADDRTYPE_UNSPEC, we must also create an
911      * IPv4 listening socket and link it to this one.
912      */
913     if (address_family == AF_INET6 && orig_address_family == ADDRTYPE_UNSPEC) {
914         Actual_Socket other;
915
916         other = (Actual_Socket) sk_newlistener(srcaddr, port, plug,
917                                                local_host_only, ADDRTYPE_IPV4);
918
919         if (other) {
920             if (!other->error) {
921                 other->parent = ret;
922                 ret->child = other;
923             } else {
924                 /* If we couldn't create a listening socket on IPv4 as well
925                  * as IPv6, we must return an error overall. */
926                 close(s);
927                 sfree(ret);
928                 return (Socket) other;
929             }
930         }
931     }
932 #endif
933
934     ret->s = s;
935
936     uxsel_tell(ret);
937     add234(sktree, ret);
938
939     return (Socket) ret;
940 }
941
942 static void sk_tcp_close(Socket sock)
943 {
944     Actual_Socket s = (Actual_Socket) sock;
945
946     if (s->child)
947         sk_tcp_close((Socket)s->child);
948
949     uxsel_del(s->s);
950     del234(sktree, s);
951     close(s->s);
952     if (s->addr)
953         sk_addr_free(s->addr);
954     sfree(s);
955 }
956
957 void *sk_getxdmdata(void *sock, int *lenp)
958 {
959     Actual_Socket s = (Actual_Socket) sock;
960     union sockaddr_union u;
961     socklen_t addrlen;
962     char *buf;
963     static unsigned int unix_addr = 0xFFFFFFFF;
964
965     /*
966      * We must check that this socket really _is_ an Actual_Socket.
967      */
968     if (s->fn != &tcp_fn_table)
969         return NULL;                   /* failure */
970
971     addrlen = sizeof(u);
972     if (getsockname(s->s, &u.sa, &addrlen) < 0)
973         return NULL;
974     switch(u.sa.sa_family) {
975       case AF_INET:
976         *lenp = 6;
977         buf = snewn(*lenp, char);
978         PUT_32BIT_MSB_FIRST(buf, ntohl(u.sin.sin_addr.s_addr));
979         PUT_16BIT_MSB_FIRST(buf+4, ntohs(u.sin.sin_port));
980         break;
981 #ifndef NO_IPV6
982     case AF_INET6:
983         *lenp = 6;
984         buf = snewn(*lenp, char);
985         if (IN6_IS_ADDR_V4MAPPED(&u.sin6.sin6_addr)) {
986             memcpy(buf, u.sin6.sin6_addr.s6_addr + 12, 4);
987             PUT_16BIT_MSB_FIRST(buf+4, ntohs(u.sin6.sin6_port));
988         } else
989             /* This is stupid, but it's what XLib does. */
990             memset(buf, 0, 6);
991         break;
992 #endif
993       case AF_UNIX:
994         *lenp = 6;
995         buf = snewn(*lenp, char);
996         PUT_32BIT_MSB_FIRST(buf, unix_addr--);
997         PUT_16BIT_MSB_FIRST(buf+4, getpid());
998         break;
999
1000         /* XXX IPV6 */
1001
1002       default:
1003         return NULL;
1004     }
1005
1006     return buf;
1007 }
1008
1009 /*
1010  * The function which tries to send on a socket once it's deemed
1011  * writable.
1012  */
1013 void try_send(Actual_Socket s)
1014 {
1015     while (s->sending_oob || bufchain_size(&s->output_data) > 0) {
1016         int nsent;
1017         int err;
1018         void *data;
1019         int len, urgentflag;
1020
1021         if (s->sending_oob) {
1022             urgentflag = MSG_OOB;
1023             len = s->sending_oob;
1024             data = &s->oobdata;
1025         } else {
1026             urgentflag = 0;
1027             bufchain_prefix(&s->output_data, &data, &len);
1028         }
1029         nsent = send(s->s, data, len, urgentflag);
1030         noise_ultralight(nsent);
1031         if (nsent <= 0) {
1032             err = (nsent < 0 ? errno : 0);
1033             if (err == EWOULDBLOCK) {
1034                 /*
1035                  * Perfectly normal: we've sent all we can for the moment.
1036                  */
1037                 s->writable = FALSE;
1038                 return;
1039             } else {
1040                 /*
1041                  * We unfortunately can't just call plug_closing(),
1042                  * because it's quite likely that we're currently
1043                  * _in_ a call from the code we'd be calling back
1044                  * to, so we'd have to make half the SSH code
1045                  * reentrant. Instead we flag a pending error on
1046                  * the socket, to be dealt with (by calling
1047                  * plug_closing()) at some suitable future moment.
1048                  */
1049                 s->pending_error = err;
1050                 return;
1051             }
1052         } else {
1053             if (s->sending_oob) {
1054                 if (nsent < len) {
1055                     memmove(s->oobdata, s->oobdata+nsent, len-nsent);
1056                     s->sending_oob = len - nsent;
1057                 } else {
1058                     s->sending_oob = 0;
1059                 }
1060             } else {
1061                 bufchain_consume(&s->output_data, nsent);
1062             }
1063         }
1064     }
1065     uxsel_tell(s);
1066 }
1067
1068 static int sk_tcp_write(Socket sock, const char *buf, int len)
1069 {
1070     Actual_Socket s = (Actual_Socket) sock;
1071
1072     /*
1073      * Add the data to the buffer list on the socket.
1074      */
1075     bufchain_add(&s->output_data, buf, len);
1076
1077     /*
1078      * Now try sending from the start of the buffer list.
1079      */
1080     if (s->writable)
1081         try_send(s);
1082
1083     /*
1084      * Update the select() status to correctly reflect whether or
1085      * not we should be selecting for write.
1086      */
1087     uxsel_tell(s);
1088
1089     return bufchain_size(&s->output_data);
1090 }
1091
1092 static int sk_tcp_write_oob(Socket sock, const char *buf, int len)
1093 {
1094     Actual_Socket s = (Actual_Socket) sock;
1095
1096     /*
1097      * Replace the buffer list on the socket with the data.
1098      */
1099     bufchain_clear(&s->output_data);
1100     assert(len <= sizeof(s->oobdata));
1101     memcpy(s->oobdata, buf, len);
1102     s->sending_oob = len;
1103
1104     /*
1105      * Now try sending from the start of the buffer list.
1106      */
1107     if (s->writable)
1108         try_send(s);
1109
1110     /*
1111      * Update the select() status to correctly reflect whether or
1112      * not we should be selecting for write.
1113      */
1114     uxsel_tell(s);
1115
1116     return s->sending_oob;
1117 }
1118
1119 static int net_select_result(int fd, int event)
1120 {
1121     int ret;
1122     char buf[20480];                   /* nice big buffer for plenty of speed */
1123     Actual_Socket s;
1124     u_long atmark;
1125
1126     /* Find the Socket structure */
1127     s = find234(sktree, &fd, cmpforsearch);
1128     if (!s)
1129         return 1;                      /* boggle */
1130
1131     noise_ultralight(event);
1132
1133     switch (event) {
1134       case 4:                          /* exceptional */
1135         if (!s->oobinline) {
1136             /*
1137              * On a non-oobinline socket, this indicates that we
1138              * can immediately perform an OOB read and get back OOB
1139              * data, which we will send to the back end with
1140              * type==2 (urgent data).
1141              */
1142             ret = recv(s->s, buf, sizeof(buf), MSG_OOB);
1143             noise_ultralight(ret);
1144             if (ret <= 0) {
1145                 return plug_closing(s->plug,
1146                                     ret == 0 ? "Internal networking trouble" :
1147                                     strerror(errno), errno, 0);
1148             } else {
1149                 /*
1150                  * Receiving actual data on a socket means we can
1151                  * stop falling back through the candidate
1152                  * addresses to connect to.
1153                  */
1154                 if (s->addr) {
1155                     sk_addr_free(s->addr);
1156                     s->addr = NULL;
1157                 }
1158                 return plug_receive(s->plug, 2, buf, ret);
1159             }
1160             break;
1161         }
1162
1163         /*
1164          * If we reach here, this is an oobinline socket, which
1165          * means we should set s->oobpending and then deal with it
1166          * when we get called for the readability event (which
1167          * should also occur).
1168          */
1169         s->oobpending = TRUE;
1170         break;
1171       case 1:                          /* readable; also acceptance */
1172         if (s->listener) {
1173             /*
1174              * On a listening socket, the readability event means a
1175              * connection is ready to be accepted.
1176              */
1177 #ifdef NO_IPV6
1178             struct sockaddr_in ss;
1179 #else
1180             struct sockaddr_storage ss;
1181 #endif
1182             socklen_t addrlen = sizeof(ss);
1183             int t;  /* socket of connection */
1184             int fl;
1185
1186             memset(&ss, 0, addrlen);
1187             t = accept(s->s, (struct sockaddr *)&ss, &addrlen);
1188             if (t < 0) {
1189                 break;
1190             }
1191
1192             fl = fcntl(t, F_GETFL);
1193             if (fl != -1)
1194                 fcntl(t, F_SETFL, fl | O_NONBLOCK);
1195
1196             if (s->localhost_only &&
1197                 !sockaddr_is_loopback((struct sockaddr *)&ss)) {
1198                 close(t);              /* someone let nonlocal through?! */
1199             } else if (plug_accepting(s->plug, t)) {
1200                 close(t);              /* denied or error */
1201             }
1202             break;
1203         }
1204
1205         /*
1206          * If we reach here, this is not a listening socket, so
1207          * readability really means readability.
1208          */
1209
1210         /* In the case the socket is still frozen, we don't even bother */
1211         if (s->frozen) {
1212             s->frozen_readable = 1;
1213             break;
1214         }
1215
1216         /*
1217          * We have received data on the socket. For an oobinline
1218          * socket, this might be data _before_ an urgent pointer,
1219          * in which case we send it to the back end with type==1
1220          * (data prior to urgent).
1221          */
1222         if (s->oobinline && s->oobpending) {
1223             atmark = 1;
1224             if (ioctl(s->s, SIOCATMARK, &atmark) == 0 && atmark)
1225                 s->oobpending = FALSE; /* clear this indicator */
1226         } else
1227             atmark = 1;
1228
1229         ret = recv(s->s, buf, s->oobpending ? 1 : sizeof(buf), 0);
1230         noise_ultralight(ret);
1231         if (ret < 0) {
1232             if (errno == EWOULDBLOCK) {
1233                 break;
1234             }
1235         }
1236         if (ret < 0) {
1237             /*
1238              * An error at this point _might_ be an error reported
1239              * by a non-blocking connect(). So before we return a
1240              * panic status to the user, let's just see whether
1241              * that's the case.
1242              */
1243             int err = errno;
1244             if (s->addr) {
1245                 plug_log(s->plug, 1, s->addr, s->port, strerror(err), err);
1246                 while (s->addr && sk_nextaddr(s->addr, &s->step)) {
1247                     err = try_connect(s);
1248                 }
1249             }
1250             if (err != 0)
1251                 return plug_closing(s->plug, strerror(err), err, 0);
1252         } else if (0 == ret) {
1253             return plug_closing(s->plug, NULL, 0, 0);
1254         } else {
1255             /*
1256              * Receiving actual data on a socket means we can
1257              * stop falling back through the candidate
1258              * addresses to connect to.
1259              */
1260             if (s->addr) {
1261                 sk_addr_free(s->addr);
1262                 s->addr = NULL;
1263             }
1264             return plug_receive(s->plug, atmark ? 0 : 1, buf, ret);
1265         }
1266         break;
1267       case 2:                          /* writable */
1268         if (!s->connected) {
1269             /*
1270              * select() reports a socket as _writable_ when an
1271              * asynchronous connection is completed.
1272              */
1273             s->connected = s->writable = 1;
1274             uxsel_tell(s);
1275             break;
1276         } else {
1277             int bufsize_before, bufsize_after;
1278             s->writable = 1;
1279             bufsize_before = s->sending_oob + bufchain_size(&s->output_data);
1280             try_send(s);
1281             bufsize_after = s->sending_oob + bufchain_size(&s->output_data);
1282             if (bufsize_after < bufsize_before)
1283                 plug_sent(s->plug, bufsize_after);
1284         }
1285         break;
1286     }
1287
1288     return 1;
1289 }
1290
1291 /*
1292  * Deal with socket errors detected in try_send().
1293  */
1294 void net_pending_errors(void)
1295 {
1296     int i;
1297     Actual_Socket s;
1298
1299     /*
1300      * This might be a fiddly business, because it's just possible
1301      * that handling a pending error on one socket might cause
1302      * others to be closed. (I can't think of any reason this might
1303      * happen in current SSH implementation, but to maintain
1304      * generality of this network layer I'll assume the worst.)
1305      * 
1306      * So what we'll do is search the socket list for _one_ socket
1307      * with a pending error, and then handle it, and then search
1308      * the list again _from the beginning_. Repeat until we make a
1309      * pass with no socket errors present. That way we are
1310      * protected against the socket list changing under our feet.
1311      */
1312
1313     do {
1314         for (i = 0; (s = index234(sktree, i)) != NULL; i++) {
1315             if (s->pending_error) {
1316                 /*
1317                  * An error has occurred on this socket. Pass it to the
1318                  * plug.
1319                  */
1320                 plug_closing(s->plug, strerror(s->pending_error),
1321                              s->pending_error, 0);
1322                 break;
1323             }
1324         }
1325     } while (s);
1326 }
1327
1328 /*
1329  * Each socket abstraction contains a `void *' private field in
1330  * which the client can keep state.
1331  */
1332 static void sk_tcp_set_private_ptr(Socket sock, void *ptr)
1333 {
1334     Actual_Socket s = (Actual_Socket) sock;
1335     s->private_ptr = ptr;
1336 }
1337
1338 static void *sk_tcp_get_private_ptr(Socket sock)
1339 {
1340     Actual_Socket s = (Actual_Socket) sock;
1341     return s->private_ptr;
1342 }
1343
1344 /*
1345  * Special error values are returned from sk_namelookup and sk_new
1346  * if there's a problem. These functions extract an error message,
1347  * or return NULL if there's no problem.
1348  */
1349 const char *sk_addr_error(SockAddr addr)
1350 {
1351     return addr->error;
1352 }
1353 static const char *sk_tcp_socket_error(Socket sock)
1354 {
1355     Actual_Socket s = (Actual_Socket) sock;
1356     return s->error;
1357 }
1358
1359 static void sk_tcp_set_frozen(Socket sock, int is_frozen)
1360 {
1361     Actual_Socket s = (Actual_Socket) sock;
1362     if (s->frozen == is_frozen)
1363         return;
1364     s->frozen = is_frozen;
1365     if (!is_frozen && s->frozen_readable) {
1366         char c;
1367         recv(s->s, &c, 1, MSG_PEEK);
1368     }
1369     s->frozen_readable = 0;
1370     uxsel_tell(s);
1371 }
1372
1373 static void uxsel_tell(Actual_Socket s)
1374 {
1375     int rwx = 0;
1376     if (s->listener) {
1377         rwx |= 1;                       /* read == accept */
1378     } else {
1379         if (!s->connected)
1380             rwx |= 2;                   /* write == connect */
1381         if (s->connected && !s->frozen)
1382             rwx |= 1 | 4;               /* read, except */
1383         if (bufchain_size(&s->output_data))
1384             rwx |= 2;                   /* write */
1385     }
1386     uxsel_set(s->s, rwx, net_select_result);
1387 }
1388
1389 int net_service_lookup(char *service)
1390 {
1391     struct servent *se;
1392     se = getservbyname(service, NULL);
1393     if (se != NULL)
1394         return ntohs(se->s_port);
1395     else
1396         return 0;
1397 }
1398
1399 char *get_hostname(void)
1400 {
1401     int len = 128;
1402     char *hostname = NULL;
1403     do {
1404         len *= 2;
1405         hostname = sresize(hostname, len, char);
1406         if ((gethostname(hostname, len) < 0) &&
1407             (errno != ENAMETOOLONG)) {
1408             sfree(hostname);
1409             hostname = NULL;
1410             break;
1411         }
1412     } while (strlen(hostname) >= len-1);
1413     return hostname;
1414 }
1415
1416 SockAddr platform_get_x11_unix_address(const char *sockpath, int displaynum)
1417 {
1418     SockAddr ret = snew(struct SockAddr_tag);
1419     int n;
1420
1421     memset(ret, 0, sizeof *ret);
1422     ret->superfamily = UNIX;
1423     /*
1424      * In special circumstances (notably Mac OS X Leopard), we'll
1425      * have been passed an explicit Unix socket path.
1426      */
1427     if (sockpath) {
1428         n = snprintf(ret->hostname, sizeof ret->hostname,
1429                      "%s", sockpath);
1430     } else {
1431         n = snprintf(ret->hostname, sizeof ret->hostname,
1432                      "%s%d", X11_UNIX_PATH, displaynum);
1433     }
1434
1435     if (n < 0)
1436         ret->error = "snprintf failed";
1437     else if (n >= sizeof ret->hostname)
1438         ret->error = "X11 UNIX name too long";
1439
1440 #ifndef NO_IPV6
1441     ret->ais = NULL;
1442 #else
1443     ret->addresses = NULL;
1444     ret->naddresses = 0;
1445 #endif
1446     ret->refcount = 1;
1447     return ret;
1448 }