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