2 * Windows networking abstraction.
4 * For the IPv6 code in here I am indebted to Jeroen Massar and
8 #include <winsock2.h> /* need to put this first, for winelib builds */
14 #define NEED_DECLARATION_OF_SELECT /* in order to initialise it */
29 #pragma clang diagnostic push
30 #pragma clang diagnostic ignored "-Wmissing-braces"
32 const struct in6_addr in6addr_any
= IN6ADDR_ANY_INIT
;
33 const struct in6_addr in6addr_loopback
= IN6ADDR_LOOPBACK_INIT
;
35 #pragma clang diagnostic pop
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
47 typedef struct SockAddrStep_tag SockAddrStep
;
48 struct SockAddrStep_tag
{
50 struct addrinfo
*ai
; /* steps along addr->ais */
55 typedef struct NetSocket NetSocket
;
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 */
69 bool oobinline
, nodelay
, keepalive
, privport
;
70 enum { EOF_NO
, EOF_PENDING
, EOF_SENT
} outgoingeof
;
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
81 NetSocket
*parent
, *child
;
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
{
107 SuperFamily superfamily
;
109 struct addrinfo
*ais
; /* Addresses IPv6 style. */
111 unsigned long *addresses
; /* Addresses IPv4 style. */
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
) {
128 return step
.ai
->ai_family
;
141 * Start a SockAddrStep structure to step through multiple
145 #define START_STEP(addr, step) \
146 ((step).ai = (addr)->ais, (step).curraddr = 0)
148 #define START_STEP(addr, step) \
149 ((step).curraddr = 0)
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
;
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
;
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
,
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
));
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
,
231 static HMODULE winsock_module
= NULL
;
232 static WSADATA wsadata
;
234 static HMODULE winsock2_module
= NULL
;
235 static HMODULE wship6_module
= NULL
;
238 static bool sk_startup(int hi
, int lo
)
242 winsock_ver
= MAKEWORD(hi
, lo
);
244 if (p_WSAStartup(winsock_ver
, &wsadata
)) {
248 if (LOBYTE(wsadata
.wVersion
) != LOBYTE(winsock_ver
)) {
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
);
266 winsock_module
= load_system32_dll("ws2_32.dll");
267 if (!winsock_module
) {
268 winsock_module
= load_system32_dll("wsock32.dll");
271 modalfatalbox("Unable to load any WinSock library");
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. */
283 /* Fall back to wship6.dll for Windows 2000 */
284 wship6_module
= load_system32_dll("wship6.dll");
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
);
293 GET_WINDOWS_FUNCTION(winsock2_module
, WSAAddressToStringA
);
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
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
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) &&
342 modalfatalbox("Unable to initialise WinSock");
345 sktree
= newtree234(cmpfortree
);
348 void sk_cleanup(void)
354 for (i
= 0; (s
= index234(sktree
, i
)) != NULL
; i
++) {
364 FreeLibrary(winsock_module
);
367 FreeLibrary(wship6_module
);
371 const char *winsock_error_string(int error
)
374 * Error codes we know about and have historically had reasonably
375 * sensible error messages for.
379 return "Network error: Permission denied";
381 return "Network error: Address already in use";
382 case WSAEADDRNOTAVAIL
:
383 return "Network error: Cannot assign requested address";
384 case WSAEAFNOSUPPORT
:
386 "Network error: Address family not supported by protocol family";
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";
394 return "Network error: Connection reset by peer";
395 case WSAEDESTADDRREQ
:
396 return "Network error: Destination address required";
398 return "Network error: Bad address";
400 return "Network error: Host is down";
401 case WSAEHOSTUNREACH
:
402 return "Network error: No route to host";
404 return "Network error: Operation now in progress";
406 return "Network error: Interrupted function call";
408 return "Network error: Invalid argument";
410 return "Network error: Socket is already connected";
412 return "Network error: Too many open files";
414 return "Network error: Message too long";
416 return "Network error: Network is down";
418 return "Network error: Network dropped connection on reset";
420 return "Network error: Network is unreachable";
422 return "Network error: No buffer space available";
424 return "Network error: Bad protocol option";
426 return "Network error: Socket is not connected";
428 return "Network error: Socket operation on non-socket";
430 return "Network error: Operation not supported";
431 case WSAEPFNOSUPPORT
:
432 return "Network error: Protocol family not supported";
434 return "Network error: Too many processes";
435 case WSAEPROTONOSUPPORT
:
436 return "Network error: Protocol not supported";
438 return "Network error: Protocol wrong type for socket";
440 return "Network error: Cannot send after socket shutdown";
441 case WSAESOCKTNOSUPPORT
:
442 return "Network error: Socket type not supported";
444 return "Network error: Connection timed out";
446 return "Network error: Resource temporarily unavailable";
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" :
467 SockAddr
*sk_namelookup(const char *host
, char **canonicalname
,
470 *canonicalname
= NULL
;
472 SockAddr
*addr
= snew(SockAddr
);
473 memset(addr
, 0, sizeof(SockAddr
));
474 addr
->superfamily
= UNRESOLVED
;
479 * Use getaddrinfo, as long as it's available. This should handle
480 * both IPv4 and IPv6 address literals, and hostnames, in one
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
:
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
);
498 addr
->superfamily
= IP
;
499 if (addr
->ais
->ai_canonname
)
500 *canonicalname
= dupstr(addr
->ais
->ai_canonname
);
502 *canonicalname
= dupstr(host
);
504 addr
->error
= namelookup_strerror(err
);
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
);
526 struct hostent
*h
= p_gethostbyname(host
);
528 addr
->superfamily
= IP
;
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
++) {
536 memcpy(&a
, h
->h_addr_list
[n
], sizeof(a
));
537 addr
->addresses
[n
] = p_ntohl(a
);
540 *canonicalname
= dupstr(h
->h_name
);
542 DWORD err
= p_WSAGetLastError();
543 addr
->error
= namelookup_strerror(err
);
548 static SockAddr
*sk_special_addr(SuperFamily superfamily
, const char *name
)
550 SockAddr
*ret
= snew(SockAddr
);
552 ret
->superfamily
= superfamily
;
556 ret
->addresses
= NULL
;
559 strncpy(ret
->hostname
, name
, lenof(ret
->hostname
));
560 ret
->hostname
[lenof(ret
->hostname
)-1] = '\0';
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
);
575 SockAddr
*sk_unix_addr(const char *sockpath
)
577 return sk_special_addr(UNIX
, sockpath
);
581 static bool sk_nextaddr(SockAddr
*addr
, SockAddrStep
*step
)
585 if (step
->ai
->ai_next
) {
586 step
->ai
= step
->ai
->ai_next
;
592 if (step
->curraddr
+1 < addr
->naddresses
) {
600 void sk_getaddr(SockAddr
*addr
, char *buf
, int buflen
)
603 START_STEP(addr
, step
);
608 if (p_WSAAddressToStringA
) {
609 DWORD dwbuflen
= buflen
;
610 err
= p_WSAAddressToStringA(step
.ai
->ai_addr
, step
.ai
->ai_addrlen
,
611 NULL
, buf
, &dwbuflen
);
615 strncpy(buf
, addr
->hostname
, buflen
);
617 strncpy(buf
, "<unknown>", buflen
);
618 buf
[buflen
-1] = '\0';
622 if (sockaddr_family(addr
, step
) == AF_INET
) {
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';
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
)
647 toret
= *addr
; /* structure copy */
651 toret
.ais
= step
->ai
;
653 if (sockaddr_family(addr
, *step
) == AF_INET
658 toret
.addresses
+= step
->curraddr
;
663 bool sk_addr_needs_port(SockAddr
*addr
)
665 return addr
->superfamily
!= NAMEDPIPE
667 && addr
->superfamily
!= UNIX
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);
690 SetHandleInformation((HANDLE
)s
, HANDLE_FLAG_INHERIT
, 0);
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
);
698 n_local_interfaces
= -1;
700 if (n_local_interfaces
> 0) {
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
)
716 START_STEP(addr
, step
);
717 family
= sockaddr_family(addr
, step
);
720 if (family
== AF_INET6
) {
721 return IN6_IS_ADDR_LOOPBACK(&((const struct sockaddr_in6
*)step
.ai
->ai_addr
)->sin6_addr
);
724 if (family
== AF_INET
) {
727 return ipv4_is_local_addr(((struct sockaddr_in
*)step
.ai
->ai_addr
)
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
);
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
)
752 START_STEP(addr
, step
);
753 family
= sockaddr_family(addr
, step
);
755 return (family
== AF_INET
? ADDRTYPE_IPV4
:
757 family
== AF_INET6
? ADDRTYPE_IPV6
:
762 void sk_addrcopy(SockAddr
*addr
, char *buf
)
766 START_STEP(addr
, step
);
767 family
= sockaddr_family(addr
, step
);
769 assert(family
!= AF_UNSPEC
);
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
));
779 unreachable("bad address family in sk_addrcopy");
782 if (family
== AF_INET
) {
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)
795 if (addr
->ais
&& p_freeaddrinfo
)
796 p_freeaddrinfo(addr
->ais
);
799 sfree(addr
->addresses
);
803 SockAddr
*sk_addr_dup(SockAddr
*addr
)
809 static Plug
*sk_net_plug(Socket
*sock
, Plug
*p
)
811 NetSocket
*s
= container_of(sock
, NetSocket
, sock
);
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
= {
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
)
844 * Create NetSocket structure.
846 ret
= snew(NetSocket
);
847 ret
->sock
.vt
= &NetSocket_sockvt
;
850 bufchain_init(&ret
->output_data
);
851 ret
->writable
= true; /* to start with */
852 ret
->sending_oob
= 0;
853 ret
->outgoingeof
= EOF_NO
;
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
;
861 ret
->s
= (SOCKET
)ctx
.p
;
863 if (ret
->s
== INVALID_SOCKET
) {
864 err
= p_WSAGetLastError();
865 ret
->error
= winsock_error_string(err
);
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);
884 static DWORD
try_connect(NetSocket
*sock
)
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);
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);
924 if (s
== INVALID_SOCKET
) {
925 err
= p_WSAGetLastError();
926 sock
->error
= winsock_error_string(err
);
930 SetHandleInformation((HANDLE
)s
, HANDLE_FLAG_INHERIT
, 0);
932 if (sock
->oobinline
) {
934 p_setsockopt(s
, SOL_SOCKET
, SO_OOBINLINE
, (void *) &b
, sizeof(b
));
939 p_setsockopt(s
, IPPROTO_TCP
, TCP_NODELAY
, (void *) &b
, sizeof(b
));
942 if (sock
->keepalive
) {
944 p_setsockopt(s
, SOL_SOCKET
, SO_KEEPALIVE
, (void *) &b
, sizeof(b
));
948 * Bind to local address.
951 localport
= 1023; /* count from 1023 downwards */
953 localport
= 0; /* just use port 0 (ie winsock picks) */
955 /* Loop round trying to bind */
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
);
968 a
.sin_family
= AF_INET
;
969 a
.sin_addr
.s_addr
= p_htonl(INADDR_ANY
);
970 a
.sin_port
= p_htons(localport
);
973 sockcode
= p_bind(s
, (family
== AF_INET6
?
974 (struct sockaddr
*) &a6
:
975 (struct sockaddr
*) &a
),
976 (family
== AF_INET6
? sizeof(a6
) : sizeof(a
)));
978 sockcode
= p_bind(s
, (struct sockaddr
*) &a
, sizeof(a
));
980 if (sockcode
!= SOCKET_ERROR
) {
984 err
= p_WSAGetLastError();
985 if (err
!= WSAEADDRINUSE
) /* failed, for a bad reason */
990 break; /* we're only looping once */
993 break; /* we might have got to the end */
997 sock
->error
= winsock_error_string(err
);
1002 * Connect to remote address.
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
);
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
;
1014 a
.sin_family
= AF_INET
;
1016 ((struct sockaddr_in
*) sock
->step
.ai
->ai_addr
)->sin_addr
;
1017 a
.sin_port
= p_htons((short) sock
->port
);
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);
1032 sock
->error
= errstr
;
1040 ((family
== AF_INET6
) ? (struct sockaddr
*) &a6
:
1041 (struct sockaddr
*) &a
),
1042 (family
== AF_INET6
) ? sizeof(a6
) : sizeof(a
))
1044 p_connect(s
, (struct sockaddr
*) &a
, sizeof(a
))
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
1054 if ( err
!= WSAEWOULDBLOCK
) {
1055 sock
->error
= winsock_error_string(err
);
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);
1074 * No matter what happened, put the socket back in the tree.
1076 add234(sktree
, sock
);
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
);
1087 Socket
*sk_new(SockAddr
*addr
, int port
, bool privport
, bool oobinline
,
1088 bool nodelay
, bool keepalive
, Plug
*plug
)
1094 * Create NetSocket structure.
1096 ret
= snew(NetSocket
);
1097 ret
->sock
.vt
= &NetSocket_sockvt
;
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
;
1116 START_STEP(ret
->addr
, ret
->step
);
1117 ret
->s
= INVALID_SOCKET
;
1121 err
= try_connect(ret
);
1122 } while (err
&& sk_nextaddr(ret
->addr
, &ret
->step
));
1127 static Socket
*sk_newlistener_internal(
1128 const char *srcaddr
, int port
, Plug
*plug
,
1129 bool local_host_only
, int orig_address_family
)
1139 struct sockaddr
*bindaddr
;
1147 int address_family
= orig_address_family
;
1150 * Create NetSocket structure.
1152 ret
= snew(NetSocket
);
1153 ret
->sock
.vt
= &NetSocket_sockvt
;
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
;
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
;
1179 s
= p_socket(address_family
, SOCK_STREAM
, 0);
1182 if (s
== INVALID_SOCKET
) {
1183 err
= p_WSAGetLastError();
1184 ret
->error
= winsock_error_string(err
);
1188 SetHandleInformation((HANDLE
)s
, HANDLE_FLAG_INHERIT
, 0);
1190 ret
->oobinline
= false;
1193 if (address_family
!= AF_UNIX
)
1197 p_setsockopt(s
, SOL_SOCKET
, SO_EXCLUSIVEADDRUSE
,
1198 (const char *)&on
, sizeof(on
));
1201 switch (address_family
) {
1204 memset(&a6
, 0, sizeof(a6
));
1205 a6
.sin6_family
= AF_INET6
;
1206 if (local_host_only
)
1207 a6
.sin6_addr
= in6addr_loopback
;
1209 a6
.sin6_addr
= in6addr_any
;
1210 if (srcaddr
!= NULL
&& p_getaddrinfo
) {
1211 struct addrinfo hints
;
1212 struct addrinfo
*ai
;
1215 memset(&hints
, 0, sizeof(hints
));
1216 hints
.ai_family
= AF_INET6
;
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
) {
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
);
1236 bool got_addr
= false;
1237 a
.sin_family
= AF_INET
;
1240 * Bind to source address. First try an explicitly
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
);
1253 * ... and failing that, go with one of the standard ones.
1256 if (local_host_only
)
1257 a
.sin_addr
.s_addr
= p_htonl(INADDR_LOOPBACK
);
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
);
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
);
1277 unreachable("bad address family in sk_newlistener_internal");
1280 retcode
= p_bind(s
, bindaddr
, bindsize
);
1281 if (retcode
!= SOCKET_ERROR
) {
1284 err
= p_WSAGetLastError();
1289 ret
->error
= winsock_error_string(err
);
1294 if (p_listen(s
, SOMAXCONN
) == SOCKET_ERROR
) {
1296 ret
->error
= winsock_error_string(p_WSAGetLastError());
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);
1305 ret
->error
= errstr
;
1309 add234(sktree
, ret
);
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
);
1321 NetSocket
*ns
= container_of(other
, NetSocket
, 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
:
1344 orig_address_family
== ADDRTYPE_IPV6
? AF_INET6
:
1348 return sk_newlistener_internal(srcaddr
, port
, plug
, local_host_only
,
1352 Socket
*sk_newlistener_unix(const char *path
, Plug
*plug
)
1355 return sk_newlistener_internal(path
, 0, plug
, false, AF_UNIX
);
1357 return new_error_socket_fmt(
1358 plug
, "AF_UNIX support not compiled into this program");
1362 static void sk_net_close(Socket
*sock
)
1364 NetSocket
*s
= container_of(sock
, NetSocket
, sock
);
1367 sk_net_close(&s
->child
->sock
);
1369 bufchain_clear(&s
->output_data
);
1372 do_select(s
->s
, false);
1373 p_closesocket(s
->s
);
1375 sk_addr_free(s
->addr
);
1376 delete_callbacks_for_context(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
)
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
1417 static void try_send(NetSocket
*s
)
1419 while (s
->sending_oob
|| bufchain_size(&s
->output_data
) > 0) {
1426 if (s
->sending_oob
) {
1427 urgentflag
= MSG_OOB
;
1428 len
= s
->sending_oob
;
1432 ptrlen bufdata
= bufchain_prefix(&s
->output_data
);
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
);
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;
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
1464 s
->pending_error
= err
;
1465 queue_toplevel_callback(socket_error_callback
, s
);
1469 if (s
->sending_oob
) {
1471 memmove(s
->oobdata
, s
->oobdata
+nsent
, len
-nsent
);
1472 s
->sending_oob
= len
- nsent
;
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.
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.
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.
1553 void select_result(WPARAM wParam
, LPARAM lParam
)
1557 char buf
[20480]; /* nice big buffer for plenty of speed */
1561 /* wParam is the socket itself */
1564 return; /* boggle */
1566 s
= find234(sktree
, (void *) wParam
, cmpforsearch
);
1568 return; /* boggle */
1570 if ((err
= WSAGETSELECTERROR(lParam
)) != 0) {
1572 * An error has occurred on this socket. Pass it to the
1576 SockAddr thisaddr
= sk_extractaddr_tmp(
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
);
1585 plug_closing_winsock_error(s
->plug
, err
);
1589 noise_ultralight(NOISE_SOURCE_IOID
, wParam
);
1591 switch (WSAGETSELECTEVENT(lParam
)) {
1593 s
->connected
= 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.
1602 SockAddr thisaddr
= sk_extractaddr_tmp(
1604 plug_log(s
->plug
, PLUGLOG_CONNECT_SUCCESS
,
1605 &thisaddr
, s
->port
, NULL
, 0);
1607 sk_addr_free(s
->addr
);
1612 /* In the case the socket is still frozen, we don't even bother */
1614 s
->frozen_readable
= true;
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).
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
;
1638 ret
= p_recv(s
->s
, buf
, sizeof(buf
), 0);
1639 noise_ultralight(NOISE_SOURCE_IOLEN
, ret
);
1641 err
= p_WSAGetLastError();
1642 if (err
== WSAEWOULDBLOCK
) {
1647 plug_closing_winsock_error(s
->plug
, err
);
1648 } else if (0 == ret
) {
1649 plug_closing_normal(s
->plug
);
1651 plug_receive(s
->plug
, atmark
? 0 : 1, buf
, ret
);
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
);
1664 int err
= p_WSAGetLastError();
1665 plug_closing_winsock_error(s
->plug
, err
);
1667 plug_receive(s
->plug
, 2, buf
, ret
);
1671 int bufsize_before
, bufsize_after
;
1673 bufsize_before
= s
->sending_oob
+ bufchain_size(&s
->output_data
);
1675 bufsize_after
= s
->sending_oob
+ bufchain_size(&s
->output_data
);
1676 if (bufsize_after
< bufsize_before
)
1677 plug_sent(s
->plug
, bufsize_after
);
1681 /* Signal a close on the socket. First read any outstanding data. */
1683 ret
= p_recv(s
->s
, buf
, sizeof(buf
), 0);
1685 err
= p_WSAGetLastError();
1686 if (err
== WSAEWOULDBLOCK
)
1688 plug_closing_winsock_error(s
->plug
, err
);
1691 plug_receive(s
->plug
, 0, buf
, ret
);
1693 plug_closing_normal(s
->plug
);
1699 struct sockaddr_in isa
;
1701 struct sockaddr_storage isa
; // FIXME: also if Unix and no IPv6
1703 int addrlen
= sizeof(isa
);
1704 SOCKET t
; /* socket of connection */
1707 memset(&isa
, 0, sizeof(isa
));
1709 t
= p_accept(s
->s
,(struct sockaddr
*)&isa
,&addrlen
);
1710 if (t
== INVALID_SOCKET
)
1712 err
= p_WSAGetLastError();
1713 if (err
== WSATRY_AGAIN
)
1720 if (isa
.ss_family
== AF_INET
&&
1721 s
->localhost_only
&&
1722 !ipv4_is_local_addr(((struct sockaddr_in
*)&isa
)->sin_addr
))
1724 if (s
->localhost_only
&& !ipv4_is_local_addr(isa
.sin_addr
))
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 */
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
)
1745 static const char *sk_net_socket_error(Socket
*sock
)
1747 NetSocket
*s
= container_of(sock
, NetSocket
, sock
);
1751 static SocketPeerInfo
*sk_net_peer_info(Socket
*sock
)
1753 NetSocket
*s
= container_of(sock
, NetSocket
, sock
);
1755 struct sockaddr_in addr
;
1757 struct sockaddr_storage addr
; // FIXME: also if Unix and no IPv6
1758 char buf
[INET6_ADDRSTRLEN
];
1760 int addrlen
= sizeof(addr
);
1763 if (p_getpeername(s
->s
, (struct sockaddr
*)&addr
, &addrlen
) < 0)
1766 pi
= snew(SocketPeerInfo
);
1767 pi
->addressfamily
= ADDRTYPE_UNSPEC
;
1768 pi
->addr_text
= NULL
;
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
);
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
,
1789 pi
->log_text
= dupprintf("[%s]:%d", pi
->addr_text
, pi
->port
);
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
)
1805 s
->frozen
= is_frozen
;
1807 do_select(s
->s
, true);
1808 if (s
->frozen_readable
) {
1810 p_recv(s
->s
, &c
, 1, MSG_PEEK
);
1813 s
->frozen_readable
= false;
1816 void socket_reselect_all(void)
1821 for (i
= 0; (s
= index234(sktree
, i
)) != NULL
; i
++) {
1823 do_select(s
->s
, true);
1828 * For Plink: enumerate all sockets currently active.
1830 SOCKET
first_socket(int *state
)
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
);
1849 return bufchain_size(&s
->output_data
) > 0;
1854 int net_service_lookup(const char *service
)
1857 se
= p_getservbyname(service
, NULL
);
1859 return p_ntohs(se
->s_port
);
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)
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";