From: Simon Tatham Date: Sat, 28 Jan 2017 10:56:19 +0000 (+0000) Subject: Report the right address in connection setup errors. X-Git-Tag: 0.68~68 X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=commitdiff_plain;h=769ce54734f0359068a72d71bca99da9d5d3555e;p=PuTTY.git Report the right address in connection setup errors. 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. --- diff --git a/unix/uxnet.c b/unix/uxnet.c index 903faeb0..47490a1e 100644 --- a/unix/uxnet.c +++ b/unix/uxnet.c @@ -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); } diff --git a/windows/winnet.c b/windows/winnet.c index 72360639..b4ac166c 100644 --- a/windows/winnet.c +++ b/windows/winnet.c @@ -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);