]> asedeno.scripts.mit.edu Git - PuTTY_svn.git/commitdiff
Support explicit IPv6 source addresses in Windows port forwarding.
authorSimon Tatham <anakin@pobox.com>
Sat, 25 Jan 2014 15:58:59 +0000 (15:58 +0000)
committerSimon Tatham <anakin@pobox.com>
Sat, 25 Jan 2014 15:58:59 +0000 (15:58 +0000)
There's been a long-standing FIXME in Windows's sk_newlistener which
says that in IPv6 mode, an explicit source address (e.g. from a
command-line option of the form -L srcaddr:12345:dest:22) is ignored.
Now it's honoured if possible.

git-svn-id: http://svn.tartarus.org/sgt/putty@10122 cda61777-01e9-0310-a592-d414129be87e

windows/winnet.c

index 1a5a76f1d1c5dade5e4bab351661ecab8f94f36d..039701cf0bd9b9aab05d0e0f89c9f7af3622f6e2 100644 (file)
@@ -1247,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