]> asedeno.scripts.mit.edu Git - PuTTY.git/blobdiff - windows/winnet.c
Giant const-correctness patch of doom!
[PuTTY.git] / windows / winnet.c
index f4507240ff5497248117a929b90936c6d65596f7..5e05cfc29978366f44918b9b7518c8e4b65ef3a0 100644 (file)
@@ -50,7 +50,7 @@ struct SockAddrStep_tag {
 struct Socket_tag {
     const struct socket_function_table *fn;
     /* the above variable absolutely *must* be the first in this structure */
-    char *error;
+    const char *error;
     SOCKET s;
     Plug plug;
     bufchain output_data;
@@ -356,7 +356,7 @@ static int errstring_compare(void *av, void *bv)
 
 static tree234 *errstrings = NULL;
 
-char *winsock_error_string(int error)
+const char *winsock_error_string(int error)
 {
     const char prefix[] = "Network error: ";
     struct errstring *es;
@@ -527,7 +527,13 @@ SockAddr sk_namelookup(const char *host, char **canonicalname,
            memset(&hints, 0, sizeof(hints));
            hints.ai_family = hint_family;
            hints.ai_flags = AI_CANONNAME;
-           if ((err = p_getaddrinfo(host, NULL, &hints, &ret->ais)) == 0)
+            {
+                /* strip [] on IPv6 address literals */
+                char *trimmed_host = host_strduptrim(host);
+                err = p_getaddrinfo(trimmed_host, NULL, &hints, &ret->ais);
+                sfree(trimmed_host);
+            }
+           if (err == 0)
                ret->resolved = TRUE;
        } else
 #endif
@@ -1156,8 +1162,8 @@ Socket sk_new(SockAddr addr, int port, int privport, int oobinline,
     return (Socket) ret;
 }
 
-Socket sk_newlistener(char *srcaddr, int port, Plug plug, int local_host_only,
-                     int orig_address_family)
+Socket sk_newlistener(const char *srcaddr, int port, Plug plug,
+                      int local_host_only, int orig_address_family)
 {
     static const struct socket_function_table fn_table = {
        sk_tcp_plug,
@@ -1241,15 +1247,29 @@ Socket sk_newlistener(char *srcaddr, int port, Plug plug, int local_host_only,
        if (address_family == AF_INET6) {
            memset(&a6, 0, sizeof(a6));
            a6.sin6_family = AF_INET6;
-           /* FIXME: srcaddr is ignored for IPv6, because I (SGT) don't
-            * know how to do it. :-)
-            * (jeroen:) saddr is specified as an address.. eg 2001:db8::1
-            * Thus we need either a parser that understands [2001:db8::1]:80
-            * style addresses and/or enhance this to understand hostnames too. */
            if (local_host_only)
                a6.sin6_addr = in6addr_loopback;
            else
                a6.sin6_addr = in6addr_any;
+            if (srcaddr != NULL && p_getaddrinfo) {
+                struct addrinfo hints;
+                struct addrinfo *ai;
+                int err;
+
+                memset(&hints, 0, sizeof(hints));
+                hints.ai_family = AF_INET6;
+                hints.ai_flags = 0;
+                {
+                    /* strip [] on IPv6 address literals */
+                    char *trimmed_addr = host_strduptrim(srcaddr);
+                    err = p_getaddrinfo(trimmed_addr, NULL, &hints, &ai);
+                    sfree(trimmed_addr);
+                }
+                if (err == 0 && ai->ai_family == AF_INET6) {
+                    a6.sin6_addr =
+                        ((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr;
+                }
+            }
            a6.sin6_port = p_htons(port);
        } else
 #endif