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