PageRenderTime 127ms CodeModel.GetById 3ms app.highlight 110ms RepoModel.GetById 1ms app.codeStats 0ms

/windows/winnet.c

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