]> asedeno.scripts.mit.edu Git - PuTTY.git/commitdiff
Report the right address in connection setup errors.
authorSimon Tatham <anakin@pobox.com>
Sat, 28 Jan 2017 10:56:19 +0000 (10:56 +0000)
committerSimon Tatham <anakin@pobox.com>
Sat, 28 Jan 2017 14:03:09 +0000 (14:03 +0000)
backend_socket_log was generating the IP address in its error messages
by means of calling sk_getaddr(). But sk_getaddr only gets a SockAddr,
which may contain a whole list of candidate addresses; it doesn't also
get the information stored in the 'step' field of the Socket that was
actually trying to make the connection, which says _which_ of those
addresses we were in the middle of trying to connect to.

So now we construct a temporary SockAddr that points at the
appropriate one of the addresses, and use that for calls to plug_log
during connection setup.

unix/uxnet.c
windows/winnet.c

index 903faeb096744e20e943fec174a2f0063166ad9a..47490a1eefe235de82fdcf35d8a70c24c5a2ee35 100644 (file)
@@ -344,6 +344,34 @@ void sk_getaddr(SockAddr addr, char *buf, int buflen)
     }
 }
 
+/*
+ * This constructs a SockAddr that points at one specific sub-address
+ * of a parent SockAddr. The returned SockAddr does not own all its
+ * own memory: it points into the old one's data structures, so it
+ * MUST NOT be used after the old one is freed, and it MUST NOT be
+ * passed to sk_addr_free. (The latter is why it's returned by value
+ * rather than dynamically allocated - that should clue in anyone
+ * writing a call to it that something is weird about it.)
+ */
+static struct SockAddr_tag sk_extractaddr_tmp(
+    SockAddr addr, const SockAddrStep *step)
+{
+    struct SockAddr_tag toret;
+    toret = *addr;                    /* structure copy */
+    toret.refcount = 1;
+
+    if (addr->superfamily == IP) {
+#ifndef NO_IPV6
+        toret.ais = step->ai;
+#else
+       assert(SOCKADDR_FAMILY(addr, *step) == AF_INET);
+        toret.addresses += step->curraddr;
+#endif
+    }
+
+    return toret;
+}
+
 int sk_addr_needs_port(SockAddr addr)
 {
     if (addr->superfamily == UNRESOLVED || addr->superfamily == UNIX) {
@@ -561,7 +589,11 @@ static int try_connect(Actual_Socket sock)
     if (sock->s >= 0)
         close(sock->s);
 
-    plug_log(sock->plug, 0, sock->addr, sock->port, NULL, 0);
+    {
+        struct SockAddr_tag thisaddr = sk_extractaddr_tmp(
+            sock->addr, &sock->step);
+        plug_log(sock->plug, 0, &thisaddr, sock->port, NULL, 0);
+    }
 
     /*
      * Open socket.
@@ -728,8 +760,11 @@ static int try_connect(Actual_Socket sock)
      */
     add234(sktree, sock);
 
-    if (err)
-       plug_log(sock->plug, 1, sock->addr, sock->port, strerror(err), err);
+    if (err) {
+        struct SockAddr_tag thisaddr = sk_extractaddr_tmp(
+            sock->addr, &sock->step);
+       plug_log(sock->plug, 1, &thisaddr, sock->port, strerror(err), err);
+    }
     return err;
 }
 
@@ -1385,8 +1420,12 @@ static int net_select_result(int fd, int event)
                      * with the next candidate address, if we have
                      * more than one.
                      */
+                    struct SockAddr_tag thisaddr;
                     assert(s->addr);
-                    plug_log(s->plug, 1, s->addr, s->port, errmsg, err);
+
+                    thisaddr = sk_extractaddr_tmp(s->addr, &s->step);
+                    plug_log(s->plug, 1, &thisaddr, s->port, errmsg, err);
+
                     while (err && s->addr && sk_nextaddr(s->addr, &s->step)) {
                         err = try_connect(s);
                     }
index 72360639e7c49cd770349a1d6388b3eb311c61d0..b4ac166cd2d99710a2c655c1a98619d8e5e0b11c 100644 (file)
@@ -704,6 +704,35 @@ void sk_getaddr(SockAddr addr, char *buf, int buflen)
     }
 }
 
+/*
+ * This constructs a SockAddr that points at one specific sub-address
+ * of a parent SockAddr. The returned SockAddr does not own all its
+ * own memory: it points into the old one's data structures, so it
+ * MUST NOT be used after the old one is freed, and it MUST NOT be
+ * passed to sk_addr_free. (The latter is why it's returned by value
+ * rather than dynamically allocated - that should clue in anyone
+ * writing a call to it that something is weird about it.)
+ */
+static struct SockAddr_tag sk_extractaddr_tmp(
+    SockAddr addr, const SockAddrStep *step)
+{
+    struct SockAddr_tag toret;
+    toret = *addr;                    /* structure copy */
+    toret.refcount = 1;
+
+#ifndef NO_IPV6
+    toret.ais = step->ai;
+#endif
+    if (SOCKADDR_FAMILY(addr, *step) == AF_INET
+#ifndef NO_IPV6
+        && !toret.ais
+#endif
+        )
+        toret.addresses += step->curraddr;
+
+    return toret;
+}
+
 int sk_addr_needs_port(SockAddr addr)
 {
     return addr->namedpipe ? FALSE : TRUE;
@@ -947,7 +976,11 @@ static DWORD try_connect(Actual_Socket sock)
         p_closesocket(sock->s);
     }
 
-    plug_log(sock->plug, 0, sock->addr, sock->port, NULL, 0);
+    {
+        struct SockAddr_tag thisaddr = sk_extractaddr_tmp(
+            sock->addr, &sock->step);
+        plug_log(sock->plug, 0, &thisaddr, sock->port, NULL, 0);
+    }
 
     /*
      * Open socket.
@@ -1114,8 +1147,11 @@ static DWORD try_connect(Actual_Socket sock)
      */
     add234(sktree, sock);
 
-    if (err)
-       plug_log(sock->plug, 1, sock->addr, sock->port, sock->error, err);
+    if (err) {
+        struct SockAddr_tag thisaddr = sk_extractaddr_tmp(
+            sock->addr, &sock->step);
+       plug_log(sock->plug, 1, &thisaddr, sock->port, sock->error, err);
+    }
     return err;
 }
 
@@ -1578,7 +1614,9 @@ int select_result(WPARAM wParam, LPARAM lParam)
         * plug.
         */
        if (s->addr) {
-           plug_log(s->plug, 1, s->addr, s->port,
+            struct SockAddr_tag thisaddr = sk_extractaddr_tmp(
+                s->addr, &s->step);
+           plug_log(s->plug, 1, &thisaddr, s->port,
                     winsock_error_string(err), err);
            while (err && s->addr && sk_nextaddr(s->addr, &s->step)) {
                err = try_connect(s);