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