X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/6ee9b735013c0e636b027b77e9f6ba57a96e142f..c85623f918b8a6c639afc15604414f9b113bb20d:/winnet.c diff --git a/winnet.c b/winnet.c index 9d3f66c2..f617b0fc 100644 --- a/winnet.c +++ b/winnet.c @@ -59,7 +59,7 @@ ((ntohl(addr.s_addr) & 0xFF000000L) == 0x7F000000L) struct Socket_tag { - struct socket_function_table *fn; + const struct socket_function_table *fn; /* the above variable absolutely *must* be the first in this structure */ char *error; SOCKET s; @@ -90,12 +90,18 @@ typedef struct Socket_tag *Actual_Socket; struct SockAddr_tag { char *error; - /* address family this belongs to, AF_INET for IPv4, AF_INET6 for IPv6. */ + /* + * Which address family this address belongs to. AF_INET for + * IPv4; AF_INET6 for IPv6; AF_UNSPEC indicates that name + * resolution has not been done and a simple host name is held + * in this SockAddr structure. + */ int family; unsigned long address; /* Address IPv4 style. */ #ifdef IPV6 struct addrinfo *ai; /* Address IPv6 style. */ #endif + char hostname[512]; /* Store an unresolved host name. */ }; static tree234 *sktree; @@ -218,7 +224,7 @@ char *winsock_error_string(int error) } } -SockAddr sk_namelookup(char *host, char **canonicalname) +SockAddr sk_namelookup(const char *host, char **canonicalname) { SockAddr ret = smalloc(sizeof(struct SockAddr_tag)); unsigned long a; @@ -356,39 +362,79 @@ SockAddr sk_namelookup(char *host, char **canonicalname) return ret; } +SockAddr sk_nonamelookup(const char *host) +{ + SockAddr ret = smalloc(sizeof(struct SockAddr_tag)); + ret->error = NULL; + ret->family = AF_UNSPEC; + strncpy(ret->hostname, host, lenof(ret->hostname)); + ret->hostname[lenof(ret->hostname)-1] = '\0'; + return ret; +} + void sk_getaddr(SockAddr addr, char *buf, int buflen) { #ifdef IPV6 - if (addr->family == AF_INET) { + if (addr->family == AF_INET6) { + FIXME; /* I don't know how to get a text form of an IPv6 address. */ + } else #endif + if (addr->family == AF_INET) { struct in_addr a; a.s_addr = htonl(addr->address); strncpy(buf, inet_ntoa(a), buflen); -#ifdef IPV6 + buf[buflen-1] = '\0'; } else { - FIXME; /* I don't know how to get a text form of an IPv6 address. */ + assert(addr->family == AF_UNSPEC); + strncpy(buf, addr->hostname, buflen); + buf[buflen-1] = '\0'; } +} + +int sk_hostname_is_local(char *name) +{ + return !strcmp(name, "localhost"); +} + +int sk_address_is_local(SockAddr addr) +{ +#ifdef IPV6 + if (addr->family == AF_INET6) { + FIXME; /* someone who can compile for IPV6 had better do this bit */ + } else #endif + if (addr->family == AF_INET) { + struct in_addr a; + a.s_addr = htonl(addr->address); + return ipv4_is_loopback(a); + } else { + assert(addr->family == AF_UNSPEC); + return 0; /* we don't know; assume not */ + } } int sk_addrtype(SockAddr addr) { - return (addr->family == AF_INET ? ADDRTYPE_IPV4 : ADDRTYPE_IPV6); + return (addr->family == AF_INET ? ADDRTYPE_IPV4 : +#ifdef IPV6 + addr->family == AF_INET6 ? ADDRTYPE_IPV6 : +#endif + ADDRTYPE_NAME); } void sk_addrcopy(SockAddr addr, char *buf) { + assert(addr->family != AF_UNSPEC); #ifdef IPV6 - if (addr->family == AF_INET) { + if (addr->family == AF_INET6) { + memcpy(buf, (char*) addr->ai, 16); + } else #endif + if (addr->family == AF_INET) { struct in_addr a; a.s_addr = htonl(addr->address); memcpy(buf, (char*) &a.s_addr, 4); -#ifdef IPV6 - } else { - memcpy(buf, (char*) addr->ai, 16); } -#endif } void sk_addr_free(SockAddr addr) @@ -414,8 +460,8 @@ static void sk_tcp_flush(Socket s) } static void sk_tcp_close(Socket s); -static int sk_tcp_write(Socket s, char *data, int len); -static int sk_tcp_write_oob(Socket s, char *data, int len); +static int sk_tcp_write(Socket s, const char *data, int len); +static int sk_tcp_write_oob(Socket s, const char *data, int len); static void sk_tcp_set_private_ptr(Socket s, void *ptr); static void *sk_tcp_get_private_ptr(Socket s); static void sk_tcp_set_frozen(Socket s, int is_frozen); @@ -425,7 +471,7 @@ extern char *do_select(SOCKET skt, int startup); Socket sk_register(void *sock, Plug plug) { - static struct socket_function_table fn_table = { + static const struct socket_function_table fn_table = { sk_tcp_plug, sk_tcp_close, sk_tcp_write, @@ -482,7 +528,7 @@ Socket sk_register(void *sock, Plug plug) Socket sk_new(SockAddr addr, int port, int privport, int oobinline, int nodelay, Plug plug) { - static struct socket_function_table fn_table = { + static const struct socket_function_table fn_table = { sk_tcp_plug, sk_tcp_close, sk_tcp_write, @@ -523,6 +569,7 @@ Socket sk_new(SockAddr addr, int port, int privport, int oobinline, /* * Open socket. */ + assert(addr->family != AF_UNSPEC); s = socket(addr->family, SOCK_STREAM, 0); ret->s = s; @@ -659,7 +706,7 @@ Socket sk_new(SockAddr addr, int port, int privport, int oobinline, Socket sk_newlistener(char *srcaddr, int port, Plug plug, int local_host_only) { - static struct socket_function_table fn_table = { + static const struct socket_function_table fn_table = { sk_tcp_plug, sk_tcp_close, sk_tcp_write, @@ -711,10 +758,8 @@ Socket sk_newlistener(char *srcaddr, int port, Plug plug, int local_host_only) ret->oobinline = 0; - setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const char *)&on, sizeof(on)); - #ifdef IPV6 if (addr->family == AF_INET6) { memset(&a6, 0, sizeof(a6)); @@ -879,7 +924,7 @@ void try_send(Actual_Socket s) } } -static int sk_tcp_write(Socket sock, char *buf, int len) +static int sk_tcp_write(Socket sock, const char *buf, int len) { Actual_Socket s = (Actual_Socket) sock; @@ -897,7 +942,7 @@ static int sk_tcp_write(Socket sock, char *buf, int len) return bufchain_size(&s->output_data); } -static int sk_tcp_write_oob(Socket sock, char *buf, int len) +static int sk_tcp_write_oob(Socket sock, const char *buf, int len) { Actual_Socket s = (Actual_Socket) sock; @@ -928,23 +973,8 @@ int select_result(WPARAM wParam, LPARAM lParam) /* wParam is the socket itself */ - /* - * One user has reported an assertion failure in tree234 which - * indicates a null element pointer has been passed to a - * find*234 function. The following find234 is the only one in - * the whole program that I can see being capable of doing - * this, hence I'm forced to conclude that WinSock is capable - * of sending me netevent messages with wParam==0. I want to - * know what the rest of the message is if it does so! - */ - if (wParam == 0) { - char *str; - str = dupprintf("Strange WinSock message: wp=%08x lp=%08x", - (int)wParam, (int)lParam); - logevent(NULL, str); - connection_fatal(NULL, str); - sfree(str); - } + if (wParam == 0) + return 1; /* boggle */ s = find234(sktree, (void *) wParam, cmpforsearch); if (!s)