No need to set variable to NULL
[TortoiseGit.git] / src / TortoisePlink / Windows / network.c
blob9f89e0fb78d5822161b47579facebcf962dcf8a3
1 /*
2 * Windows networking abstraction.
4 * For the IPv6 code in here I am indebted to Jeroen Massar and
5 * unfix.org.
6 */
8 #include <winsock2.h> /* need to put this first, for winelib builds */
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <assert.h>
14 #define NEED_DECLARATION_OF_SELECT /* in order to initialise it */
16 #include "putty.h"
17 #include "network.h"
18 #include "tree234.h"
19 #include "ssh.h"
21 #include <ws2tcpip.h>
23 #if HAVE_AFUNIX_H
24 #include <afunix.h>
25 #endif
27 #ifndef NO_IPV6
28 #ifdef __clang__
29 #pragma clang diagnostic push
30 #pragma clang diagnostic ignored "-Wmissing-braces"
31 #endif
32 const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
33 const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
34 #ifdef __clang__
35 #pragma clang diagnostic pop
36 #endif
37 #endif
39 #define ipv4_is_loopback(addr) \
40 ((p_ntohl(addr.s_addr) & 0xFF000000L) == 0x7F000000L)
43 * Mutable state that goes with a SockAddr: stores information
44 * about where in the list of candidate IP(v*) addresses we've
45 * currently got to.
47 typedef struct SockAddrStep_tag SockAddrStep;
48 struct SockAddrStep_tag {
49 #ifndef NO_IPV6
50 struct addrinfo *ai; /* steps along addr->ais */
51 #endif
52 int curraddr;
55 typedef struct NetSocket NetSocket;
56 struct NetSocket {
57 const char *error;
58 SOCKET s;
59 Plug *plug;
60 bufchain output_data;
61 bool connected;
62 bool writable;
63 bool frozen; /* this causes readability notifications to be ignored */
64 bool frozen_readable; /* this means we missed at least one readability
65 * notification while we were frozen */
66 bool localhost_only; /* for listening sockets */
67 char oobdata[1];
68 size_t sending_oob;
69 bool oobinline, nodelay, keepalive, privport;
70 enum { EOF_NO, EOF_PENDING, EOF_SENT } outgoingeof;
71 SockAddr *addr;
72 SockAddrStep step;
73 int port;
74 int pending_error; /* in case send() returns error */
76 * We sometimes need pairs of Socket structures to be linked:
77 * if we are listening on the same IPv6 and v4 port, for
78 * example. So here we define `parent' and `child' pointers to
79 * track this link.
81 NetSocket *parent, *child;
83 Socket sock;
87 * Top-level discriminator for SockAddr.
89 * UNRESOLVED means a host name not yet put through DNS; IP means a
90 * resolved IP address (or list of them); UNIX indicates the AF_UNIX
91 * network family (which Windows also has); NAMEDPIPE indicates that
92 * this SockAddr is phony, holding a Windows named pipe pathname
93 * instead of any address WinSock can understand.
95 typedef enum SuperFamily {
96 UNRESOLVED,
97 IP,
98 #if HAVE_AFUNIX_H
99 UNIX,
100 #endif
101 NAMEDPIPE
102 } SuperFamily;
104 struct SockAddr {
105 int refcount;
106 const char *error;
107 SuperFamily superfamily;
108 #ifndef NO_IPV6
109 struct addrinfo *ais; /* Addresses IPv6 style. */
110 #endif
111 unsigned long *addresses; /* Addresses IPv4 style. */
112 int naddresses;
113 char hostname[512]; /* Store an unresolved host name. */
117 * Which address family this address belongs to. AF_INET for IPv4;
118 * AF_INET6 for IPv6; AF_UNIX for Unix-domain sockets; AF_UNSPEC
119 * indicates that name resolution has not been done and a simple host
120 * name is held in this SockAddr structure.
122 static inline int sockaddr_family(SockAddr *addr, SockAddrStep step)
124 switch (addr->superfamily) {
125 case IP:
126 #ifndef NO_IPV6
127 if (step.ai)
128 return step.ai->ai_family;
129 #endif
130 return AF_INET;
131 #if HAVE_AFUNIX_H
132 case UNIX:
133 return AF_UNIX;
134 #endif
135 default:
136 return AF_UNSPEC;
141 * Start a SockAddrStep structure to step through multiple
142 * addresses.
144 #ifndef NO_IPV6
145 #define START_STEP(addr, step) \
146 ((step).ai = (addr)->ais, (step).curraddr = 0)
147 #else
148 #define START_STEP(addr, step) \
149 ((step).curraddr = 0)
150 #endif
152 static tree234 *sktree;
154 static int cmpfortree(void *av, void *bv)
156 NetSocket *a = (NetSocket *)av, *b = (NetSocket *)bv;
157 uintptr_t as = (uintptr_t) a->s, bs = (uintptr_t) b->s;
158 if (as < bs)
159 return -1;
160 if (as > bs)
161 return +1;
162 if (a < b)
163 return -1;
164 if (a > b)
165 return +1;
166 return 0;
169 static int cmpforsearch(void *av, void *bv)
171 NetSocket *b = (NetSocket *)bv;
172 uintptr_t as = (uintptr_t) av, bs = (uintptr_t) b->s;
173 if (as < bs)
174 return -1;
175 if (as > bs)
176 return +1;
177 return 0;
180 DECL_WINDOWS_FUNCTION(static, int, WSAStartup, (WORD, LPWSADATA));
181 DECL_WINDOWS_FUNCTION(static, int, WSACleanup, (void));
182 DECL_WINDOWS_FUNCTION(static, int, closesocket, (SOCKET));
183 DECL_WINDOWS_FUNCTION(static, ULONG, ntohl, (ULONG));
184 DECL_WINDOWS_FUNCTION(static, ULONG, htonl, (ULONG));
185 DECL_WINDOWS_FUNCTION(static, USHORT, htons, (USHORT));
186 DECL_WINDOWS_FUNCTION(static, USHORT, ntohs, (USHORT));
187 DECL_WINDOWS_FUNCTION(static, int, gethostname, (char *, int));
188 DECL_WINDOWS_FUNCTION(static, struct hostent FAR *, gethostbyname,
189 (const char FAR *));
190 DECL_WINDOWS_FUNCTION(static, struct servent FAR *, getservbyname,
191 (const char FAR *, const char FAR *));
192 DECL_WINDOWS_FUNCTION(static, ULONG, inet_addr, (const char FAR *));
193 DECL_WINDOWS_FUNCTION(static, char FAR *, inet_ntoa, (struct in_addr));
194 DECL_WINDOWS_FUNCTION(static, const char FAR *, inet_ntop,
195 (int, void FAR *, char *, size_t));
196 DECL_WINDOWS_FUNCTION(static, int, connect,
197 (SOCKET, const struct sockaddr FAR *, int));
198 DECL_WINDOWS_FUNCTION(static, int, bind,
199 (SOCKET, const struct sockaddr FAR *, int));
200 DECL_WINDOWS_FUNCTION(static, int, setsockopt,
201 (SOCKET, int, int, const char FAR *, int));
202 DECL_WINDOWS_FUNCTION(static, SOCKET, socket, (int, int, int));
203 DECL_WINDOWS_FUNCTION(static, int, listen, (SOCKET, int));
204 DECL_WINDOWS_FUNCTION(static, int, send, (SOCKET, const char FAR *, int, int));
205 DECL_WINDOWS_FUNCTION(static, int, shutdown, (SOCKET, int));
206 DECL_WINDOWS_FUNCTION(static, int, ioctlsocket,
207 (SOCKET, LONG, ULONG FAR *));
208 DECL_WINDOWS_FUNCTION(static, SOCKET, accept,
209 (SOCKET, struct sockaddr FAR *, int FAR *));
210 DECL_WINDOWS_FUNCTION(static, int, getpeername,
211 (SOCKET, struct sockaddr FAR *, int FAR *));
212 DECL_WINDOWS_FUNCTION(static, int, recv, (SOCKET, char FAR *, int, int));
213 DECL_WINDOWS_FUNCTION(static, int, WSAIoctl,
214 (SOCKET, DWORD, LPVOID, DWORD, LPVOID, DWORD,
215 LPDWORD, LPWSAOVERLAPPED,
216 LPWSAOVERLAPPED_COMPLETION_ROUTINE));
217 #ifndef NO_IPV6
218 DECL_WINDOWS_FUNCTION(static, int, getaddrinfo,
219 (const char *nodename, const char *servname,
220 const struct addrinfo *hints, struct addrinfo **res));
221 DECL_WINDOWS_FUNCTION(static, void, freeaddrinfo, (struct addrinfo *res));
222 DECL_WINDOWS_FUNCTION(static, int, getnameinfo,
223 (const struct sockaddr FAR *sa, socklen_t salen,
224 char FAR *host, DWORD hostlen, char FAR *serv,
225 DWORD servlen, int flags));
226 DECL_WINDOWS_FUNCTION(static, int, WSAAddressToStringA,
227 (LPSOCKADDR, DWORD, LPWSAPROTOCOL_INFO,
228 LPSTR, LPDWORD));
229 #endif
231 static HMODULE winsock_module = NULL;
232 static WSADATA wsadata;
233 #ifndef NO_IPV6
234 static HMODULE winsock2_module = NULL;
235 static HMODULE wship6_module = NULL;
236 #endif
238 static bool sk_startup(int hi, int lo)
240 WORD winsock_ver;
242 winsock_ver = MAKEWORD(hi, lo);
244 if (p_WSAStartup(winsock_ver, &wsadata)) {
245 return false;
248 if (LOBYTE(wsadata.wVersion) != LOBYTE(winsock_ver)) {
249 return false;
252 return true;
255 DEF_WINDOWS_FUNCTION(WSAAsyncSelect);
256 DEF_WINDOWS_FUNCTION(WSAEventSelect);
257 DEF_WINDOWS_FUNCTION(WSAGetLastError);
258 DEF_WINDOWS_FUNCTION(WSAEnumNetworkEvents);
259 DEF_WINDOWS_FUNCTION(select);
261 void sk_init(void)
263 #ifndef NO_IPV6
264 winsock2_module =
265 #endif
266 winsock_module = load_system32_dll("ws2_32.dll");
267 if (!winsock_module) {
268 winsock_module = load_system32_dll("wsock32.dll");
270 if (!winsock_module)
271 modalfatalbox("Unable to load any WinSock library");
273 #ifndef NO_IPV6
274 /* Check if we have getaddrinfo in Winsock */
275 if (GetProcAddress(winsock_module, "getaddrinfo") != NULL) {
276 GET_WINDOWS_FUNCTION(winsock_module, getaddrinfo);
277 GET_WINDOWS_FUNCTION(winsock_module, freeaddrinfo);
278 GET_WINDOWS_FUNCTION_NO_TYPECHECK(winsock_module, getnameinfo);
279 /* This function would fail its type-check if we did one,
280 * because the VS header file provides an inline definition
281 * which is __cdecl instead of WINAPI. */
282 } else {
283 /* Fall back to wship6.dll for Windows 2000 */
284 wship6_module = load_system32_dll("wship6.dll");
285 if (wship6_module) {
286 GET_WINDOWS_FUNCTION(wship6_module, getaddrinfo);
287 GET_WINDOWS_FUNCTION(wship6_module, freeaddrinfo);
288 /* See comment above about type check */
289 GET_WINDOWS_FUNCTION_NO_TYPECHECK(wship6_module, getnameinfo);
290 } else {
293 GET_WINDOWS_FUNCTION(winsock2_module, WSAAddressToStringA);
294 #endif
296 GET_WINDOWS_FUNCTION(winsock_module, WSAAsyncSelect);
297 GET_WINDOWS_FUNCTION(winsock_module, WSAEventSelect);
298 /* We don't type-check select because at least some MinGW versions
299 * of the Windows API headers seem to disagree with the
300 * documentation on whether the 'struct timeval *' pointer is
301 * const or not. */
302 GET_WINDOWS_FUNCTION_NO_TYPECHECK(winsock_module, select);
303 GET_WINDOWS_FUNCTION(winsock_module, WSAGetLastError);
304 GET_WINDOWS_FUNCTION(winsock_module, WSAEnumNetworkEvents);
305 GET_WINDOWS_FUNCTION(winsock_module, WSAStartup);
306 GET_WINDOWS_FUNCTION(winsock_module, WSACleanup);
307 GET_WINDOWS_FUNCTION(winsock_module, closesocket);
308 /* Winelib maps ntohl and friends to things like
309 * __wine_ulong_swap, which fail these type checks hopelessly */
310 GET_WINDOWS_FUNCTION_NO_TYPECHECK(winsock_module, ntohl);
311 GET_WINDOWS_FUNCTION_NO_TYPECHECK(winsock_module, htonl);
312 GET_WINDOWS_FUNCTION_NO_TYPECHECK(winsock_module, htons);
313 GET_WINDOWS_FUNCTION_NO_TYPECHECK(winsock_module, ntohs);
314 GET_WINDOWS_FUNCTION_NO_TYPECHECK(winsock_module, gethostname);
315 GET_WINDOWS_FUNCTION(winsock_module, gethostbyname);
316 GET_WINDOWS_FUNCTION(winsock_module, getservbyname);
317 GET_WINDOWS_FUNCTION(winsock_module, inet_addr);
318 GET_WINDOWS_FUNCTION(winsock_module, inet_ntoa);
319 /* Older Visual Studio, and MinGW as of Ubuntu 16.04, don't know
320 * about this function at all, so can't type-check it. Also there
321 * seems to be some disagreement in the VS headers about whether
322 * the second argument is void * or const void *, so I omit the
323 * type check. */
324 GET_WINDOWS_FUNCTION_NO_TYPECHECK(winsock_module, inet_ntop);
325 GET_WINDOWS_FUNCTION(winsock_module, connect);
326 GET_WINDOWS_FUNCTION(winsock_module, bind);
327 GET_WINDOWS_FUNCTION(winsock_module, setsockopt);
328 GET_WINDOWS_FUNCTION(winsock_module, socket);
329 GET_WINDOWS_FUNCTION(winsock_module, listen);
330 GET_WINDOWS_FUNCTION(winsock_module, send);
331 GET_WINDOWS_FUNCTION(winsock_module, shutdown);
332 GET_WINDOWS_FUNCTION(winsock_module, ioctlsocket);
333 GET_WINDOWS_FUNCTION(winsock_module, accept);
334 GET_WINDOWS_FUNCTION(winsock_module, getpeername);
335 GET_WINDOWS_FUNCTION(winsock_module, recv);
336 GET_WINDOWS_FUNCTION(winsock_module, WSAIoctl);
338 /* Try to get the best WinSock version we can get */
339 if (!sk_startup(2,2) &&
340 !sk_startup(2,0) &&
341 !sk_startup(1,1)) {
342 modalfatalbox("Unable to initialise WinSock");
345 sktree = newtree234(cmpfortree);
348 void sk_cleanup(void)
350 NetSocket *s;
351 int i;
353 if (sktree) {
354 for (i = 0; (s = index234(sktree, i)) != NULL; i++) {
355 p_closesocket(s->s);
357 freetree234(sktree);
358 sktree = NULL;
361 if (p_WSACleanup)
362 p_WSACleanup();
363 if (winsock_module)
364 FreeLibrary(winsock_module);
365 #ifndef NO_IPV6
366 if (wship6_module)
367 FreeLibrary(wship6_module);
368 #endif
371 const char *winsock_error_string(int error)
374 * Error codes we know about and have historically had reasonably
375 * sensible error messages for.
377 switch (error) {
378 case WSAEACCES:
379 return "Network error: Permission denied";
380 case WSAEADDRINUSE:
381 return "Network error: Address already in use";
382 case WSAEADDRNOTAVAIL:
383 return "Network error: Cannot assign requested address";
384 case WSAEAFNOSUPPORT:
385 return
386 "Network error: Address family not supported by protocol family";
387 case WSAEALREADY:
388 return "Network error: Operation already in progress";
389 case WSAECONNABORTED:
390 return "Network error: Software caused connection abort";
391 case WSAECONNREFUSED:
392 return "Network error: Connection refused";
393 case WSAECONNRESET:
394 return "Network error: Connection reset by peer";
395 case WSAEDESTADDRREQ:
396 return "Network error: Destination address required";
397 case WSAEFAULT:
398 return "Network error: Bad address";
399 case WSAEHOSTDOWN:
400 return "Network error: Host is down";
401 case WSAEHOSTUNREACH:
402 return "Network error: No route to host";
403 case WSAEINPROGRESS:
404 return "Network error: Operation now in progress";
405 case WSAEINTR:
406 return "Network error: Interrupted function call";
407 case WSAEINVAL:
408 return "Network error: Invalid argument";
409 case WSAEISCONN:
410 return "Network error: Socket is already connected";
411 case WSAEMFILE:
412 return "Network error: Too many open files";
413 case WSAEMSGSIZE:
414 return "Network error: Message too long";
415 case WSAENETDOWN:
416 return "Network error: Network is down";
417 case WSAENETRESET:
418 return "Network error: Network dropped connection on reset";
419 case WSAENETUNREACH:
420 return "Network error: Network is unreachable";
421 case WSAENOBUFS:
422 return "Network error: No buffer space available";
423 case WSAENOPROTOOPT:
424 return "Network error: Bad protocol option";
425 case WSAENOTCONN:
426 return "Network error: Socket is not connected";
427 case WSAENOTSOCK:
428 return "Network error: Socket operation on non-socket";
429 case WSAEOPNOTSUPP:
430 return "Network error: Operation not supported";
431 case WSAEPFNOSUPPORT:
432 return "Network error: Protocol family not supported";
433 case WSAEPROCLIM:
434 return "Network error: Too many processes";
435 case WSAEPROTONOSUPPORT:
436 return "Network error: Protocol not supported";
437 case WSAEPROTOTYPE:
438 return "Network error: Protocol wrong type for socket";
439 case WSAESHUTDOWN:
440 return "Network error: Cannot send after socket shutdown";
441 case WSAESOCKTNOSUPPORT:
442 return "Network error: Socket type not supported";
443 case WSAETIMEDOUT:
444 return "Network error: Connection timed out";
445 case WSAEWOULDBLOCK:
446 return "Network error: Resource temporarily unavailable";
447 case WSAEDISCON:
448 return "Network error: Graceful shutdown in progress";
452 * Handle any other error code by delegating to win_strerror.
454 return win_strerror(error);
457 static inline const char *namelookup_strerror(DWORD err)
459 /* PuTTY has traditionally translated a few of the likely error
460 * messages into more concise strings than the standard Windows ones */
461 return (err == WSAENETDOWN ? "Network is down" :
462 err == WSAHOST_NOT_FOUND ? "Host does not exist" :
463 err == WSATRY_AGAIN ? "Host not found" :
464 win_strerror(err));
467 SockAddr *sk_namelookup(const char *host, char **canonicalname,
468 int address_family)
470 *canonicalname = NULL;
472 SockAddr *addr = snew(SockAddr);
473 memset(addr, 0, sizeof(SockAddr));
474 addr->superfamily = UNRESOLVED;
475 addr->refcount = 1;
477 #ifndef NO_IPV6
479 * Use getaddrinfo, as long as it's available. This should handle
480 * both IPv4 and IPv6 address literals, and hostnames, in one
481 * unified API.
483 if (p_getaddrinfo) {
484 struct addrinfo hints;
485 memset(&hints, 0, sizeof(hints));
486 hints.ai_family = (address_family == ADDRTYPE_IPV4 ? AF_INET :
487 address_family == ADDRTYPE_IPV6 ? AF_INET6 :
488 AF_UNSPEC);
489 hints.ai_flags = AI_CANONNAME;
490 hints.ai_socktype = SOCK_STREAM;
492 /* strip [] on IPv6 address literals */
493 char *trimmed_host = host_strduptrim(host);
494 int err = p_getaddrinfo(trimmed_host, NULL, &hints, &addr->ais);
495 sfree(trimmed_host);
497 if (addr->ais) {
498 addr->superfamily = IP;
499 if (addr->ais->ai_canonname)
500 *canonicalname = dupstr(addr->ais->ai_canonname);
501 else
502 *canonicalname = dupstr(host);
503 } else {
504 addr->error = namelookup_strerror(err);
506 return addr;
508 #endif
511 * Failing that (if IPv6 support was not compiled in, or if
512 * getaddrinfo turned out to be unavailable at run time), try the
513 * old-fashioned approach, which is to start by manually checking
514 * for an IPv4 literal and then use gethostbyname.
516 unsigned long a = p_inet_addr(host);
517 if (a != (unsigned long) INADDR_NONE) {
518 addr->addresses = snew(unsigned long);
519 addr->naddresses = 1;
520 addr->addresses[0] = p_ntohl(a);
521 addr->superfamily = IP;
522 *canonicalname = dupstr(host);
523 return addr;
526 struct hostent *h = p_gethostbyname(host);
527 if (h) {
528 addr->superfamily = IP;
530 size_t n;
531 for (n = 0; h->h_addr_list[n]; n++);
532 addr->addresses = snewn(n, unsigned long);
533 addr->naddresses = n;
534 for (n = 0; n < addr->naddresses; n++) {
535 uint32_t a;
536 memcpy(&a, h->h_addr_list[n], sizeof(a));
537 addr->addresses[n] = p_ntohl(a);
540 *canonicalname = dupstr(h->h_name);
541 } else {
542 DWORD err = p_WSAGetLastError();
543 addr->error = namelookup_strerror(err);
545 return addr;
548 static SockAddr *sk_special_addr(SuperFamily superfamily, const char *name)
550 SockAddr *ret = snew(SockAddr);
551 ret->error = NULL;
552 ret->superfamily = superfamily;
553 #ifndef NO_IPV6
554 ret->ais = NULL;
555 #endif
556 ret->addresses = NULL;
557 ret->naddresses = 0;
558 ret->refcount = 1;
559 strncpy(ret->hostname, name, lenof(ret->hostname));
560 ret->hostname[lenof(ret->hostname)-1] = '\0';
561 return ret;
564 SockAddr *sk_nonamelookup(const char *host)
566 return sk_special_addr(UNRESOLVED, host);
569 SockAddr *sk_namedpipe_addr(const char *pipename)
571 return sk_special_addr(NAMEDPIPE, pipename);
574 #if HAVE_AFUNIX_H
575 SockAddr *sk_unix_addr(const char *sockpath)
577 return sk_special_addr(UNIX, sockpath);
579 #endif
581 static bool sk_nextaddr(SockAddr *addr, SockAddrStep *step)
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;
591 #endif
592 if (step->curraddr+1 < addr->naddresses) {
593 step->curraddr++;
594 return true;
595 } else {
596 return false;
600 void sk_getaddr(SockAddr *addr, char *buf, int buflen)
602 SockAddrStep step;
603 START_STEP(addr, step);
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';
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';
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.)
643 static SockAddr sk_extractaddr_tmp(
644 SockAddr *addr, const SockAddrStep *step)
646 SockAddr toret;
647 toret = *addr; /* structure copy */
648 toret.refcount = 1;
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
658 toret.addresses += step->curraddr;
660 return toret;
663 bool sk_addr_needs_port(SockAddr *addr)
665 return addr->superfamily != NAMEDPIPE
666 #if HAVE_AFUNIX_H
667 && addr->superfamily != UNIX
668 #endif
672 bool sk_hostname_is_local(const char *name)
674 return !strcmp(name, "localhost") ||
675 !strcmp(name, "::1") ||
676 !strncmp(name, "127.", 4);
679 static INTERFACE_INFO local_interfaces[16];
680 static int n_local_interfaces; /* 0=not yet, -1=failed, >0=number */
682 static bool ipv4_is_local_addr(struct in_addr addr)
684 if (ipv4_is_loopback(addr))
685 return true; /* loopback addresses are local */
686 if (!n_local_interfaces) {
687 SOCKET s = p_socket(AF_INET, SOCK_DGRAM, 0);
688 DWORD retbytes;
690 SetHandleInformation((HANDLE)s, HANDLE_FLAG_INHERIT, 0);
692 if (p_WSAIoctl &&
693 p_WSAIoctl(s, SIO_GET_INTERFACE_LIST, NULL, 0,
694 local_interfaces, sizeof(local_interfaces),
695 &retbytes, NULL, NULL) == 0)
696 n_local_interfaces = retbytes / sizeof(INTERFACE_INFO);
697 else
698 n_local_interfaces = -1;
700 if (n_local_interfaces > 0) {
701 int i;
702 for (i = 0; i < n_local_interfaces; i++) {
703 SOCKADDR_IN *address =
704 (SOCKADDR_IN *)&local_interfaces[i].iiAddress;
705 if (address->sin_addr.s_addr == addr.s_addr)
706 return true; /* this address is local */
709 return false; /* this address is not local */
712 bool sk_address_is_local(SockAddr *addr)
714 SockAddrStep step;
715 int family;
716 START_STEP(addr, step);
717 family = sockaddr_family(addr, step);
719 #ifndef NO_IPV6
720 if (family == AF_INET6) {
721 return IN6_IS_ADDR_LOOPBACK(&((const struct sockaddr_in6 *)step.ai->ai_addr)->sin6_addr);
722 } else
723 #endif
724 if (family == AF_INET) {
725 #ifndef NO_IPV6
726 if (step.ai) {
727 return ipv4_is_local_addr(((struct sockaddr_in *)step.ai->ai_addr)
728 ->sin_addr);
729 } else
730 #endif
732 struct in_addr a;
733 assert(addr->addresses && step.curraddr < addr->naddresses);
734 a.s_addr = p_htonl(addr->addresses[step.curraddr]);
735 return ipv4_is_local_addr(a);
737 } else {
738 assert(family == AF_UNSPEC);
739 return false; /* we don't know; assume not */
743 bool sk_address_is_special_local(SockAddr *addr)
745 return false; /* no Unix-domain socket analogue here */
748 int sk_addrtype(SockAddr *addr)
750 SockAddrStep step;
751 int family;
752 START_STEP(addr, step);
753 family = sockaddr_family(addr, step);
755 return (family == AF_INET ? ADDRTYPE_IPV4 :
756 #ifndef NO_IPV6
757 family == AF_INET6 ? ADDRTYPE_IPV6 :
758 #endif
759 ADDRTYPE_NAME);
762 void sk_addrcopy(SockAddr *addr, char *buf)
764 SockAddrStep step;
765 int family;
766 START_STEP(addr, step);
767 family = sockaddr_family(addr, step);
769 assert(family != AF_UNSPEC);
770 #ifndef NO_IPV6
771 if (step.ai) {
772 if (family == AF_INET)
773 memcpy(buf, &((struct sockaddr_in *)step.ai->ai_addr)->sin_addr,
774 sizeof(struct in_addr));
775 else if (family == AF_INET6)
776 memcpy(buf, &((struct sockaddr_in6 *)step.ai->ai_addr)->sin6_addr,
777 sizeof(struct in6_addr));
778 else
779 unreachable("bad address family in sk_addrcopy");
780 } else
781 #endif
782 if (family == AF_INET) {
783 struct in_addr a;
784 assert(addr->addresses && step.curraddr < addr->naddresses);
785 a.s_addr = p_htonl(addr->addresses[step.curraddr]);
786 memcpy(buf, (char*) &a.s_addr, 4);
790 void sk_addr_free(SockAddr *addr)
792 if (--addr->refcount > 0)
793 return;
794 #ifndef NO_IPV6
795 if (addr->ais && p_freeaddrinfo)
796 p_freeaddrinfo(addr->ais);
797 #endif
798 if (addr->addresses)
799 sfree(addr->addresses);
800 sfree(addr);
803 SockAddr *sk_addr_dup(SockAddr *addr)
805 addr->refcount++;
806 return addr;
809 static Plug *sk_net_plug(Socket *sock, Plug *p)
811 NetSocket *s = container_of(sock, NetSocket, sock);
812 Plug *ret = s->plug;
813 if (p)
814 s->plug = p;
815 return ret;
818 static void sk_net_close(Socket *s);
819 static size_t sk_net_write(Socket *s, const void *data, size_t len);
820 static size_t sk_net_write_oob(Socket *s, const void *data, size_t len);
821 static void sk_net_write_eof(Socket *s);
822 static void sk_net_set_frozen(Socket *s, bool is_frozen);
823 static const char *sk_net_socket_error(Socket *s);
824 static SocketPeerInfo *sk_net_peer_info(Socket *s);
826 static const SocketVtable NetSocket_sockvt = {
827 .plug = sk_net_plug,
828 .close = sk_net_close,
829 .write = sk_net_write,
830 .write_oob = sk_net_write_oob,
831 .write_eof = sk_net_write_eof,
832 .set_frozen = sk_net_set_frozen,
833 .socket_error = sk_net_socket_error,
834 .peer_info = sk_net_peer_info,
837 static Socket *sk_net_accept(accept_ctx_t ctx, Plug *plug)
839 DWORD err;
840 const char *errstr;
841 NetSocket *ret;
844 * Create NetSocket structure.
846 ret = snew(NetSocket);
847 ret->sock.vt = &NetSocket_sockvt;
848 ret->error = NULL;
849 ret->plug = plug;
850 bufchain_init(&ret->output_data);
851 ret->writable = true; /* to start with */
852 ret->sending_oob = 0;
853 ret->outgoingeof = EOF_NO;
854 ret->frozen = true;
855 ret->frozen_readable = false;
856 ret->localhost_only = false; /* unused, but best init anyway */
857 ret->pending_error = 0;
858 ret->parent = ret->child = NULL;
859 ret->addr = NULL;
861 ret->s = (SOCKET)ctx.p;
863 if (ret->s == INVALID_SOCKET) {
864 err = p_WSAGetLastError();
865 ret->error = winsock_error_string(err);
866 return &ret->sock;
869 ret->oobinline = false;
871 /* Set up a select mechanism. This could be an AsyncSelect on a
872 * window, or an EventSelect on an event object. */
873 errstr = do_select(ret->s, true);
874 if (errstr) {
875 ret->error = errstr;
876 return &ret->sock;
879 add234(sktree, ret);
881 return &ret->sock;
884 static DWORD try_connect(NetSocket *sock)
886 SOCKET s;
887 #ifndef NO_IPV6
888 SOCKADDR_IN6 a6;
889 #endif
890 SOCKADDR_IN a;
891 DWORD err;
892 const char *errstr;
893 short localport;
894 int family;
896 if (sock->s != INVALID_SOCKET) {
897 do_select(sock->s, false);
898 p_closesocket(sock->s);
902 SockAddr thisaddr = sk_extractaddr_tmp(
903 sock->addr, &sock->step);
904 plug_log(sock->plug, PLUGLOG_CONNECT_TRYING,
905 &thisaddr, sock->port, NULL, 0);
909 * Open socket.
911 family = sockaddr_family(sock->addr, sock->step);
914 * Remove the socket from the tree before we overwrite its
915 * internal socket id, because that forms part of the tree's
916 * sorting criterion. We'll add it back before exiting this
917 * function, whether we changed anything or not.
919 del234(sktree, sock);
921 s = p_socket(family, SOCK_STREAM, 0);
922 sock->s = s;
924 if (s == INVALID_SOCKET) {
925 err = p_WSAGetLastError();
926 sock->error = winsock_error_string(err);
927 goto ret;
930 SetHandleInformation((HANDLE)s, HANDLE_FLAG_INHERIT, 0);
932 if (sock->oobinline) {
933 BOOL b = true;
934 p_setsockopt(s, SOL_SOCKET, SO_OOBINLINE, (void *) &b, sizeof(b));
937 if (sock->nodelay) {
938 BOOL b = true;
939 p_setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (void *) &b, sizeof(b));
942 if (sock->keepalive) {
943 BOOL b = true;
944 p_setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (void *) &b, sizeof(b));
948 * Bind to local address.
950 if (sock->privport)
951 localport = 1023; /* count from 1023 downwards */
952 else
953 localport = 0; /* just use port 0 (ie winsock picks) */
955 /* Loop round trying to bind */
956 while (1) {
957 int sockcode;
959 #ifndef NO_IPV6
960 if (family == AF_INET6) {
961 memset(&a6, 0, sizeof(a6));
962 a6.sin6_family = AF_INET6;
963 /*a6.sin6_addr = in6addr_any; */ /* == 0 done by memset() */
964 a6.sin6_port = p_htons(localport);
965 } else
966 #endif
968 a.sin_family = AF_INET;
969 a.sin_addr.s_addr = p_htonl(INADDR_ANY);
970 a.sin_port = p_htons(localport);
972 #ifndef NO_IPV6
973 sockcode = p_bind(s, (family == AF_INET6 ?
974 (struct sockaddr *) &a6 :
975 (struct sockaddr *) &a),
976 (family == AF_INET6 ? sizeof(a6) : sizeof(a)));
977 #else
978 sockcode = p_bind(s, (struct sockaddr *) &a, sizeof(a));
979 #endif
980 if (sockcode != SOCKET_ERROR) {
981 err = 0;
982 break; /* done */
983 } else {
984 err = p_WSAGetLastError();
985 if (err != WSAEADDRINUSE) /* failed, for a bad reason */
986 break;
989 if (localport == 0)
990 break; /* we're only looping once */
991 localport--;
992 if (localport == 0)
993 break; /* we might have got to the end */
996 if (err) {
997 sock->error = winsock_error_string(err);
998 goto ret;
1002 * Connect to remote address.
1004 #ifndef NO_IPV6
1005 if (sock->step.ai) {
1006 if (family == AF_INET6) {
1007 a6.sin6_family = AF_INET6;
1008 a6.sin6_port = p_htons((short) sock->port);
1009 a6.sin6_addr =
1010 ((struct sockaddr_in6 *) sock->step.ai->ai_addr)->sin6_addr;
1011 a6.sin6_flowinfo = ((struct sockaddr_in6 *) sock->step.ai->ai_addr)->sin6_flowinfo;
1012 a6.sin6_scope_id = ((struct sockaddr_in6 *) sock->step.ai->ai_addr)->sin6_scope_id;
1013 } else {
1014 a.sin_family = AF_INET;
1015 a.sin_addr =
1016 ((struct sockaddr_in *) sock->step.ai->ai_addr)->sin_addr;
1017 a.sin_port = p_htons((short) sock->port);
1019 } else
1020 #endif
1022 assert(sock->addr->addresses && sock->step.curraddr < sock->addr->naddresses);
1023 a.sin_family = AF_INET;
1024 a.sin_addr.s_addr = p_htonl(sock->addr->addresses[sock->step.curraddr]);
1025 a.sin_port = p_htons((short) sock->port);
1028 /* Set up a select mechanism. This could be an AsyncSelect on a
1029 * window, or an EventSelect on an event object. */
1030 errstr = do_select(s, true);
1031 if (errstr) {
1032 sock->error = errstr;
1033 err = 1;
1034 goto ret;
1037 if ((
1038 #ifndef NO_IPV6
1039 p_connect(s,
1040 ((family == AF_INET6) ? (struct sockaddr *) &a6 :
1041 (struct sockaddr *) &a),
1042 (family == AF_INET6) ? sizeof(a6) : sizeof(a))
1043 #else
1044 p_connect(s, (struct sockaddr *) &a, sizeof(a))
1045 #endif
1046 ) == SOCKET_ERROR) {
1047 err = p_WSAGetLastError();
1049 * We expect a potential EWOULDBLOCK here, because the
1050 * chances are the front end has done a select for
1051 * FD_CONNECT, so that connect() will complete
1052 * asynchronously.
1054 if ( err != WSAEWOULDBLOCK ) {
1055 sock->error = winsock_error_string(err);
1056 goto ret;
1058 } else {
1060 * If we _don't_ get EWOULDBLOCK, the connect has completed
1061 * and we should set the socket as writable.
1063 sock->writable = true;
1064 SockAddr thisaddr = sk_extractaddr_tmp(sock->addr, &sock->step);
1065 plug_log(sock->plug, PLUGLOG_CONNECT_SUCCESS,
1066 &thisaddr, sock->port, NULL, 0);
1069 err = 0;
1071 ret:
1074 * No matter what happened, put the socket back in the tree.
1076 add234(sktree, sock);
1078 if (err) {
1079 SockAddr thisaddr = sk_extractaddr_tmp(
1080 sock->addr, &sock->step);
1081 plug_log(sock->plug, PLUGLOG_CONNECT_FAILED,
1082 &thisaddr, sock->port, sock->error, err);
1084 return err;
1087 Socket *sk_new(SockAddr *addr, int port, bool privport, bool oobinline,
1088 bool nodelay, bool keepalive, Plug *plug)
1090 NetSocket *ret;
1091 DWORD err;
1094 * Create NetSocket structure.
1096 ret = snew(NetSocket);
1097 ret->sock.vt = &NetSocket_sockvt;
1098 ret->error = NULL;
1099 ret->plug = plug;
1100 bufchain_init(&ret->output_data);
1101 ret->connected = false; /* to start with */
1102 ret->writable = false; /* to start with */
1103 ret->sending_oob = 0;
1104 ret->outgoingeof = EOF_NO;
1105 ret->frozen = false;
1106 ret->frozen_readable = false;
1107 ret->localhost_only = false; /* unused, but best init anyway */
1108 ret->pending_error = 0;
1109 ret->parent = ret->child = NULL;
1110 ret->oobinline = oobinline;
1111 ret->nodelay = nodelay;
1112 ret->keepalive = keepalive;
1113 ret->privport = privport;
1114 ret->port = port;
1115 ret->addr = addr;
1116 START_STEP(ret->addr, ret->step);
1117 ret->s = INVALID_SOCKET;
1119 err = 0;
1120 do {
1121 err = try_connect(ret);
1122 } while (err && sk_nextaddr(ret->addr, &ret->step));
1124 return &ret->sock;
1127 static Socket *sk_newlistener_internal(
1128 const char *srcaddr, int port, Plug *plug,
1129 bool local_host_only, int orig_address_family)
1131 SOCKET s;
1132 SOCKADDR_IN a;
1133 #ifndef NO_IPV6
1134 SOCKADDR_IN6 a6;
1135 #endif
1136 #if HAVE_AFUNIX_H
1137 SOCKADDR_UN au;
1138 #endif
1139 struct sockaddr *bindaddr;
1140 unsigned bindsize;
1142 DWORD err;
1143 const char *errstr;
1144 NetSocket *ret;
1145 int retcode;
1147 int address_family = orig_address_family;
1150 * Create NetSocket structure.
1152 ret = snew(NetSocket);
1153 ret->sock.vt = &NetSocket_sockvt;
1154 ret->error = NULL;
1155 ret->plug = plug;
1156 bufchain_init(&ret->output_data);
1157 ret->writable = false; /* to start with */
1158 ret->sending_oob = 0;
1159 ret->outgoingeof = EOF_NO;
1160 ret->frozen = false;
1161 ret->frozen_readable = false;
1162 ret->localhost_only = local_host_only;
1163 ret->pending_error = 0;
1164 ret->parent = ret->child = NULL;
1165 ret->addr = NULL;
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.
1174 if (address_family == AF_UNSPEC) address_family = AF_INET;
1177 * Open socket.
1179 s = p_socket(address_family, SOCK_STREAM, 0);
1180 ret->s = s;
1182 if (s == INVALID_SOCKET) {
1183 err = p_WSAGetLastError();
1184 ret->error = winsock_error_string(err);
1185 return &ret->sock;
1188 SetHandleInformation((HANDLE)s, HANDLE_FLAG_INHERIT, 0);
1190 ret->oobinline = false;
1192 #if HAVE_AFUNIX_H
1193 if (address_family != AF_UNIX)
1194 #endif
1196 BOOL on = true;
1197 p_setsockopt(s, SOL_SOCKET, SO_EXCLUSIVEADDRUSE,
1198 (const char *)&on, sizeof(on));
1201 switch (address_family) {
1202 #ifndef NO_IPV6
1203 case AF_INET6: {
1204 memset(&a6, 0, sizeof(a6));
1205 a6.sin6_family = AF_INET6;
1206 if (local_host_only)
1207 a6.sin6_addr = in6addr_loopback;
1208 else
1209 a6.sin6_addr = in6addr_any;
1210 if (srcaddr != NULL && p_getaddrinfo) {
1211 struct addrinfo hints;
1212 struct addrinfo *ai;
1213 int err;
1215 memset(&hints, 0, sizeof(hints));
1216 hints.ai_family = AF_INET6;
1217 hints.ai_flags = 0;
1219 /* strip [] on IPv6 address literals */
1220 char *trimmed_addr = host_strduptrim(srcaddr);
1221 err = p_getaddrinfo(trimmed_addr, NULL, &hints, &ai);
1222 sfree(trimmed_addr);
1224 if (err == 0 && ai->ai_family == AF_INET6) {
1225 a6.sin6_addr =
1226 ((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr;
1229 a6.sin6_port = p_htons(port);
1230 bindaddr = (struct sockaddr *)&a6;
1231 bindsize = sizeof(a6);
1232 break;
1234 #endif
1235 case AF_INET: {
1236 bool got_addr = false;
1237 a.sin_family = AF_INET;
1240 * Bind to source address. First try an explicitly
1241 * specified one...
1243 if (srcaddr) {
1244 a.sin_addr.s_addr = p_inet_addr(srcaddr);
1245 if (a.sin_addr.s_addr != INADDR_NONE) {
1246 /* Override localhost_only with specified listen addr. */
1247 ret->localhost_only = ipv4_is_loopback(a.sin_addr);
1248 got_addr = true;
1253 * ... and failing that, go with one of the standard ones.
1255 if (!got_addr) {
1256 if (local_host_only)
1257 a.sin_addr.s_addr = p_htonl(INADDR_LOOPBACK);
1258 else
1259 a.sin_addr.s_addr = p_htonl(INADDR_ANY);
1262 a.sin_port = p_htons((short)port);
1263 bindaddr = (struct sockaddr *)&a;
1264 bindsize = sizeof(a);
1265 break;
1267 #if HAVE_AFUNIX_H
1268 case AF_UNIX: {
1269 au.sun_family = AF_UNIX;
1270 strncpy(au.sun_path, srcaddr, sizeof(au.sun_path));
1271 bindaddr = (struct sockaddr *)&au;
1272 bindsize = sizeof(au);
1273 break;
1275 #endif
1276 default:
1277 unreachable("bad address family in sk_newlistener_internal");
1280 retcode = p_bind(s, bindaddr, bindsize);
1281 if (retcode != SOCKET_ERROR) {
1282 err = 0;
1283 } else {
1284 err = p_WSAGetLastError();
1287 if (err) {
1288 p_closesocket(s);
1289 ret->error = winsock_error_string(err);
1290 return &ret->sock;
1294 if (p_listen(s, SOMAXCONN) == SOCKET_ERROR) {
1295 p_closesocket(s);
1296 ret->error = winsock_error_string(p_WSAGetLastError());
1297 return &ret->sock;
1300 /* Set up a select mechanism. This could be an AsyncSelect on a
1301 * window, or an EventSelect on an event object. */
1302 errstr = do_select(s, true);
1303 if (errstr) {
1304 p_closesocket(s);
1305 ret->error = errstr;
1306 return &ret->sock;
1309 add234(sktree, ret);
1311 #ifndef NO_IPV6
1313 * If we were given ADDRTYPE_UNSPEC, we must also create an
1314 * IPv6 listening socket and link it to this one.
1316 if (address_family == AF_INET && orig_address_family == AF_UNSPEC) {
1317 Socket *other = sk_newlistener_internal(srcaddr, port, plug,
1318 local_host_only, AF_INET6);
1320 if (other) {
1321 NetSocket *ns = container_of(other, NetSocket, sock);
1322 if (!ns->error) {
1323 ns->parent = ret;
1324 ret->child = ns;
1325 } else {
1326 sfree(ns);
1330 #endif
1332 return &ret->sock;
1335 Socket *sk_newlistener(const char *srcaddr, int port, Plug *plug,
1336 bool local_host_only, int orig_address_family)
1339 * Translate address_family from platform-independent constants
1340 * into local reality.
1342 int address_family = (orig_address_family == ADDRTYPE_IPV4 ? AF_INET :
1343 #ifndef NO_IPV6
1344 orig_address_family == ADDRTYPE_IPV6 ? AF_INET6 :
1345 #endif
1346 AF_UNSPEC);
1348 return sk_newlistener_internal(srcaddr, port, plug, local_host_only,
1349 address_family);
1352 Socket *sk_newlistener_unix(const char *path, Plug *plug)
1354 #if HAVE_AFUNIX_H
1355 return sk_newlistener_internal(path, 0, plug, false, AF_UNIX);
1356 #else
1357 return new_error_socket_fmt(
1358 plug, "AF_UNIX support not compiled into this program");
1359 #endif
1362 static void sk_net_close(Socket *sock)
1364 NetSocket *s = container_of(sock, NetSocket, sock);
1366 if (s->child)
1367 sk_net_close(&s->child->sock);
1369 bufchain_clear(&s->output_data);
1371 del234(sktree, s);
1372 do_select(s->s, false);
1373 p_closesocket(s->s);
1374 if (s->addr)
1375 sk_addr_free(s->addr);
1376 delete_callbacks_for_context(s);
1377 sfree(s);
1380 void plug_closing_system_error(Plug *plug, DWORD error)
1382 PlugCloseType type = PLUGCLOSE_ERROR;
1383 if (error == ERROR_BROKEN_PIPE)
1384 type = PLUGCLOSE_BROKEN_PIPE;
1385 plug_closing(plug, type, win_strerror(error));
1388 void plug_closing_winsock_error(Plug *plug, DWORD error)
1390 plug_closing(plug, PLUGCLOSE_ERROR, winsock_error_string(error));
1394 * Deal with socket errors detected in try_send().
1396 static void socket_error_callback(void *vs)
1398 NetSocket *s = (NetSocket *)vs;
1401 * Just in case other socket work has caused this socket to vanish
1402 * or become somehow non-erroneous before this callback arrived...
1404 if (!find234(sktree, s, NULL) || !s->pending_error)
1405 return;
1408 * An error has occurred on this socket. Pass it to the plug.
1410 plug_closing_winsock_error(s->plug, s->pending_error);
1414 * The function which tries to send on a socket once it's deemed
1415 * writable.
1417 static void try_send(NetSocket *s)
1419 while (s->sending_oob || bufchain_size(&s->output_data) > 0) {
1420 int nsent;
1421 DWORD err;
1422 const void *data;
1423 size_t len;
1424 int urgentflag;
1426 if (s->sending_oob) {
1427 urgentflag = MSG_OOB;
1428 len = s->sending_oob;
1429 data = &s->oobdata;
1430 } else {
1431 urgentflag = 0;
1432 ptrlen bufdata = bufchain_prefix(&s->output_data);
1433 data = bufdata.ptr;
1434 len = bufdata.len;
1436 len = min(len, INT_MAX); /* WinSock send() takes an int */
1437 nsent = p_send(s->s, data, len, urgentflag);
1438 noise_ultralight(NOISE_SOURCE_IOLEN, nsent);
1439 if (nsent <= 0) {
1440 err = (nsent < 0 ? p_WSAGetLastError() : 0);
1441 if ((err < WSABASEERR && nsent < 0) || err == WSAEWOULDBLOCK) {
1443 * Perfectly normal: we've sent all we can for the moment.
1445 * (Some WinSock send() implementations can return
1446 * <0 but leave no sensible error indication -
1447 * WSAGetLastError() is called but returns zero or
1448 * a small number - so we check that case and treat
1449 * it just like WSAEWOULDBLOCK.)
1451 s->writable = false;
1452 return;
1453 } else {
1455 * If send() returns a socket error, we unfortunately
1456 * can't just call plug_closing(), because it's quite
1457 * likely that we're currently _in_ a call from the
1458 * code we'd be calling back to, so we'd have to make
1459 * half the SSH code reentrant. Instead we flag a
1460 * pending error on the socket, to be dealt with (by
1461 * calling plug_closing()) at some suitable future
1462 * moment.
1464 s->pending_error = err;
1465 queue_toplevel_callback(socket_error_callback, s);
1466 return;
1468 } else {
1469 if (s->sending_oob) {
1470 if (nsent < len) {
1471 memmove(s->oobdata, s->oobdata+nsent, len-nsent);
1472 s->sending_oob = len - nsent;
1473 } else {
1474 s->sending_oob = 0;
1476 } else {
1477 bufchain_consume(&s->output_data, nsent);
1483 * If we reach here, we've finished sending everything we might
1484 * have needed to send. Send EOF, if we need to.
1486 if (s->outgoingeof == EOF_PENDING) {
1487 p_shutdown(s->s, SD_SEND);
1488 s->outgoingeof = EOF_SENT;
1492 static size_t sk_net_write(Socket *sock, const void *buf, size_t len)
1494 NetSocket *s = container_of(sock, NetSocket, sock);
1496 assert(s->outgoingeof == EOF_NO);
1499 * Add the data to the buffer list on the socket.
1501 bufchain_add(&s->output_data, buf, len);
1504 * Now try sending from the start of the buffer list.
1506 if (s->writable)
1507 try_send(s);
1509 return bufchain_size(&s->output_data);
1512 static size_t sk_net_write_oob(Socket *sock, const void *buf, size_t len)
1514 NetSocket *s = container_of(sock, NetSocket, sock);
1516 assert(s->outgoingeof == EOF_NO);
1519 * Replace the buffer list on the socket with the data.
1521 bufchain_clear(&s->output_data);
1522 assert(len <= sizeof(s->oobdata));
1523 memcpy(s->oobdata, buf, len);
1524 s->sending_oob = len;
1527 * Now try sending from the start of the buffer list.
1529 if (s->writable)
1530 try_send(s);
1532 return s->sending_oob;
1535 static void sk_net_write_eof(Socket *sock)
1537 NetSocket *s = container_of(sock, NetSocket, sock);
1539 assert(s->outgoingeof == EOF_NO);
1542 * Mark the socket as pending outgoing EOF.
1544 s->outgoingeof = EOF_PENDING;
1547 * Now try sending from the start of the buffer list.
1549 if (s->writable)
1550 try_send(s);
1553 void select_result(WPARAM wParam, LPARAM lParam)
1555 int ret;
1556 DWORD err;
1557 char buf[20480]; /* nice big buffer for plenty of speed */
1558 NetSocket *s;
1559 bool atmark;
1561 /* wParam is the socket itself */
1563 if (wParam == 0)
1564 return; /* boggle */
1566 s = find234(sktree, (void *) wParam, cmpforsearch);
1567 if (!s)
1568 return; /* boggle */
1570 if ((err = WSAGETSELECTERROR(lParam)) != 0) {
1572 * An error has occurred on this socket. Pass it to the
1573 * plug.
1575 if (s->addr) {
1576 SockAddr thisaddr = sk_extractaddr_tmp(
1577 s->addr, &s->step);
1578 plug_log(s->plug, PLUGLOG_CONNECT_FAILED, &thisaddr, s->port,
1579 winsock_error_string(err), err);
1580 while (err && s->addr && sk_nextaddr(s->addr, &s->step)) {
1581 err = try_connect(s);
1584 if (err != 0)
1585 plug_closing_winsock_error(s->plug, err);
1586 return;
1589 noise_ultralight(NOISE_SOURCE_IOID, wParam);
1591 switch (WSAGETSELECTEVENT(lParam)) {
1592 case FD_CONNECT:
1593 s->connected = true;
1594 s->writable = true;
1597 * Once a socket is connected, we can stop falling back
1598 * through the candidate addresses to connect to. But first,
1599 * let the plug know we were successful.
1601 if (s->addr) {
1602 SockAddr thisaddr = sk_extractaddr_tmp(
1603 s->addr, &s->step);
1604 plug_log(s->plug, PLUGLOG_CONNECT_SUCCESS,
1605 &thisaddr, s->port, NULL, 0);
1607 sk_addr_free(s->addr);
1608 s->addr = NULL;
1610 break;
1611 case FD_READ:
1612 /* In the case the socket is still frozen, we don't even bother */
1613 if (s->frozen) {
1614 s->frozen_readable = true;
1615 break;
1619 * We have received data on the socket. For an oobinline
1620 * socket, this might be data _before_ an urgent pointer,
1621 * in which case we send it to the back end with type==1
1622 * (data prior to urgent).
1624 if (s->oobinline) {
1625 u_long atmark_from_ioctl = 1;
1626 p_ioctlsocket(s->s, SIOCATMARK, &atmark_from_ioctl);
1628 * Avoid checking the return value from ioctlsocket(),
1629 * on the grounds that some WinSock wrappers don't
1630 * support it. If it does nothing, we get atmark==1,
1631 * which is equivalent to `no OOB pending', so the
1632 * effect will be to non-OOB-ify any OOB data.
1634 atmark = atmark_from_ioctl;
1635 } else
1636 atmark = true;
1638 ret = p_recv(s->s, buf, sizeof(buf), 0);
1639 noise_ultralight(NOISE_SOURCE_IOLEN, ret);
1640 if (ret < 0) {
1641 err = p_WSAGetLastError();
1642 if (err == WSAEWOULDBLOCK) {
1643 break;
1646 if (ret < 0) {
1647 plug_closing_winsock_error(s->plug, err);
1648 } else if (0 == ret) {
1649 plug_closing_normal(s->plug);
1650 } else {
1651 plug_receive(s->plug, atmark ? 0 : 1, buf, ret);
1653 break;
1654 case FD_OOB:
1656 * This will only happen on a non-oobinline socket. It
1657 * indicates that we can immediately perform an OOB read
1658 * and get back OOB data, which we will send to the back
1659 * end with type==2 (urgent data).
1661 ret = p_recv(s->s, buf, sizeof(buf), MSG_OOB);
1662 noise_ultralight(NOISE_SOURCE_IOLEN, ret);
1663 if (ret <= 0) {
1664 int err = p_WSAGetLastError();
1665 plug_closing_winsock_error(s->plug, err);
1666 } else {
1667 plug_receive(s->plug, 2, buf, ret);
1669 break;
1670 case FD_WRITE: {
1671 int bufsize_before, bufsize_after;
1672 s->writable = true;
1673 bufsize_before = s->sending_oob + bufchain_size(&s->output_data);
1674 try_send(s);
1675 bufsize_after = s->sending_oob + bufchain_size(&s->output_data);
1676 if (bufsize_after < bufsize_before)
1677 plug_sent(s->plug, bufsize_after);
1678 break;
1680 case FD_CLOSE:
1681 /* Signal a close on the socket. First read any outstanding data. */
1682 do {
1683 ret = p_recv(s->s, buf, sizeof(buf), 0);
1684 if (ret < 0) {
1685 err = p_WSAGetLastError();
1686 if (err == WSAEWOULDBLOCK)
1687 break;
1688 plug_closing_winsock_error(s->plug, err);
1689 } else {
1690 if (ret)
1691 plug_receive(s->plug, 0, buf, ret);
1692 else
1693 plug_closing_normal(s->plug);
1695 } while (ret > 0);
1696 return;
1697 case FD_ACCEPT: {
1698 #ifdef NO_IPV6
1699 struct sockaddr_in isa;
1700 #else
1701 struct sockaddr_storage isa; // FIXME: also if Unix and no IPv6
1702 #endif
1703 int addrlen = sizeof(isa);
1704 SOCKET t; /* socket of connection */
1705 accept_ctx_t actx;
1707 memset(&isa, 0, sizeof(isa));
1708 err = 0;
1709 t = p_accept(s->s,(struct sockaddr *)&isa,&addrlen);
1710 if (t == INVALID_SOCKET)
1712 err = p_WSAGetLastError();
1713 if (err == WSATRY_AGAIN)
1714 break;
1717 actx.p = (void *)t;
1719 #ifndef NO_IPV6
1720 if (isa.ss_family == AF_INET &&
1721 s->localhost_only &&
1722 !ipv4_is_local_addr(((struct sockaddr_in *)&isa)->sin_addr))
1723 #else
1724 if (s->localhost_only && !ipv4_is_local_addr(isa.sin_addr))
1725 #endif
1727 p_closesocket(t); /* dodgy WinSock let nonlocal through */
1728 } else if (plug_accepting(s->plug, sk_net_accept, actx)) {
1729 p_closesocket(t); /* denied or error */
1731 break;
1737 * Special error values are returned from sk_namelookup and sk_new
1738 * if there's a problem. These functions extract an error message,
1739 * or return NULL if there's no problem.
1741 const char *sk_addr_error(SockAddr *addr)
1743 return addr->error;
1745 static const char *sk_net_socket_error(Socket *sock)
1747 NetSocket *s = container_of(sock, NetSocket, sock);
1748 return s->error;
1751 static SocketPeerInfo *sk_net_peer_info(Socket *sock)
1753 NetSocket *s = container_of(sock, NetSocket, sock);
1754 #ifdef NO_IPV6
1755 struct sockaddr_in addr;
1756 #else
1757 struct sockaddr_storage addr; // FIXME: also if Unix and no IPv6
1758 char buf[INET6_ADDRSTRLEN];
1759 #endif
1760 int addrlen = sizeof(addr);
1761 SocketPeerInfo *pi;
1763 if (p_getpeername(s->s, (struct sockaddr *)&addr, &addrlen) < 0)
1764 return NULL;
1766 pi = snew(SocketPeerInfo);
1767 pi->addressfamily = ADDRTYPE_UNSPEC;
1768 pi->addr_text = NULL;
1769 pi->port = -1;
1770 pi->log_text = NULL;
1772 if (((struct sockaddr *)&addr)->sa_family == AF_INET) {
1773 pi->addressfamily = ADDRTYPE_IPV4;
1774 memcpy(pi->addr_bin.ipv4, &((struct sockaddr_in *)&addr)->sin_addr, 4);
1775 pi->port = p_ntohs(((struct sockaddr_in *)&addr)->sin_port);
1776 pi->addr_text = dupstr(
1777 p_inet_ntoa(((struct sockaddr_in *)&addr)->sin_addr));
1778 pi->log_text = dupprintf("%s:%d", pi->addr_text, pi->port);
1780 #ifndef NO_IPV6
1781 } else if (((struct sockaddr *)&addr)->sa_family == AF_INET6) {
1782 pi->addressfamily = ADDRTYPE_IPV6;
1783 memcpy(pi->addr_bin.ipv6,
1784 &((struct sockaddr_in6 *)&addr)->sin6_addr, 16);
1785 pi->port = p_ntohs(((struct sockaddr_in6 *)&addr)->sin6_port);
1786 pi->addr_text = dupstr(
1787 p_inet_ntop(AF_INET6, &((struct sockaddr_in6 *)&addr)->sin6_addr,
1788 buf, sizeof(buf)));
1789 pi->log_text = dupprintf("[%s]:%d", pi->addr_text, pi->port);
1791 #endif
1792 } else {
1793 sfree(pi);
1794 return NULL;
1797 return pi;
1800 static void sk_net_set_frozen(Socket *sock, bool is_frozen)
1802 NetSocket *s = container_of(sock, NetSocket, sock);
1803 if (s->frozen == is_frozen)
1804 return;
1805 s->frozen = is_frozen;
1806 if (!is_frozen) {
1807 do_select(s->s, true);
1808 if (s->frozen_readable) {
1809 char c;
1810 p_recv(s->s, &c, 1, MSG_PEEK);
1813 s->frozen_readable = false;
1816 void socket_reselect_all(void)
1818 NetSocket *s;
1819 int i;
1821 for (i = 0; (s = index234(sktree, i)) != NULL; i++) {
1822 if (!s->frozen)
1823 do_select(s->s, true);
1828 * For Plink: enumerate all sockets currently active.
1830 SOCKET first_socket(int *state)
1832 NetSocket *s;
1833 *state = 0;
1834 s = index234(sktree, (*state)++);
1835 return s ? s->s : INVALID_SOCKET;
1838 SOCKET next_socket(int *state)
1840 NetSocket *s = index234(sktree, (*state)++);
1841 return s ? s->s : INVALID_SOCKET;
1844 bool socket_writable(SOCKET skt)
1846 NetSocket *s = find234(sktree, (void *)skt, cmpforsearch);
1848 if (s)
1849 return bufchain_size(&s->output_data) > 0;
1850 else
1851 return false;
1854 int net_service_lookup(const char *service)
1856 struct servent *se;
1857 se = p_getservbyname(service, NULL);
1858 if (se != NULL)
1859 return p_ntohs(se->s_port);
1860 else
1861 return 0;
1864 char *get_hostname(void)
1866 char hostbuf[256]; /* MSDN docs for gethostname() promise this is enough */
1867 if (p_gethostname(hostbuf, sizeof(hostbuf)) < 0)
1868 return NULL;
1869 return dupstr(hostbuf);
1872 SockAddr *platform_get_x11_unix_address(const char *display, int displaynum)
1874 SockAddr *ret = snew(SockAddr);
1875 memset(ret, 0, sizeof(SockAddr));
1876 ret->error = "unix sockets for X11 not supported on this platform";
1877 ret->refcount = 1;
1878 return ret;