1 /*
2  * Windows networking abstraction.
3  *
4  * For the IPv6 code in here I am indebted to Jeroen Massar and
5  * unfix.org.
6  */
7 
8 #include <winsock2.h> /* need to put this first, for winelib builds */
9 
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <assert.h>
13 
14 #define NEED_DECLARATION_OF_SELECT     /* in order to initialise it */
15 
16 #include "putty.h"
17 #include "network.h"
18 #include "tree234.h"
19 #include "ssh.h"
20 
21 #include <ws2tcpip.h>
22 
23 #ifndef NO_IPV6
24 #ifdef __clang__
25 #pragma clang diagnostic push
26 #pragma clang diagnostic ignored "-Wmissing-braces"
27 #endif
28 const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
29 const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
30 #ifdef __clang__
31 #pragma clang diagnostic pop
32 #endif
33 #endif
34 
35 #define ipv4_is_loopback(addr) \
36         ((p_ntohl(addr.s_addr) & 0xFF000000L) == 0x7F000000L)
37 
38 /*
39  * Mutable state that goes with a SockAddr: stores information
40  * about where in the list of candidate IP(v*) addresses we've
41  * currently got to.
42  */
43 typedef struct SockAddrStep_tag SockAddrStep;
44 struct SockAddrStep_tag {
45 #ifndef NO_IPV6
46     struct addrinfo *ai;               /* steps along addr->ais */
47 #endif
48     int curraddr;
49 };
50 
51 typedef struct NetSocket NetSocket;
52 struct NetSocket {
53     const char *error;
54     SOCKET s;
55     Plug *plug;
56     bufchain output_data;
57     bool connected;
58     bool writable;
59     bool frozen; /* this causes readability notifications to be ignored */
60     bool frozen_readable; /* this means we missed at least one readability
61                            * notification while we were frozen */
62     bool localhost_only;               /* for listening sockets */
63     char oobdata[1];
64     size_t sending_oob;
65     bool oobinline, nodelay, keepalive, privport;
66     enum { EOF_NO, EOF_PENDING, EOF_SENT } outgoingeof;
67     SockAddr *addr;
68     SockAddrStep step;
69     int port;
70     int pending_error;             /* in case send() returns error */
71     /*
72      * We sometimes need pairs of Socket structures to be linked:
73      * if we are listening on the same IPv6 and v4 port, for
74      * example. So here we define `parent' and `child' pointers to
75      * track this link.
76      */
77     NetSocket *parent, *child;
78 
79     Socket sock;
80 };
81 
82 struct SockAddr {
83     int refcount;
84     char *error;
85     bool resolved;
86     bool namedpipe; /* indicates that this SockAddr is phony, holding a Windows
87                      * named pipe pathname instead of a network address */
88 #ifndef NO_IPV6
89     struct addrinfo *ais;              /* Addresses IPv6 style. */
90 #endif
91     unsigned long *addresses;          /* Addresses IPv4 style. */
92     int naddresses;
93     char hostname[512];                /* Store an unresolved host name. */
94 };
95 
96 /*
97  * Which address family this address belongs to. AF_INET for IPv4;
98  * AF_INET6 for IPv6; AF_UNSPEC indicates that name resolution has
99  * not been done and a simple host name is held in this SockAddr
100  * structure.
101  */
102 #ifndef NO_IPV6
103 #define SOCKADDR_FAMILY(addr, step) \
104     (!(addr)->resolved ? AF_UNSPEC : \
105      (step).ai ? (step).ai->ai_family : AF_INET)
106 #else
107 #define SOCKADDR_FAMILY(addr, step) \
108     (!(addr)->resolved ? AF_UNSPEC : AF_INET)
109 #endif
110 
111 /*
112  * Start a SockAddrStep structure to step through multiple
113  * addresses.
114  */
115 #ifndef NO_IPV6
116 #define START_STEP(addr, step) \
117     ((step).ai = (addr)->ais, (step).curraddr = 0)
118 #else
119 #define START_STEP(addr, step) \
120     ((step).curraddr = 0)
121 #endif
122 
123 static tree234 *sktree;
124 
cmpfortree(void * av,void * bv)125 static int cmpfortree(void *av, void *bv)
126 {
127     NetSocket *a = (NetSocket *)av, *b = (NetSocket *)bv;
128     uintptr_t as = (uintptr_t) a->s, bs = (uintptr_t) b->s;
129     if (as < bs)
130         return -1;
131     if (as > bs)
132         return +1;
133     if (a < b)
134         return -1;
135     if (a > b)
136         return +1;
137     return 0;
138 }
139 
cmpforsearch(void * av,void * bv)140 static int cmpforsearch(void *av, void *bv)
141 {
142     NetSocket *b = (NetSocket *)bv;
143     uintptr_t as = (uintptr_t) av, bs = (uintptr_t) b->s;
144     if (as < bs)
145         return -1;
146     if (as > bs)
147         return +1;
148     return 0;
149 }
150 
151 DECL_WINDOWS_FUNCTION(static, int, WSAStartup, (WORD, LPWSADATA));
152 DECL_WINDOWS_FUNCTION(static, int, WSACleanup, (void));
153 DECL_WINDOWS_FUNCTION(static, int, closesocket, (SOCKET));
154 DECL_WINDOWS_FUNCTION(static, u_long, ntohl, (u_long));
155 DECL_WINDOWS_FUNCTION(static, u_long, htonl, (u_long));
156 DECL_WINDOWS_FUNCTION(static, u_short, htons, (u_short));
157 DECL_WINDOWS_FUNCTION(static, u_short, ntohs, (u_short));
158 DECL_WINDOWS_FUNCTION(static, int, gethostname, (char *, int));
159 DECL_WINDOWS_FUNCTION(static, struct hostent FAR *, gethostbyname,
160                       (const char FAR *));
161 DECL_WINDOWS_FUNCTION(static, struct servent FAR *, getservbyname,
162                       (const char FAR *, const char FAR *));
163 DECL_WINDOWS_FUNCTION(static, unsigned long, inet_addr, (const char FAR *));
164 DECL_WINDOWS_FUNCTION(static, char FAR *, inet_ntoa, (struct in_addr));
165 DECL_WINDOWS_FUNCTION(static, const char FAR *, inet_ntop,
166                       (int, void FAR *, char *, size_t));
167 DECL_WINDOWS_FUNCTION(static, int, connect,
168                       (SOCKET, const struct sockaddr FAR *, int));
169 DECL_WINDOWS_FUNCTION(static, int, bind,
170                       (SOCKET, const struct sockaddr FAR *, int));
171 DECL_WINDOWS_FUNCTION(static, int, setsockopt,
172                       (SOCKET, int, int, const char FAR *, int));
173 DECL_WINDOWS_FUNCTION(static, SOCKET, socket, (int, int, int));
174 DECL_WINDOWS_FUNCTION(static, int, listen, (SOCKET, int));
175 DECL_WINDOWS_FUNCTION(static, int, send, (SOCKET, const char FAR *, int, int));
176 DECL_WINDOWS_FUNCTION(static, int, shutdown, (SOCKET, int));
177 DECL_WINDOWS_FUNCTION(static, int, ioctlsocket,
178                       (SOCKET, long, u_long FAR *));
179 DECL_WINDOWS_FUNCTION(static, SOCKET, accept,
180                       (SOCKET, struct sockaddr FAR *, int FAR *));
181 DECL_WINDOWS_FUNCTION(static, int, getpeername,
182                       (SOCKET, struct sockaddr FAR *, int FAR *));
183 DECL_WINDOWS_FUNCTION(static, int, recv, (SOCKET, char FAR *, int, int));
184 DECL_WINDOWS_FUNCTION(static, int, WSAIoctl,
185                       (SOCKET, DWORD, LPVOID, DWORD, LPVOID, DWORD,
186                        LPDWORD, LPWSAOVERLAPPED,
187                        LPWSAOVERLAPPED_COMPLETION_ROUTINE));
188 #ifndef NO_IPV6
189 DECL_WINDOWS_FUNCTION(static, int, getaddrinfo,
190                       (const char *nodename, const char *servname,
191                        const struct addrinfo *hints, struct addrinfo **res));
192 DECL_WINDOWS_FUNCTION(static, void, freeaddrinfo, (struct addrinfo *res));
193 DECL_WINDOWS_FUNCTION(static, int, getnameinfo,
194                       (const struct sockaddr FAR * sa, socklen_t salen,
195                        char FAR * host, DWORD hostlen, char FAR * serv,
196                        DWORD servlen, int flags));
197 DECL_WINDOWS_FUNCTION(static, char *, gai_strerror, (int ecode));
198 DECL_WINDOWS_FUNCTION(static, int, WSAAddressToStringA,
199                       (LPSOCKADDR, DWORD, LPWSAPROTOCOL_INFO,
200                        LPSTR, LPDWORD));
201 #endif
202 
203 static HMODULE winsock_module = NULL;
204 static WSADATA wsadata;
205 #ifndef NO_IPV6
206 static HMODULE winsock2_module = NULL;
207 static HMODULE wship6_module = NULL;
208 #endif
209 
sk_startup(int hi,int lo)210 static bool sk_startup(int hi, int lo)
211 {
212     WORD winsock_ver;
213 
214     winsock_ver = MAKEWORD(hi, lo);
215 
216     if (p_WSAStartup(winsock_ver, &wsadata)) {
217         return false;
218     }
219 
220     if (LOBYTE(wsadata.wVersion) != LOBYTE(winsock_ver)) {
221         return false;
222     }
223 
224     return true;
225 }
226 
227 DEF_WINDOWS_FUNCTION(WSAAsyncSelect);
228 DEF_WINDOWS_FUNCTION(WSAEventSelect);
229 DEF_WINDOWS_FUNCTION(WSAGetLastError);
230 DEF_WINDOWS_FUNCTION(WSAEnumNetworkEvents);
231 DEF_WINDOWS_FUNCTION(select);
232 
sk_init(void)233 void sk_init(void)
234 {
235 #ifndef NO_IPV6
236     winsock2_module =
237 #endif
238         winsock_module = load_system32_dll("ws2_32.dll");
239     if (!winsock_module) {
240         winsock_module = load_system32_dll("wsock32.dll");
241     }
242     if (!winsock_module)
243         modalfatalbox("Unable to load any WinSock library");
244 
245 #ifndef NO_IPV6
246     /* Check if we have getaddrinfo in Winsock */
247     if (GetProcAddress(winsock_module, "getaddrinfo") != NULL) {
248         GET_WINDOWS_FUNCTION(winsock_module, getaddrinfo);
249         GET_WINDOWS_FUNCTION(winsock_module, freeaddrinfo);
250         GET_WINDOWS_FUNCTION_NO_TYPECHECK(winsock_module, getnameinfo);
251         /* This function would fail its type-check if we did one,
252          * because the VS header file provides an inline definition
253          * which is __cdecl instead of WINAPI. */
254         GET_WINDOWS_FUNCTION_NO_TYPECHECK(winsock_module, gai_strerror);
255     } else {
256         /* Fall back to wship6.dll for Windows 2000 */
257         wship6_module = load_system32_dll("wship6.dll");
258         if (wship6_module) {
259             GET_WINDOWS_FUNCTION(wship6_module, getaddrinfo);
260             GET_WINDOWS_FUNCTION(wship6_module, freeaddrinfo);
261             /* See comment above about type check */
262             GET_WINDOWS_FUNCTION_NO_TYPECHECK(wship6_module, getnameinfo);
263             GET_WINDOWS_FUNCTION_NO_TYPECHECK(winsock_module, gai_strerror);
264         } else {
265         }
266     }
267     GET_WINDOWS_FUNCTION(winsock2_module, WSAAddressToStringA);
268 #endif
269 
270     GET_WINDOWS_FUNCTION(winsock_module, WSAAsyncSelect);
271     GET_WINDOWS_FUNCTION(winsock_module, WSAEventSelect);
272     /* We don't type-check select because at least some MinGW versions
273      * of the Windows API headers seem to disagree with the
274      * documentation on whether the 'struct timeval *' pointer is
275      * const or not. */
276     GET_WINDOWS_FUNCTION_NO_TYPECHECK(winsock_module, select);
277     GET_WINDOWS_FUNCTION(winsock_module, WSAGetLastError);
278     GET_WINDOWS_FUNCTION(winsock_module, WSAEnumNetworkEvents);
279     GET_WINDOWS_FUNCTION(winsock_module, WSAStartup);
280     GET_WINDOWS_FUNCTION(winsock_module, WSACleanup);
281     GET_WINDOWS_FUNCTION(winsock_module, closesocket);
282     GET_WINDOWS_FUNCTION(winsock_module, ntohl);
283     GET_WINDOWS_FUNCTION(winsock_module, htonl);
284     GET_WINDOWS_FUNCTION(winsock_module, htons);
285     GET_WINDOWS_FUNCTION(winsock_module, ntohs);
286     GET_WINDOWS_FUNCTION_NO_TYPECHECK(winsock_module, gethostname);
287     GET_WINDOWS_FUNCTION(winsock_module, gethostbyname);
288     GET_WINDOWS_FUNCTION(winsock_module, getservbyname);
289     GET_WINDOWS_FUNCTION(winsock_module, inet_addr);
290     GET_WINDOWS_FUNCTION(winsock_module, inet_ntoa);
291     /* Older Visual Studio, and MinGW as of Ubuntu 16.04, don't know
292      * about this function at all, so can't type-check it. Also there
293      * seems to be some disagreement in the VS headers about whether
294      * the second argument is void * or const void *, so I omit the
295      * type check. */
296     GET_WINDOWS_FUNCTION_NO_TYPECHECK(winsock_module, inet_ntop);
297     GET_WINDOWS_FUNCTION(winsock_module, connect);
298     GET_WINDOWS_FUNCTION(winsock_module, bind);
299     GET_WINDOWS_FUNCTION(winsock_module, setsockopt);
300     GET_WINDOWS_FUNCTION(winsock_module, socket);
301     GET_WINDOWS_FUNCTION(winsock_module, listen);
302     GET_WINDOWS_FUNCTION(winsock_module, send);
303     GET_WINDOWS_FUNCTION(winsock_module, shutdown);
304     GET_WINDOWS_FUNCTION(winsock_module, ioctlsocket);
305     GET_WINDOWS_FUNCTION(winsock_module, accept);
306     GET_WINDOWS_FUNCTION(winsock_module, getpeername);
307     GET_WINDOWS_FUNCTION(winsock_module, recv);
308     GET_WINDOWS_FUNCTION(winsock_module, WSAIoctl);
309 
310     /* Try to get the best WinSock version we can get */
311     if (!sk_startup(2,2) &&
312         !sk_startup(2,0) &&
313         !sk_startup(1,1)) {
314         modalfatalbox("Unable to initialise WinSock");
315     }
316 
317     sktree = newtree234(cmpfortree);
318 }
319 
sk_cleanup(void)320 void sk_cleanup(void)
321 {
322     NetSocket *s;
323     int i;
324 
325     if (sktree) {
326         for (i = 0; (s = index234(sktree, i)) != NULL; i++) {
327             p_closesocket(s->s);
328         }
329         freetree234(sktree);
330         sktree = NULL;
331     }
332 
333     if (p_WSACleanup)
334         p_WSACleanup();
335     if (winsock_module)
336         FreeLibrary(winsock_module);
337 #ifndef NO_IPV6
338     if (wship6_module)
339         FreeLibrary(wship6_module);
340 #endif
341 }
342 
winsock_error_string(int error)343 const char *winsock_error_string(int error)
344 {
345     /*
346      * Error codes we know about and have historically had reasonably
347      * sensible error messages for.
348      */
349     switch (error) {
350       case WSAEACCES:
351         return "Network error: Permission denied";
352       case WSAEADDRINUSE:
353         return "Network error: Address already in use";
354       case WSAEADDRNOTAVAIL:
355         return "Network error: Cannot assign requested address";
356       case WSAEAFNOSUPPORT:
357         return
358             "Network error: Address family not supported by protocol family";
359       case WSAEALREADY:
360         return "Network error: Operation already in progress";
361       case WSAECONNABORTED:
362         return "Network error: Software caused connection abort";
363       case WSAECONNREFUSED:
364         return "Network error: Connection refused";
365       case WSAECONNRESET:
366         return "Network error: Connection reset by peer";
367       case WSAEDESTADDRREQ:
368         return "Network error: Destination address required";
369       case WSAEFAULT:
370         return "Network error: Bad address";
371       case WSAEHOSTDOWN:
372         return "Network error: Host is down";
373       case WSAEHOSTUNREACH:
374         return "Network error: No route to host";
375       case WSAEINPROGRESS:
376         return "Network error: Operation now in progress";
377       case WSAEINTR:
378         return "Network error: Interrupted function call";
379       case WSAEINVAL:
380         return "Network error: Invalid argument";
381       case WSAEISCONN:
382         return "Network error: Socket is already connected";
383       case WSAEMFILE:
384         return "Network error: Too many open files";
385       case WSAEMSGSIZE:
386         return "Network error: Message too long";
387       case WSAENETDOWN:
388         return "Network error: Network is down";
389       case WSAENETRESET:
390         return "Network error: Network dropped connection on reset";
391       case WSAENETUNREACH:
392         return "Network error: Network is unreachable";
393       case WSAENOBUFS:
394         return "Network error: No buffer space available";
395       case WSAENOPROTOOPT:
396         return "Network error: Bad protocol option";
397       case WSAENOTCONN:
398         return "Network error: Socket is not connected";
399       case WSAENOTSOCK:
400         return "Network error: Socket operation on non-socket";
401       case WSAEOPNOTSUPP:
402         return "Network error: Operation not supported";
403       case WSAEPFNOSUPPORT:
404         return "Network error: Protocol family not supported";
405       case WSAEPROCLIM:
406         return "Network error: Too many processes";
407       case WSAEPROTONOSUPPORT:
408         return "Network error: Protocol not supported";
409       case WSAEPROTOTYPE:
410         return "Network error: Protocol wrong type for socket";
411       case WSAESHUTDOWN:
412         return "Network error: Cannot send after socket shutdown";
413       case WSAESOCKTNOSUPPORT:
414         return "Network error: Socket type not supported";
415       case WSAETIMEDOUT:
416         return "Network error: Connection timed out";
417       case WSAEWOULDBLOCK:
418         return "Network error: Resource temporarily unavailable";
419       case WSAEDISCON:
420         return "Network error: Graceful shutdown in progress";
421     }
422 
423     /*
424      * Handle any other error code by delegating to win_strerror.
425      */
426     return win_strerror(error);
427 }
428 
sk_namelookup(const char * host,char ** canonicalname,int address_family)429 SockAddr *sk_namelookup(const char *host, char **canonicalname,
430                         int address_family)
431 {
432     SockAddr *ret = snew(SockAddr);
433     unsigned long a;
434     char realhost[8192];
435     int hint_family;
436 
437     /* Default to IPv4. */
438     hint_family = (address_family == ADDRTYPE_IPV4 ? AF_INET :
439 #ifndef NO_IPV6
440                    address_family == ADDRTYPE_IPV6 ? AF_INET6 :
441 #endif
442                    AF_UNSPEC);
443 
444     /* Clear the structure and default to IPv4. */
445     memset(ret, 0, sizeof(SockAddr));
446 #ifndef NO_IPV6
447     ret->ais = NULL;
448 #endif
449     ret->namedpipe = false;
450     ret->addresses = NULL;
451     ret->resolved = false;
452     ret->refcount = 1;
453     *realhost = '\0';
454 
455     if ((a = p_inet_addr(host)) == (unsigned long) INADDR_NONE) {
456         struct hostent *h = NULL;
457         int err = 0;
458 #ifndef NO_IPV6
459         /*
460          * Use getaddrinfo when it's available
461          */
462         if (p_getaddrinfo) {
463             struct addrinfo hints;
464             memset(&hints, 0, sizeof(hints));
465             hints.ai_family = hint_family;
466             hints.ai_flags = AI_CANONNAME;
467             {
468                 /* strip [] on IPv6 address literals */
469                 char *trimmed_host = host_strduptrim(host);
470                 err = p_getaddrinfo(trimmed_host, NULL, &hints, &ret->ais);
471                 sfree(trimmed_host);
472             }
473             if (err == 0)
474                 ret->resolved = true;
475         } else
476 #endif
477         {
478             /*
479              * Otherwise use the IPv4-only gethostbyname...
480              * (NOTE: we don't use gethostbyname as a fallback!)
481              */
482             if ( (h = p_gethostbyname(host)) )
483                 ret->resolved = true;
484             else
485                 err = p_WSAGetLastError();
486         }
487 
488         if (!ret->resolved) {
489             ret->error = (err == WSAENETDOWN ? "Network is down" :
490                           err == WSAHOST_NOT_FOUND ? "Host does not exist" :
491                           err == WSATRY_AGAIN ? "Host not found" :
492 #ifndef NO_IPV6
493                           p_getaddrinfo&&p_gai_strerror ? p_gai_strerror(err) :
494 #endif
495                           "gethostbyname: unknown error");
496         } else {
497             ret->error = NULL;
498 
499 #ifndef NO_IPV6
500             /* If we got an address info use that... */
501             if (ret->ais) {
502                 /* Are we in IPv4 fallback mode? */
503                 /* We put the IPv4 address into the a variable so we can further-on use the IPv4 code... */
504                 if (ret->ais->ai_family == AF_INET)
505                     memcpy(&a,
506                            (char *) &((SOCKADDR_IN *) ret->ais->
507                                       ai_addr)->sin_addr, sizeof(a));
508 
509                 if (ret->ais->ai_canonname)
510                     strncpy(realhost, ret->ais->ai_canonname, lenof(realhost));
511                 else
512                     strncpy(realhost, host, lenof(realhost));
513             }
514             /* We used the IPv4-only gethostbyname()... */
515             else
516 #endif
517             {
518                 int n;
519                 for (n = 0; h->h_addr_list[n]; n++);
520                 ret->addresses = snewn(n, unsigned long);
521                 ret->naddresses = n;
522                 for (n = 0; n < ret->naddresses; n++) {
523                     memcpy(&a, h->h_addr_list[n], sizeof(a));
524                     ret->addresses[n] = p_ntohl(a);
525                 }
526                 memcpy(&a, h->h_addr, sizeof(a));
527                 /* This way we are always sure the h->h_name is valid :) */
528                 strncpy(realhost, h->h_name, sizeof(realhost));
529             }
530         }
531     } else {
532         /*
533          * This must be a numeric IPv4 address because it caused a
534          * success return from inet_addr.
535          */
536         ret->addresses = snewn(1, unsigned long);
537         ret->naddresses = 1;
538         ret->addresses[0] = p_ntohl(a);
539         ret->resolved = true;
540         strncpy(realhost, host, sizeof(realhost));
541     }
542     realhost[lenof(realhost)-1] = '\0';
543     *canonicalname = dupstr(realhost);
544     return ret;
545 }
546 
sk_nonamelookup(const char * host)547 SockAddr *sk_nonamelookup(const char *host)
548 {
549     SockAddr *ret = snew(SockAddr);
550     ret->error = NULL;
551     ret->resolved = false;
552 #ifndef NO_IPV6
553     ret->ais = NULL;
554 #endif
555     ret->namedpipe = false;
556     ret->addresses = NULL;
557     ret->naddresses = 0;
558     ret->refcount = 1;
559     strncpy(ret->hostname, host, lenof(ret->hostname));
560     ret->hostname[lenof(ret->hostname)-1] = '\0';
561     return ret;
562 }
563 
sk_namedpipe_addr(const char * pipename)564 SockAddr *sk_namedpipe_addr(const char *pipename)
565 {
566     SockAddr *ret = snew(SockAddr);
567     ret->error = NULL;
568     ret->resolved = false;
569 #ifndef NO_IPV6
570     ret->ais = NULL;
571 #endif
572     ret->namedpipe = true;
573     ret->addresses = NULL;
574     ret->naddresses = 0;
575     ret->refcount = 1;
576     strncpy(ret->hostname, pipename, lenof(ret->hostname));
577     ret->hostname[lenof(ret->hostname)-1] = '\0';
578     return ret;
579 }
580 
sk_nextaddr(SockAddr * addr,SockAddrStep * step)581 static bool sk_nextaddr(SockAddr *addr, SockAddrStep *step)
582 {
583 #ifndef NO_IPV6
584     if (step->ai) {
585         if (step->ai->ai_next) {
586             step->ai = step->ai->ai_next;
587             return true;
588         } else
589             return false;
590     }
591 #endif
592     if (step->curraddr+1 < addr->naddresses) {
593         step->curraddr++;
594         return true;
595     } else {
596         return false;
597     }
598 }
599 
sk_getaddr(SockAddr * addr,char * buf,int buflen)600 void sk_getaddr(SockAddr *addr, char *buf, int buflen)
601 {
602     SockAddrStep step;
603     START_STEP(addr, step);
604 
605 #ifndef NO_IPV6
606     if (step.ai) {
607         int err = 0;
608         if (p_WSAAddressToStringA) {
609             DWORD dwbuflen = buflen;
610             err = p_WSAAddressToStringA(step.ai->ai_addr, step.ai->ai_addrlen,
611                                         NULL, buf, &dwbuflen);
612         } else
613             err = -1;
614         if (err) {
615             strncpy(buf, addr->hostname, buflen);
616             if (!buf[0])
617                 strncpy(buf, "<unknown>", buflen);
618             buf[buflen-1] = '\0';
619         }
620     } else
621 #endif
622     if (SOCKADDR_FAMILY(addr, step) == AF_INET) {
623         struct in_addr a;
624         assert(addr->addresses && step.curraddr < addr->naddresses);
625         a.s_addr = p_htonl(addr->addresses[step.curraddr]);
626         strncpy(buf, p_inet_ntoa(a), buflen);
627         buf[buflen-1] = '\0';
628     } else {
629         strncpy(buf, addr->hostname, buflen);
630         buf[buflen-1] = '\0';
631     }
632 }
633 
634 /*
635  * This constructs a SockAddr that points at one specific sub-address
636  * of a parent SockAddr. The returned SockAddr does not own all its
637  * own memory: it points into the old one's data structures, so it
638  * MUST NOT be used after the old one is freed, and it MUST NOT be
639  * passed to sk_addr_free. (The latter is why it's returned by value
640  * rather than dynamically allocated - that should clue in anyone
641  * writing a call to it that something is weird about it.)
642  */
sk_extractaddr_tmp(SockAddr * addr,const SockAddrStep * step)643 static SockAddr sk_extractaddr_tmp(
644     SockAddr *addr, const SockAddrStep *step)
645 {
646     SockAddr toret;
647     toret = *addr;                    /* structure copy */
648     toret.refcount = 1;
649 
650 #ifndef NO_IPV6
651     toret.ais = step->ai;
652 #endif
653     if (SOCKADDR_FAMILY(addr, *step) == AF_INET
654 #ifndef NO_IPV6
655         && !toret.ais
656 #endif
657         )
658         toret.addresses += step->curraddr;
659 
660     return toret;
661 }
662 
sk_addr_needs_port(SockAddr * addr)663 bool sk_addr_needs_port(SockAddr *addr)
664 {
665     return !addr->namedpipe;
666 }
667 
sk_hostname_is_local(const char * name)668 bool sk_hostname_is_local(const char *name)
669 {
670     return !strcmp(name, "localhost") ||
671            !strcmp(name, "::1") ||
672            !strncmp(name, "127.", 4);
673 }
674 
675 static INTERFACE_INFO local_interfaces[16];
676 static int n_local_interfaces;       /* 0=not yet, -1=failed, >0=number */
677 
ipv4_is_local_addr(struct in_addr addr)678 static bool ipv4_is_local_addr(struct in_addr addr)
679 {
680     if (ipv4_is_loopback(addr))
681         return true;                   /* loopback addresses are local */
682     if (!n_local_interfaces) {
683         SOCKET s = p_socket(AF_INET, SOCK_DGRAM, 0);
684         DWORD retbytes;
685 
686         SetHandleInformation((HANDLE)s, HANDLE_FLAG_INHERIT, 0);
687 
688         if (p_WSAIoctl &&
689             p_WSAIoctl(s, SIO_GET_INTERFACE_LIST, NULL, 0,
690                        local_interfaces, sizeof(local_interfaces),
691                        &retbytes, NULL, NULL) == 0)
692             n_local_interfaces = retbytes / sizeof(INTERFACE_INFO);
693         else
694             n_local_interfaces = -1;
695     }
696     if (n_local_interfaces > 0) {
697         int i;
698         for (i = 0; i < n_local_interfaces; i++) {
699             SOCKADDR_IN *address =
700                 (SOCKADDR_IN *)&local_interfaces[i].iiAddress;
701             if (address->sin_addr.s_addr == addr.s_addr)
702                 return true;           /* this address is local */
703         }
704     }
705     return false;                      /* this address is not local */
706 }
707 
sk_address_is_local(SockAddr * addr)708 bool sk_address_is_local(SockAddr *addr)
709 {
710     SockAddrStep step;
711     int family;
712     START_STEP(addr, step);
713     family = SOCKADDR_FAMILY(addr, step);
714 
715 #ifndef NO_IPV6
716     if (family == AF_INET6) {
717         return IN6_IS_ADDR_LOOPBACK(&((const struct sockaddr_in6 *)step.ai->ai_addr)->sin6_addr);
718     } else
719 #endif
720     if (family == AF_INET) {
721 #ifndef NO_IPV6
722         if (step.ai) {
723             return ipv4_is_local_addr(((struct sockaddr_in *)step.ai->ai_addr)
724                                       ->sin_addr);
725         } else
726 #endif
727         {
728             struct in_addr a;
729             assert(addr->addresses && step.curraddr < addr->naddresses);
730             a.s_addr = p_htonl(addr->addresses[step.curraddr]);
731             return ipv4_is_local_addr(a);
732         }
733     } else {
734         assert(family == AF_UNSPEC);
735         return false;                  /* we don't know; assume not */
736     }
737 }
738 
sk_address_is_special_local(SockAddr * addr)739 bool sk_address_is_special_local(SockAddr *addr)
740 {
741     return false;            /* no Unix-domain socket analogue here */
742 }
743 
sk_addrtype(SockAddr * addr)744 int sk_addrtype(SockAddr *addr)
745 {
746     SockAddrStep step;
747     int family;
748     START_STEP(addr, step);
749     family = SOCKADDR_FAMILY(addr, step);
750 
751     return (family == AF_INET ? ADDRTYPE_IPV4 :
752 #ifndef NO_IPV6
753             family == AF_INET6 ? ADDRTYPE_IPV6 :
754 #endif
755             ADDRTYPE_NAME);
756 }
757 
sk_addrcopy(SockAddr * addr,char * buf)758 void sk_addrcopy(SockAddr *addr, char *buf)
759 {
760     SockAddrStep step;
761     int family;
762     START_STEP(addr, step);
763     family = SOCKADDR_FAMILY(addr, step);
764 
765     assert(family != AF_UNSPEC);
766 #ifndef NO_IPV6
767     if (step.ai) {
768         if (family == AF_INET)
769             memcpy(buf, &((struct sockaddr_in *)step.ai->ai_addr)->sin_addr,
770                    sizeof(struct in_addr));
771         else if (family == AF_INET6)
772             memcpy(buf, &((struct sockaddr_in6 *)step.ai->ai_addr)->sin6_addr,
773                    sizeof(struct in6_addr));
774         else
775             unreachable("bad address family in sk_addrcopy");
776     } else
777 #endif
778     if (family == AF_INET) {
779         struct in_addr a;
780         assert(addr->addresses && step.curraddr < addr->naddresses);
781         a.s_addr = p_htonl(addr->addresses[step.curraddr]);
782         memcpy(buf, (char*) &a.s_addr, 4);
783     }
784 }
785 
sk_addr_free(SockAddr * addr)786 void sk_addr_free(SockAddr *addr)
787 {
788     if (--addr->refcount > 0)
789         return;
790 #ifndef NO_IPV6
791     if (addr->ais && p_freeaddrinfo)
792         p_freeaddrinfo(addr->ais);
793 #endif
794     if (addr->addresses)
795         sfree(addr->addresses);
796     sfree(addr);
797 }
798 
sk_addr_dup(SockAddr * addr)799 SockAddr *sk_addr_dup(SockAddr *addr)
800 {
801     addr->refcount++;
802     return addr;
803 }
804 
sk_net_plug(Socket * sock,Plug * p)805 static Plug *sk_net_plug(Socket *sock, Plug *p)
806 {
807     NetSocket *s = container_of(sock, NetSocket, sock);
808     Plug *ret = s->plug;
809     if (p)
810         s->plug = p;
811     return ret;
812 }
813 
814 static void sk_net_close(Socket *s);
815 static size_t sk_net_write(Socket *s, const void *data, size_t len);
816 static size_t sk_net_write_oob(Socket *s, const void *data, size_t len);
817 static void sk_net_write_eof(Socket *s);
818 static void sk_net_set_frozen(Socket *s, bool is_frozen);
819 static const char *sk_net_socket_error(Socket *s);
820 static SocketPeerInfo *sk_net_peer_info(Socket *s);
821 
822 static const SocketVtable NetSocket_sockvt = {
823     .plug = sk_net_plug,
824     .close = sk_net_close,
825     .write = sk_net_write,
826     .write_oob = sk_net_write_oob,
827     .write_eof = sk_net_write_eof,
828     .set_frozen = sk_net_set_frozen,
829     .socket_error = sk_net_socket_error,
830     .peer_info = sk_net_peer_info,
831 };
832 
sk_net_accept(accept_ctx_t ctx,Plug * plug)833 static Socket *sk_net_accept(accept_ctx_t ctx, Plug *plug)
834 {
835     DWORD err;
836     const char *errstr;
837     NetSocket *ret;
838 
839     /*
840      * Create NetSocket structure.
841      */
842     ret = snew(NetSocket);
843     ret->sock.vt = &NetSocket_sockvt;
844     ret->error = NULL;
845     ret->plug = plug;
846     bufchain_init(&ret->output_data);
847     ret->writable = true;              /* to start with */
848     ret->sending_oob = 0;
849     ret->outgoingeof = EOF_NO;
850     ret->frozen = true;
851     ret->frozen_readable = false;
852     ret->localhost_only = false;    /* unused, but best init anyway */
853     ret->pending_error = 0;
854     ret->parent = ret->child = NULL;
855     ret->addr = NULL;
856 
857     ret->s = (SOCKET)ctx.p;
858 
859     if (ret->s == INVALID_SOCKET) {
860         err = p_WSAGetLastError();
861         ret->error = winsock_error_string(err);
862         return &ret->sock;
863     }
864 
865     ret->oobinline = false;
866 
867     /* Set up a select mechanism. This could be an AsyncSelect on a
868      * window, or an EventSelect on an event object. */
869     errstr = do_select(ret->s, true);
870     if (errstr) {
871         ret->error = errstr;
872         return &ret->sock;
873     }
874 
875     add234(sktree, ret);
876 
877     return &ret->sock;
878 }
879 
try_connect(NetSocket * sock)880 static DWORD try_connect(NetSocket *sock)
881 {
882     SOCKET s;
883 #ifndef NO_IPV6
884     SOCKADDR_IN6 a6;
885 #endif
886     SOCKADDR_IN a;
887     DWORD err;
888     const char *errstr;
889     short localport;
890     int family;
891 
892     if (sock->s != INVALID_SOCKET) {
893         do_select(sock->s, false);
894         p_closesocket(sock->s);
895     }
896 
897     {
898         SockAddr thisaddr = sk_extractaddr_tmp(
899             sock->addr, &sock->step);
900         plug_log(sock->plug, PLUGLOG_CONNECT_TRYING,
901                  &thisaddr, sock->port, NULL, 0);
902     }
903 
904     /*
905      * Open socket.
906      */
907     family = SOCKADDR_FAMILY(sock->addr, sock->step);
908 
909     /*
910      * Remove the socket from the tree before we overwrite its
911      * internal socket id, because that forms part of the tree's
912      * sorting criterion. We'll add it back before exiting this
913      * function, whether we changed anything or not.
914      */
915     del234(sktree, sock);
916 
917     s = p_socket(family, SOCK_STREAM, 0);
918     sock->s = s;
919 
920     if (s == INVALID_SOCKET) {
921         err = p_WSAGetLastError();
922         sock->error = winsock_error_string(err);
923         goto ret;
924     }
925 
926         SetHandleInformation((HANDLE)s, HANDLE_FLAG_INHERIT, 0);
927 
928     if (sock->oobinline) {
929         BOOL b = true;
930         p_setsockopt(s, SOL_SOCKET, SO_OOBINLINE, (void *) &b, sizeof(b));
931     }
932 
933     if (sock->nodelay) {
934         BOOL b = true;
935         p_setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (void *) &b, sizeof(b));
936     }
937 
938     if (sock->keepalive) {
939         BOOL b = true;
940         p_setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (void *) &b, sizeof(b));
941     }
942 
943     /*
944      * Bind to local address.
945      */
946     if (sock->privport)
947         localport = 1023;              /* count from 1023 downwards */
948     else
949         localport = 0;                 /* just use port 0 (ie winsock picks) */
950 
951     /* Loop round trying to bind */
952     while (1) {
953         int sockcode;
954 
955 #ifndef NO_IPV6
956         if (family == AF_INET6) {
957             memset(&a6, 0, sizeof(a6));
958             a6.sin6_family = AF_INET6;
959           /*a6.sin6_addr = in6addr_any; */ /* == 0 done by memset() */
960             a6.sin6_port = p_htons(localport);
961         } else
962 #endif
963         {
964             a.sin_family = AF_INET;
965             a.sin_addr.s_addr = p_htonl(INADDR_ANY);
966             a.sin_port = p_htons(localport);
967         }
968 #ifndef NO_IPV6
969         sockcode = p_bind(s, (family == AF_INET6 ?
970                               (struct sockaddr *) &a6 :
971                               (struct sockaddr *) &a),
972                           (family == AF_INET6 ? sizeof(a6) : sizeof(a)));
973 #else
974         sockcode = p_bind(s, (struct sockaddr *) &a, sizeof(a));
975 #endif
976         if (sockcode != SOCKET_ERROR) {
977             err = 0;
978             break;                     /* done */
979         } else {
980             err = p_WSAGetLastError();
981             if (err != WSAEADDRINUSE)  /* failed, for a bad reason */
982                 break;
983         }
984 
985         if (localport == 0)
986             break;                     /* we're only looping once */
987         localport--;
988         if (localport == 0)
989             break;                     /* we might have got to the end */
990     }
991 
992     if (err) {
993         sock->error = winsock_error_string(err);
994         goto ret;
995     }
996 
997     /*
998      * Connect to remote address.
999      */
1000 #ifndef NO_IPV6
1001     if (sock->step.ai) {
1002         if (family == AF_INET6) {
1003             a6.sin6_family = AF_INET6;
1004             a6.sin6_port = p_htons((short) sock->port);
1005             a6.sin6_addr =
1006                 ((struct sockaddr_in6 *) sock->step.ai->ai_addr)->sin6_addr;
1007             a6.sin6_flowinfo = ((struct sockaddr_in6 *) sock->step.ai->ai_addr)->sin6_flowinfo;
1008             a6.sin6_scope_id = ((struct sockaddr_in6 *) sock->step.ai->ai_addr)->sin6_scope_id;
1009         } else {
1010             a.sin_family = AF_INET;
1011             a.sin_addr =
1012                 ((struct sockaddr_in *) sock->step.ai->ai_addr)->sin_addr;
1013             a.sin_port = p_htons((short) sock->port);
1014         }
1015     } else
1016 #endif
1017     {
1018         assert(sock->addr->addresses && sock->step.curraddr < sock->addr->naddresses);
1019         a.sin_family = AF_INET;
1020         a.sin_addr.s_addr = p_htonl(sock->addr->addresses[sock->step.curraddr]);
1021         a.sin_port = p_htons((short) sock->port);
1022     }
1023 
1024     /* Set up a select mechanism. This could be an AsyncSelect on a
1025      * window, or an EventSelect on an event object. */
1026     errstr = do_select(s, true);
1027     if (errstr) {
1028         sock->error = errstr;
1029         err = 1;
1030         goto ret;
1031     }
1032 
1033     if ((
1034 #ifndef NO_IPV6
1035             p_connect(s,
1036                       ((family == AF_INET6) ? (struct sockaddr *) &a6 :
1037                        (struct sockaddr *) &a),
1038                       (family == AF_INET6) ? sizeof(a6) : sizeof(a))
1039 #else
1040             p_connect(s, (struct sockaddr *) &a, sizeof(a))
1041 #endif
1042         ) == SOCKET_ERROR) {
1043         err = p_WSAGetLastError();
1044         /*
1045          * We expect a potential EWOULDBLOCK here, because the
1046          * chances are the front end has done a select for
1047          * FD_CONNECT, so that connect() will complete
1048          * asynchronously.
1049          */
1050         if ( err != WSAEWOULDBLOCK ) {
1051             sock->error = winsock_error_string(err);
1052             goto ret;
1053         }
1054     } else {
1055         /*
1056          * If we _don't_ get EWOULDBLOCK, the connect has completed
1057          * and we should set the socket as writable.
1058          */
1059         sock->writable = true;
1060         SockAddr thisaddr = sk_extractaddr_tmp(sock->addr, &sock->step);
1061         plug_log(sock->plug, PLUGLOG_CONNECT_SUCCESS,
1062                  &thisaddr, sock->port, NULL, 0);
1063     }
1064 
1065     err = 0;
1066 
1067     ret:
1068 
1069     /*
1070      * No matter what happened, put the socket back in the tree.
1071      */
1072     add234(sktree, sock);
1073 
1074     if (err) {
1075         SockAddr thisaddr = sk_extractaddr_tmp(
1076             sock->addr, &sock->step);
1077         plug_log(sock->plug, PLUGLOG_CONNECT_FAILED,
1078                  &thisaddr, sock->port, sock->error, err);
1079     }
1080     return err;
1081 }
1082 
sk_new(SockAddr * addr,int port,bool privport,bool oobinline,bool nodelay,bool keepalive,Plug * plug)1083 Socket *sk_new(SockAddr *addr, int port, bool privport, bool oobinline,
1084                bool nodelay, bool keepalive, Plug *plug)
1085 {
1086     NetSocket *ret;
1087     DWORD err;
1088 
1089     /*
1090      * Create NetSocket structure.
1091      */
1092     ret = snew(NetSocket);
1093     ret->sock.vt = &NetSocket_sockvt;
1094     ret->error = NULL;
1095     ret->plug = plug;
1096     bufchain_init(&ret->output_data);
1097     ret->connected = false;            /* to start with */
1098     ret->writable = false;             /* to start with */
1099     ret->sending_oob = 0;
1100     ret->outgoingeof = EOF_NO;
1101     ret->frozen = false;
1102     ret->frozen_readable = false;
1103     ret->localhost_only = false;    /* unused, but best init anyway */
1104     ret->pending_error = 0;
1105     ret->parent = ret->child = NULL;
1106     ret->oobinline = oobinline;
1107     ret->nodelay = nodelay;
1108     ret->keepalive = keepalive;
1109     ret->privport = privport;
1110     ret->port = port;
1111     ret->addr = addr;
1112     START_STEP(ret->addr, ret->step);
1113     ret->s = INVALID_SOCKET;
1114 
1115     err = 0;
1116     do {
1117         err = try_connect(ret);
1118     } while (err && sk_nextaddr(ret->addr, &ret->step));
1119 
1120     return &ret->sock;
1121 }
1122 
sk_newlistener(const char * srcaddr,int port,Plug * plug,bool local_host_only,int orig_address_family)1123 Socket *sk_newlistener(const char *srcaddr, int port, Plug *plug,
1124                        bool local_host_only, int orig_address_family)
1125 {
1126     SOCKET s;
1127 #ifndef NO_IPV6
1128     SOCKADDR_IN6 a6;
1129 #endif
1130     SOCKADDR_IN a;
1131 
1132     DWORD err;
1133     const char *errstr;
1134     NetSocket *ret;
1135     int retcode;
1136 
1137     int address_family;
1138 
1139     /*
1140      * Create NetSocket structure.
1141      */
1142     ret = snew(NetSocket);
1143     ret->sock.vt = &NetSocket_sockvt;
1144     ret->error = NULL;
1145     ret->plug = plug;
1146     bufchain_init(&ret->output_data);
1147     ret->writable = false;             /* to start with */
1148     ret->sending_oob = 0;
1149     ret->outgoingeof = EOF_NO;
1150     ret->frozen = false;
1151     ret->frozen_readable = false;
1152     ret->localhost_only = local_host_only;
1153     ret->pending_error = 0;
1154     ret->parent = ret->child = NULL;
1155     ret->addr = NULL;
1156 
1157     /*
1158      * Translate address_family from platform-independent constants
1159      * into local reality.
1160      */
1161     address_family = (orig_address_family == ADDRTYPE_IPV4 ? AF_INET :
1162 #ifndef NO_IPV6
1163                       orig_address_family == ADDRTYPE_IPV6 ? AF_INET6 :
1164 #endif
1165                       AF_UNSPEC);
1166 
1167     /*
1168      * Our default, if passed the `don't care' value
1169      * ADDRTYPE_UNSPEC, is to listen on IPv4. If IPv6 is supported,
1170      * we will also set up a second socket listening on IPv6, but
1171      * the v4 one is primary since that ought to work even on
1172      * non-v6-supporting systems.
1173      */
1174     if (address_family == AF_UNSPEC) address_family = AF_INET;
1175 
1176     /*
1177      * Open socket.
1178      */
1179     s = p_socket(address_family, SOCK_STREAM, 0);
1180     ret->s = s;
1181 
1182     if (s == INVALID_SOCKET) {
1183         err = p_WSAGetLastError();
1184         ret->error = winsock_error_string(err);
1185         return &ret->sock;
1186     }
1187 
1188     SetHandleInformation((HANDLE)s, HANDLE_FLAG_INHERIT, 0);
1189 
1190     ret->oobinline = false;
1191 
1192     {
1193         BOOL on = true;
1194         p_setsockopt(s, SOL_SOCKET, SO_EXCLUSIVEADDRUSE,
1195                      (const char *)&on, sizeof(on));
1196     }
1197 
1198 #ifndef NO_IPV6
1199         if (address_family == AF_INET6) {
1200             memset(&a6, 0, sizeof(a6));
1201             a6.sin6_family = AF_INET6;
1202             if (local_host_only)
1203                 a6.sin6_addr = in6addr_loopback;
1204             else
1205                 a6.sin6_addr = in6addr_any;
1206             if (srcaddr != NULL && p_getaddrinfo) {
1207                 struct addrinfo hints;
1208                 struct addrinfo *ai;
1209                 int err;
1210 
1211                 memset(&hints, 0, sizeof(hints));
1212                 hints.ai_family = AF_INET6;
1213                 hints.ai_flags = 0;
1214                 {
1215                     /* strip [] on IPv6 address literals */
1216                     char *trimmed_addr = host_strduptrim(srcaddr);
1217                     err = p_getaddrinfo(trimmed_addr, NULL, &hints, &ai);
1218                     sfree(trimmed_addr);
1219                 }
1220                 if (err == 0 && ai->ai_family == AF_INET6) {
1221                     a6.sin6_addr =
1222                         ((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr;
1223                 }
1224             }
1225             a6.sin6_port = p_htons(port);
1226         } else
1227 #endif
1228         {
1229             bool got_addr = false;
1230             a.sin_family = AF_INET;
1231 
1232             /*
1233              * Bind to source address. First try an explicitly
1234              * specified one...
1235              */
1236             if (srcaddr) {
1237                 a.sin_addr.s_addr = p_inet_addr(srcaddr);
1238                 if (a.sin_addr.s_addr != INADDR_NONE) {
1239                     /* Override localhost_only with specified listen addr. */
1240                     ret->localhost_only = ipv4_is_loopback(a.sin_addr);
1241                     got_addr = true;
1242                 }
1243             }
1244 
1245             /*
1246              * ... and failing that, go with one of the standard ones.
1247              */
1248             if (!got_addr) {
1249                 if (local_host_only)
1250                     a.sin_addr.s_addr = p_htonl(INADDR_LOOPBACK);
1251                 else
1252                     a.sin_addr.s_addr = p_htonl(INADDR_ANY);
1253             }
1254 
1255             a.sin_port = p_htons((short)port);
1256         }
1257 #ifndef NO_IPV6
1258         retcode = p_bind(s, (address_family == AF_INET6 ?
1259                            (struct sockaddr *) &a6 :
1260                            (struct sockaddr *) &a),
1261                        (address_family ==
1262                         AF_INET6 ? sizeof(a6) : sizeof(a)));
1263 #else
1264         retcode = p_bind(s, (struct sockaddr *) &a, sizeof(a));
1265 #endif
1266         if (retcode != SOCKET_ERROR) {
1267             err = 0;
1268         } else {
1269             err = p_WSAGetLastError();
1270         }
1271 
1272     if (err) {
1273         p_closesocket(s);
1274         ret->error = winsock_error_string(err);
1275         return &ret->sock;
1276     }
1277 
1278 
1279     if (p_listen(s, SOMAXCONN) == SOCKET_ERROR) {
1280         p_closesocket(s);
1281         ret->error = winsock_error_string(p_WSAGetLastError());
1282         return &ret->sock;
1283     }
1284 
1285     /* Set up a select mechanism. This could be an AsyncSelect on a
1286      * window, or an EventSelect on an event object. */
1287     errstr = do_select(s, true);
1288     if (errstr) {
1289         p_closesocket(s);
1290         ret->error = errstr;
1291         return &ret->sock;
1292     }
1293 
1294     add234(sktree, ret);
1295 
1296 #ifndef NO_IPV6
1297     /*
1298      * If we were given ADDRTYPE_UNSPEC, we must also create an
1299      * IPv6 listening socket and link it to this one.
1300      */
1301     if (address_family == AF_INET && orig_address_family == ADDRTYPE_UNSPEC) {
1302         Socket *other = sk_newlistener(srcaddr, port, plug,
1303                                        local_host_only, ADDRTYPE_IPV6);
1304 
1305         if (other) {
1306             NetSocket *ns = container_of(other, NetSocket, sock);
1307             if (!ns->error) {
1308                 ns->parent = ret;
1309                 ret->child = ns;
1310             } else {
1311                 sfree(ns);
1312             }
1313         }
1314     }
1315 #endif
1316 
1317     return &ret->sock;
1318 }
1319 
sk_net_close(Socket * sock)1320 static void sk_net_close(Socket *sock)
1321 {
1322     NetSocket *s = container_of(sock, NetSocket, sock);
1323 
1324     if (s->child)
1325         sk_net_close(&s->child->sock);
1326 
1327     bufchain_clear(&s->output_data);
1328 
1329     del234(sktree, s);
1330     do_select(s->s, false);
1331     p_closesocket(s->s);
1332     if (s->addr)
1333         sk_addr_free(s->addr);
1334     delete_callbacks_for_context(s);
1335     sfree(s);
1336 }
1337 
1338 /*
1339  * Deal with socket errors detected in try_send().
1340  */
socket_error_callback(void * vs)1341 static void socket_error_callback(void *vs)
1342 {
1343     NetSocket *s = (NetSocket *)vs;
1344 
1345     /*
1346      * Just in case other socket work has caused this socket to vanish
1347      * or become somehow non-erroneous before this callback arrived...
1348      */
1349     if (!find234(sktree, s, NULL) || !s->pending_error)
1350         return;
1351 
1352     /*
1353      * An error has occurred on this socket. Pass it to the plug.
1354      */
1355     plug_closing(s->plug, winsock_error_string(s->pending_error),
1356                  s->pending_error, 0);
1357 }
1358 
1359 /*
1360  * The function which tries to send on a socket once it's deemed
1361  * writable.
1362  */
try_send(NetSocket * s)1363 void try_send(NetSocket *s)
1364 {
1365     while (s->sending_oob || bufchain_size(&s->output_data) > 0) {
1366         int nsent;
1367         DWORD err;
1368         const void *data;
1369         size_t len;
1370         int urgentflag;
1371 
1372         if (s->sending_oob) {
1373             urgentflag = MSG_OOB;
1374             len = s->sending_oob;
1375             data = &s->oobdata;
1376         } else {
1377             urgentflag = 0;
1378             ptrlen bufdata = bufchain_prefix(&s->output_data);
1379             data = bufdata.ptr;
1380             len = bufdata.len;
1381         }
1382         len = min(len, INT_MAX);       /* WinSock send() takes an int */
1383         nsent = p_send(s->s, data, len, urgentflag);
1384         noise_ultralight(NOISE_SOURCE_IOLEN, nsent);
1385         if (nsent <= 0) {
1386             err = (nsent < 0 ? p_WSAGetLastError() : 0);
1387             if ((err < WSABASEERR && nsent < 0) || err == WSAEWOULDBLOCK) {
1388                 /*
1389                  * Perfectly normal: we've sent all we can for the moment.
1390                  *
1391                  * (Some WinSock send() implementations can return
1392                  * <0 but leave no sensible error indication -
1393                  * WSAGetLastError() is called but returns zero or
1394                  * a small number - so we check that case and treat
1395                  * it just like WSAEWOULDBLOCK.)
1396                  */
1397                 s->writable = false;
1398                 return;
1399             } else {
1400                 /*
1401                  * If send() returns a socket error, we unfortunately
1402                  * can't just call plug_closing(), because it's quite
1403                  * likely that we're currently _in_ a call from the
1404                  * code we'd be calling back to, so we'd have to make
1405                  * half the SSH code reentrant. Instead we flag a
1406                  * pending error on the socket, to be dealt with (by
1407                  * calling plug_closing()) at some suitable future
1408                  * moment.
1409                  */
1410                 s->pending_error = err;
1411                 queue_toplevel_callback(socket_error_callback, s);
1412                 return;
1413             }
1414         } else {
1415             if (s->sending_oob) {
1416                 if (nsent < len) {
1417                     memmove(s->oobdata, s->oobdata+nsent, len-nsent);
1418                     s->sending_oob = len - nsent;
1419                 } else {
1420                     s->sending_oob = 0;
1421                 }
1422             } else {
1423                 bufchain_consume(&s->output_data, nsent);
1424             }
1425         }
1426     }
1427 
1428     /*
1429      * If we reach here, we've finished sending everything we might
1430      * have needed to send. Send EOF, if we need to.
1431      */
1432     if (s->outgoingeof == EOF_PENDING) {
1433         p_shutdown(s->s, SD_SEND);
1434         s->outgoingeof = EOF_SENT;
1435     }
1436 }
1437 
sk_net_write(Socket * sock,const void * buf,size_t len)1438 static size_t sk_net_write(Socket *sock, const void *buf, size_t len)
1439 {
1440     NetSocket *s = container_of(sock, NetSocket, sock);
1441 
1442     assert(s->outgoingeof == EOF_NO);
1443 
1444     /*
1445      * Add the data to the buffer list on the socket.
1446      */
1447     bufchain_add(&s->output_data, buf, len);
1448 
1449     /*
1450      * Now try sending from the start of the buffer list.
1451      */
1452     if (s->writable)
1453         try_send(s);
1454 
1455     return bufchain_size(&s->output_data);
1456 }
1457 
sk_net_write_oob(Socket * sock,const void * buf,size_t len)1458 static size_t sk_net_write_oob(Socket *sock, const void *buf, size_t len)
1459 {
1460     NetSocket *s = container_of(sock, NetSocket, sock);
1461 
1462     assert(s->outgoingeof == EOF_NO);
1463 
1464     /*
1465      * Replace the buffer list on the socket with the data.
1466      */
1467     bufchain_clear(&s->output_data);
1468     assert(len <= sizeof(s->oobdata));
1469     memcpy(s->oobdata, buf, len);
1470     s->sending_oob = len;
1471 
1472     /*
1473      * Now try sending from the start of the buffer list.
1474      */
1475     if (s->writable)
1476         try_send(s);
1477 
1478     return s->sending_oob;
1479 }
1480 
sk_net_write_eof(Socket * sock)1481 static void sk_net_write_eof(Socket *sock)
1482 {
1483     NetSocket *s = container_of(sock, NetSocket, sock);
1484 
1485     assert(s->outgoingeof == EOF_NO);
1486 
1487     /*
1488      * Mark the socket as pending outgoing EOF.
1489      */
1490     s->outgoingeof = EOF_PENDING;
1491 
1492     /*
1493      * Now try sending from the start of the buffer list.
1494      */
1495     if (s->writable)
1496         try_send(s);
1497 }
1498 
select_result(WPARAM wParam,LPARAM lParam)1499 void select_result(WPARAM wParam, LPARAM lParam)
1500 {
1501     int ret;
1502     DWORD err;
1503     char buf[20480];                   /* nice big buffer for plenty of speed */
1504     NetSocket *s;
1505     bool atmark;
1506 
1507     /* wParam is the socket itself */
1508 
1509     if (wParam == 0)
1510         return;                /* boggle */
1511 
1512     s = find234(sktree, (void *) wParam, cmpforsearch);
1513     if (!s)
1514         return;                /* boggle */
1515 
1516     if ((err = WSAGETSELECTERROR(lParam)) != 0) {
1517         /*
1518          * An error has occurred on this socket. Pass it to the
1519          * plug.
1520          */
1521         if (s->addr) {
1522             SockAddr thisaddr = sk_extractaddr_tmp(
1523                 s->addr, &s->step);
1524             plug_log(s->plug, PLUGLOG_CONNECT_FAILED, &thisaddr, s->port,
1525                      winsock_error_string(err), err);
1526             while (err && s->addr && sk_nextaddr(s->addr, &s->step)) {
1527                 err = try_connect(s);
1528             }
1529         }
1530         if (err != 0)
1531             plug_closing(s->plug, winsock_error_string(err), err, 0);
1532         return;
1533     }
1534 
1535     noise_ultralight(NOISE_SOURCE_IOID, wParam);
1536 
1537     switch (WSAGETSELECTEVENT(lParam)) {
1538       case FD_CONNECT:
1539         s->connected = true;
1540         s->writable = true;
1541 
1542         /*
1543          * Once a socket is connected, we can stop falling back
1544          * through the candidate addresses to connect to. But first,
1545          * let the plug know we were successful.
1546          */
1547         if (s->addr) {
1548             SockAddr thisaddr = sk_extractaddr_tmp(
1549                 s->addr, &s->step);
1550             plug_log(s->plug, PLUGLOG_CONNECT_SUCCESS,
1551                      &thisaddr, s->port, NULL, 0);
1552 
1553             sk_addr_free(s->addr);
1554             s->addr = NULL;
1555         }
1556         break;
1557       case FD_READ:
1558         /* In the case the socket is still frozen, we don't even bother */
1559         if (s->frozen) {
1560             s->frozen_readable = true;
1561             break;
1562         }
1563 
1564         /*
1565          * We have received data on the socket. For an oobinline
1566          * socket, this might be data _before_ an urgent pointer,
1567          * in which case we send it to the back end with type==1
1568          * (data prior to urgent).
1569          */
1570         if (s->oobinline) {
1571             u_long atmark_from_ioctl = 1;
1572             p_ioctlsocket(s->s, SIOCATMARK, &atmark_from_ioctl);
1573             /*
1574              * Avoid checking the return value from ioctlsocket(),
1575              * on the grounds that some WinSock wrappers don't
1576              * support it. If it does nothing, we get atmark==1,
1577              * which is equivalent to `no OOB pending', so the
1578              * effect will be to non-OOB-ify any OOB data.
1579              */
1580             atmark = atmark_from_ioctl;
1581         } else
1582             atmark = true;
1583 
1584         ret = p_recv(s->s, buf, sizeof(buf), 0);
1585         noise_ultralight(NOISE_SOURCE_IOLEN, ret);
1586         if (ret < 0) {
1587             err = p_WSAGetLastError();
1588             if (err == WSAEWOULDBLOCK) {
1589                 break;
1590             }
1591         }
1592         if (ret < 0) {
1593             plug_closing(s->plug, winsock_error_string(err), err, 0);
1594         } else if (0 == ret) {
1595             plug_closing(s->plug, NULL, 0, 0);
1596         } else {
1597             plug_receive(s->plug, atmark ? 0 : 1, buf, ret);
1598         }
1599         break;
1600       case FD_OOB:
1601         /*
1602          * This will only happen on a non-oobinline socket. It
1603          * indicates that we can immediately perform an OOB read
1604          * and get back OOB data, which we will send to the back
1605          * end with type==2 (urgent data).
1606          */
1607         ret = p_recv(s->s, buf, sizeof(buf), MSG_OOB);
1608         noise_ultralight(NOISE_SOURCE_IOLEN, ret);
1609         if (ret <= 0) {
1610             int err = p_WSAGetLastError();
1611             plug_closing(s->plug, winsock_error_string(err), err, 0);
1612         } else {
1613             plug_receive(s->plug, 2, buf, ret);
1614         }
1615         break;
1616       case FD_WRITE: {
1617         int bufsize_before, bufsize_after;
1618         s->writable = true;
1619         bufsize_before = s->sending_oob + bufchain_size(&s->output_data);
1620         try_send(s);
1621         bufsize_after = s->sending_oob + bufchain_size(&s->output_data);
1622         if (bufsize_after < bufsize_before)
1623             plug_sent(s->plug, bufsize_after);
1624         break;
1625       }
1626       case FD_CLOSE:
1627         /* Signal a close on the socket. First read any outstanding data. */
1628         do {
1629             ret = p_recv(s->s, buf, sizeof(buf), 0);
1630             if (ret < 0) {
1631                 err = p_WSAGetLastError();
1632                 if (err == WSAEWOULDBLOCK)
1633                     break;
1634                 plug_closing(s->plug, winsock_error_string(err), err, 0);
1635             } else {
1636                 if (ret)
1637                     plug_receive(s->plug, 0, buf, ret);
1638                 else
1639                     plug_closing(s->plug, NULL, 0, 0);
1640             }
1641         } while (ret > 0);
1642         return;
1643       case FD_ACCEPT: {
1644 #ifdef NO_IPV6
1645         struct sockaddr_in isa;
1646 #else
1647         struct sockaddr_storage isa;
1648 #endif
1649         int addrlen = sizeof(isa);
1650         SOCKET t;  /* socket of connection */
1651         accept_ctx_t actx;
1652 
1653         memset(&isa, 0, sizeof(isa));
1654         err = 0;
1655         t = p_accept(s->s,(struct sockaddr *)&isa,&addrlen);
1656         if (t == INVALID_SOCKET)
1657         {
1658           err = p_WSAGetLastError();
1659           if (err == WSATRY_AGAIN)
1660               break;
1661         }
1662 
1663         actx.p = (void *)t;
1664 
1665 #ifndef NO_IPV6
1666         if (isa.ss_family == AF_INET &&
1667             s->localhost_only &&
1668             !ipv4_is_local_addr(((struct sockaddr_in *)&isa)->sin_addr))
1669 #else
1670         if (s->localhost_only && !ipv4_is_local_addr(isa.sin_addr))
1671 #endif
1672         {
1673           p_closesocket(t);      /* dodgy WinSock let nonlocal through */
1674         } else if (plug_accepting(s->plug, sk_net_accept, actx)) {
1675           p_closesocket(t);      /* denied or error */
1676         }
1677         break;
1678       }
1679     }
1680 }
1681 
1682 /*
1683  * Special error values are returned from sk_namelookup and sk_new
1684  * if there's a problem. These functions extract an error message,
1685  * or return NULL if there's no problem.
1686  */
sk_addr_error(SockAddr * addr)1687 const char *sk_addr_error(SockAddr *addr)
1688 {
1689     return addr->error;
1690 }
sk_net_socket_error(Socket * sock)1691 static const char *sk_net_socket_error(Socket *sock)
1692 {
1693     NetSocket *s = container_of(sock, NetSocket, sock);
1694     return s->error;
1695 }
1696 
sk_net_peer_info(Socket * sock)1697 static SocketPeerInfo *sk_net_peer_info(Socket *sock)
1698 {
1699     NetSocket *s = container_of(sock, NetSocket, sock);
1700 #ifdef NO_IPV6
1701     struct sockaddr_in addr;
1702 #else
1703     struct sockaddr_storage addr;
1704     char buf[INET6_ADDRSTRLEN];
1705 #endif
1706     int addrlen = sizeof(addr);
1707     SocketPeerInfo *pi;
1708 
1709     if (p_getpeername(s->s, (struct sockaddr *)&addr, &addrlen) < 0)
1710         return NULL;
1711 
1712     pi = snew(SocketPeerInfo);
1713     pi->addressfamily = ADDRTYPE_UNSPEC;
1714     pi->addr_text = NULL;
1715     pi->port = -1;
1716     pi->log_text = NULL;
1717 
1718     if (((struct sockaddr *)&addr)->sa_family == AF_INET) {
1719         pi->addressfamily = ADDRTYPE_IPV4;
1720         memcpy(pi->addr_bin.ipv4, &((struct sockaddr_in *)&addr)->sin_addr, 4);
1721         pi->port = p_ntohs(((struct sockaddr_in *)&addr)->sin_port);
1722         pi->addr_text = dupstr(
1723             p_inet_ntoa(((struct sockaddr_in *)&addr)->sin_addr));
1724         pi->log_text = dupprintf("%s:%d", pi->addr_text, pi->port);
1725 
1726 #ifndef NO_IPV6
1727     } else if (((struct sockaddr *)&addr)->sa_family == AF_INET6) {
1728         pi->addressfamily = ADDRTYPE_IPV6;
1729         memcpy(pi->addr_bin.ipv6,
1730                &((struct sockaddr_in6 *)&addr)->sin6_addr, 16);
1731         pi->port = p_ntohs(((struct sockaddr_in6 *)&addr)->sin6_port);
1732         pi->addr_text = dupstr(
1733             p_inet_ntop(AF_INET6, &((struct sockaddr_in6 *)&addr)->sin6_addr,
1734                         buf, sizeof(buf)));
1735         pi->log_text = dupprintf("[%s]:%d", pi->addr_text, pi->port);
1736 
1737 #endif
1738     } else {
1739         sfree(pi);
1740         return NULL;
1741     }
1742 
1743     return pi;
1744 }
1745 
sk_net_set_frozen(Socket * sock,bool is_frozen)1746 static void sk_net_set_frozen(Socket *sock, bool is_frozen)
1747 {
1748     NetSocket *s = container_of(sock, NetSocket, sock);
1749     if (s->frozen == is_frozen)
1750         return;
1751     s->frozen = is_frozen;
1752     if (!is_frozen) {
1753         do_select(s->s, true);
1754         if (s->frozen_readable) {
1755             char c;
1756             p_recv(s->s, &c, 1, MSG_PEEK);
1757         }
1758     }
1759     s->frozen_readable = false;
1760 }
1761 
socket_reselect_all(void)1762 void socket_reselect_all(void)
1763 {
1764     NetSocket *s;
1765     int i;
1766 
1767     for (i = 0; (s = index234(sktree, i)) != NULL; i++) {
1768         if (!s->frozen)
1769             do_select(s->s, true);
1770     }
1771 }
1772 
1773 /*
1774  * For Plink: enumerate all sockets currently active.
1775  */
first_socket(int * state)1776 SOCKET first_socket(int *state)
1777 {
1778     NetSocket *s;
1779     *state = 0;
1780     s = index234(sktree, (*state)++);
1781     return s ? s->s : INVALID_SOCKET;
1782 }
1783 
next_socket(int * state)1784 SOCKET next_socket(int *state)
1785 {
1786     NetSocket *s = index234(sktree, (*state)++);
1787     return s ? s->s : INVALID_SOCKET;
1788 }
1789 
socket_writable(SOCKET skt)1790 bool socket_writable(SOCKET skt)
1791 {
1792     NetSocket *s = find234(sktree, (void *)skt, cmpforsearch);
1793 
1794     if (s)
1795         return bufchain_size(&s->output_data) > 0;
1796     else
1797         return false;
1798 }
1799 
net_service_lookup(char * service)1800 int net_service_lookup(char *service)
1801 {
1802     struct servent *se;
1803     se = p_getservbyname(service, NULL);
1804     if (se != NULL)
1805         return p_ntohs(se->s_port);
1806     else
1807         return 0;
1808 }
1809 
get_hostname(void)1810 char *get_hostname(void)
1811 {
1812     char hostbuf[256]; /* MSDN docs for gethostname() promise this is enough */
1813     if (p_gethostname(hostbuf, sizeof(hostbuf)) < 0)
1814         return NULL;
1815     return dupstr(hostbuf);
1816 }
1817 
platform_get_x11_unix_address(const char * display,int displaynum)1818 SockAddr *platform_get_x11_unix_address(const char *display, int displaynum)
1819 {
1820     SockAddr *ret = snew(SockAddr);
1821     memset(ret, 0, sizeof(SockAddr));
1822     ret->error = "unix sockets not supported on this platform";
1823     ret->refcount = 1;
1824     return ret;
1825 }
1826