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