source: filezilla/trunk/fuentes/src/putty/windows/winnet.c @ 130

Last change on this file since 130 was 130, checked in by jrpelegrina, 3 years ago

First release to xenial

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