From dd82980774b3cf4c01e9b7f43f8134e815b32bcf Mon Sep 17 00:00:00 2001 From: Amos Jeffries Date: Sun, 8 Aug 2010 03:32:42 +1200 Subject: [PATCH] ConnOpener lookup local-end TCP link details cleanly. No more depending on fd_table to be setup for us. Instead we do the lookups when connected and set fd_table from here. --- src/comm/ConnOpener.cc | 28 ++++++++++++++++++++++++---- src/comm/ConnOpener.h | 1 + 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/comm/ConnOpener.cc b/src/comm/ConnOpener.cc index 94a33eddee..bbb471e333 100644 --- a/src/comm/ConnOpener.cc +++ b/src/comm/ConnOpener.cc @@ -190,16 +190,15 @@ Comm::ConnOpener::connect(const CommConnectCbParams &unused) if (conn_->getPeer()) conn_->getPeer()->stats.conn_open++; + lookupLocalAddress(); + /* TODO: remove these fd_table accesses. But old code still depends on fd_table flags to * indicate the state of a raw fd object being passed around. * Also, legacy code still depends on comm_local_port() with no access to Comm::Connection * when those are done comm_local_port can become one of our member functions to do the below. */ fd_table[conn_->fd].flags.open = 1; - conn_->local.SetPort(comm_local_port(conn_->fd)); - if (conn_->local.IsAnyAddr()) { - conn_->local = fd_table[conn_->fd].local_addr; - } + fd_table[conn_->fd].local_addr = conn_->local; if (host_ != NULL) ipcacheMarkGoodAddr(host_, conn_->remote); @@ -230,6 +229,27 @@ Comm::ConnOpener::connect(const CommConnectCbParams &unused) } } +/** + * Lookup local-end address and port of the TCP link just opened. + * This ensure the connection local details are set correctly + */ +void +Comm::ConnOpener::lookupLocalAddress() +{ + struct addrinfo *addr = NULL; + conn_->local.InitAddrInfo(addr); + + if (getsockname(conn_->fd, addr->ai_addr, &(addr->ai_addrlen)) != 0) { + debugs(50, DBG_IMPORTANT, "ERROR: Failed to retrieve TCP/UDP details for socket: FD " << conn_->fd << ": " << xstrerror()); + conn_->local.FreeAddrInfo(addr); + return; + } + + conn_->local = *addr; + conn_->local.FreeAddrInfo(addr); + debugs(5, 6, HERE << "FD " << conn_->fd << ": conn.local=" << conn_->local); +} + /** Abort connection attempt. * Handles the case(s) when a partially setup connection gets closed early. */ diff --git a/src/comm/ConnOpener.h b/src/comm/ConnOpener.h index ec5aa3abae..e18a79fee6 100644 --- a/src/comm/ConnOpener.h +++ b/src/comm/ConnOpener.h @@ -41,6 +41,7 @@ private: void timeout(const CommTimeoutCbParams &unused); void doneConnecting(comm_err_t status, int xerrno); static void ConnectRetry(int fd, void *data); + void lookupLocalAddress(); private: char *host_; ///< domain name we are trying to connect to. -- 2.47.2