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