X-Git-Url: https://git.distorted.org.uk/~mdw/sgt/putty/blobdiff_plain/facf756868132a288816194ebb54c5770903fc35..438015cc66d33c0cc29996de8724acb57c2e4324:/windows/winnet.c?ds=sidebyside diff --git a/windows/winnet.c b/windows/winnet.c index 93eb40c5..061f72b1 100644 --- a/windows/winnet.c +++ b/windows/winnet.c @@ -78,6 +78,7 @@ struct Socket_tag { }; struct SockAddr_tag { + int refcount; char *error; int resolved; #ifndef NO_IPV6 @@ -166,6 +167,7 @@ DECL_WINSOCK_FUNCTION(static, u_long, ntohl, (u_long)); DECL_WINSOCK_FUNCTION(static, u_long, htonl, (u_long)); DECL_WINSOCK_FUNCTION(static, u_short, htons, (u_short)); DECL_WINSOCK_FUNCTION(static, u_short, ntohs, (u_short)); +DECL_WINSOCK_FUNCTION(static, int, gethostname, (char *, int)); DECL_WINSOCK_FUNCTION(static, struct hostent FAR *, gethostbyname, (const char FAR *)); DECL_WINSOCK_FUNCTION(static, struct servent FAR *, getservbyname, @@ -202,7 +204,7 @@ DECL_WINSOCK_FUNCTION(static, int, getnameinfo, DECL_WINSOCK_FUNCTION(static, char *, gai_strerror, (int ecode)); DECL_WINSOCK_FUNCTION(static, int, WSAAddressToStringA, (LPSOCKADDR, DWORD, LPWSAPROTOCOL_INFO, - LPTSTR, LPDWORD)); + LPSTR, LPDWORD)); #endif static HMODULE winsock_module = NULL; @@ -294,6 +296,7 @@ void sk_init(void) GET_WINSOCK_FUNCTION(winsock_module, htonl); GET_WINSOCK_FUNCTION(winsock_module, htons); GET_WINSOCK_FUNCTION(winsock_module, ntohs); + GET_WINSOCK_FUNCTION(winsock_module, gethostname); GET_WINSOCK_FUNCTION(winsock_module, gethostbyname); GET_WINSOCK_FUNCTION(winsock_module, getservbyname); GET_WINSOCK_FUNCTION(winsock_module, inet_addr); @@ -332,7 +335,8 @@ void sk_cleanup(void) sktree = NULL; } - p_WSACleanup(); + if (p_WSACleanup) + p_WSACleanup(); if (winsock_module) FreeLibrary(winsock_module); #ifndef NO_IPV6 @@ -425,10 +429,8 @@ SockAddr sk_namelookup(const char *host, char **canonicalname, { SockAddr ret = snew(struct SockAddr_tag); unsigned long a; - struct hostent *h = NULL; char realhost[8192]; int hint_family; - int err; /* Default to IPv4. */ hint_family = (address_family == ADDRTYPE_IPV4 ? AF_INET : @@ -444,9 +446,12 @@ SockAddr sk_namelookup(const char *host, char **canonicalname, #endif ret->addresses = NULL; ret->resolved = FALSE; + ret->refcount = 1; *realhost = '\0'; if ((a = p_inet_addr(host)) == (unsigned long) INADDR_NONE) { + struct hostent *h = NULL; + int err; #ifndef NO_IPV6 /* * Use getaddrinfo when it's available @@ -547,6 +552,7 @@ SockAddr sk_nonamelookup(const char *host) #endif ret->addresses = NULL; ret->naddresses = 0; + ret->refcount = 1; strncpy(ret->hostname, host, lenof(ret->hostname)); ret->hostname[lenof(ret->hostname)-1] = '\0'; return ret; @@ -579,8 +585,10 @@ void sk_getaddr(SockAddr addr, char *buf, int buflen) #ifndef NO_IPV6 if (step.ai) { if (p_WSAAddressToStringA) { + DWORD dwbuflen; p_WSAAddressToStringA(step.ai->ai_addr, step.ai->ai_addrlen, - NULL, buf, &buflen); + NULL, buf, &dwbuflen); + buflen = dwbuflen; } else strncpy(buf, "IPv6", buflen); } else @@ -599,7 +607,9 @@ void sk_getaddr(SockAddr addr, char *buf, int buflen) int sk_hostname_is_local(char *name) { - return !strcmp(name, "localhost"); + return !strcmp(name, "localhost") || + !strcmp(name, "::1") || + !strncmp(name, "127.", 4); } static INTERFACE_INFO local_interfaces[16]; @@ -708,6 +718,8 @@ void sk_addrcopy(SockAddr addr, char *buf) void sk_addr_free(SockAddr addr) { + if (--addr->refcount > 0) + return; #ifndef NO_IPV6 if (addr->ais && p_freeaddrinfo) p_freeaddrinfo(addr->ais); @@ -717,6 +729,12 @@ void sk_addr_free(SockAddr addr) sfree(addr); } +SockAddr sk_addr_dup(SockAddr addr) +{ + addr->refcount++; + return addr; +} + static Plug sk_tcp_plug(Socket sock, Plug p) { Actual_Socket s = (Actual_Socket) sock; @@ -1671,11 +1689,28 @@ int net_service_lookup(char *service) return 0; } +char *get_hostname(void) +{ + int len = 128; + char *hostname = NULL; + do { + len *= 2; + hostname = sresize(hostname, len, char); + if (p_gethostname(hostname, len) < 0) { + sfree(hostname); + hostname = NULL; + break; + } + } while (strlen(hostname) >= len-1); + return hostname; +} + SockAddr platform_get_x11_unix_address(const char *display, int displaynum, char **canonicalname) { SockAddr ret = snew(struct SockAddr_tag); memset(ret, 0, sizeof(struct SockAddr_tag)); ret->error = "unix sockets not supported on this platform"; + ret->refcount = 1; return ret; }