]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
New function to find Local listening IP and add new %A macro (#198) M-staged-PR198
authorAmish <amishxda@users.noreply.github.com>
Wed, 16 May 2018 19:09:52 +0000 (19:09 +0000)
committerSquid Anubis <squid-anubis@squid-cache.org>
Thu, 17 May 2018 02:38:21 +0000 (02:38 +0000)
Implemented a new function to find local listening IP:Port in a
consistent way and added support for %A macro in error pages and
deny_info URL using the same function.

src/HttpRequest.cc
src/HttpRequest.h
src/cf.data.pre
src/errorpage.cc
src/errorpage.h
src/format/Format.cc

index 54e86bd67111fb05494ec63f093e353fd9840969..5a2417385ea1822a31c624b24924034aeb241134 100644 (file)
@@ -739,3 +739,52 @@ HttpRequest::manager(const CbcPointer<ConnStateData> &aMgr, const AccessLogEntry
     }
 }
 
+/// a helper for validating FindListeningPortAddress()-found address candidates
+static const Ip::Address *
+FindListeningPortAddressInAddress(const Ip::Address *ip)
+{
+    // FindListeningPortAddress() callers do not want INADDR_ANY addresses
+    return (ip && !ip->isAnyAddr()) ? ip : nullptr;
+}
+
+/// a helper for handling PortCfg cases of FindListeningPortAddress()
+static const Ip::Address *
+FindListeningPortAddressInPort(const AnyP::PortCfgPointer &port)
+{
+    return port ? FindListeningPortAddressInAddress(&port->s) : nullptr;
+}
+
+/// a helper for handling Connection cases of FindListeningPortAddress()
+static const Ip::Address *
+FindListeningPortAddressInConn(const Comm::ConnectionPointer &conn)
+{
+    return conn ? FindListeningPortAddressInAddress(&conn->local) : nullptr;
+}
+
+const Ip::Address *
+FindListeningPortAddress(const HttpRequest *callerRequest, const AccessLogEntry *ale)
+{
+    // Check all sources of usable listening port information, giving
+    // HttpRequest and masterXaction a preference over ALE.
+
+    const HttpRequest *request = callerRequest;
+    if (!request && ale)
+        request = ale->request;
+    if (!request)
+        return nullptr; // not enough information
+
+    const Ip::Address *ip = FindListeningPortAddressInPort(request->masterXaction->squidPort);
+    if (!ip && ale)
+        ip = FindListeningPortAddressInPort(ale->cache.port);
+
+    // XXX: also handle PROXY protocol here when we have a flag to identify such request
+    if (ip || request->flags.interceptTproxy || request->flags.intercepted)
+        return ip;
+
+    /* handle non-intercepted cases that were not handled above */
+    ip = FindListeningPortAddressInConn(request->masterXaction->tcpClient);
+    if (!ip && ale)
+        ip = FindListeningPortAddressInConn(ale->tcpClient);
+    return ip; // may still be nil
+}
+
index 029ebeacfd32d988893d9d591024af4e6fcd6484..a963883885035ba2175f2e2b678a4263871b42a5 100644 (file)
@@ -254,5 +254,9 @@ class ConnStateData;
  */
 void UpdateRequestNotes(ConnStateData *csd, HttpRequest &request, NotePairs const &notes);
 
+/// \returns listening/*_port address used by the client connection (or nil)
+/// nil parameter(s) indicate missing caller information and are handled safely
+const Ip::Address *FindListeningPortAddress(const HttpRequest *, const AccessLogEntry *);
+
 #endif /* SQUID_HTTPREQUEST_H */
 
index 74747ad2d0111c3c7fc173d20671f0517351030f..f13a7e2b9ea4f435061187c301ba88f55af332df 100644 (file)
@@ -8451,6 +8451,7 @@ DOC_START
 
        URL FORMAT TAGS:
                %a      - username (if available. Password NOT included)
+               %A      - Local listening IP address the client connection was connected to
                %B      - FTP path URL
                %e      - Error number
                %E      - Error description
index 233e7420668c51f929dfb7141e18dddfa845d3ca..5d9d6be9da17abc1a21a4ac334274654b209c101 100644 (file)
@@ -758,6 +758,14 @@ ErrorState::Convert(char token, bool building_deny_info_url, bool allowRecursion
             p = "-";
         break;
 
+    case 'A':
+        // TODO: When/if we get ALE here, pass it as well
+        if (const auto addr = FindListeningPortAddress(request.getRaw(), nullptr))
+            mb.appendf("%s", addr->toStr(ntoabuf, MAX_IPSTRLEN));
+        else
+            p = "-";
+        break;
+
     case 'b':
         mb.appendf("%u", getMyPort());
         break;
index addc8e5c06f351b785155e0b4643499d8c63aa89..18c173bbf811b0feeba9e164f31bbecdbc7e3842 100644 (file)
@@ -35,6 +35,7 @@ typedef void ERCB(int fd, void *, size_t);
  *
  \verbatim
    a - User identity                            x
+   A - Local listening IP address               x
    B - URL with FTP %2f hack                    x
    c - Squid error code                         x
    d - seconds elapsed since request received   x
index cc2c57744330808dc0a2a655cb7341464bf572da..f1a80800864d245d57388ca4d9ce04e9e2c414a0 100644 (file)
@@ -470,20 +470,10 @@ Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logS
             }
             break;
 
-        case LFT_LOCAL_LISTENING_IP: {
-            // avoid logging a dash if we have reliable info
-            const bool interceptedAtKnownPort = al->request ?
-                                                (al->request->flags.interceptTproxy ||
-                                                 al->request->flags.intercepted) && al->cache.port :
-                                                false;
-            if (interceptedAtKnownPort) {
-                const bool portAddressConfigured = !al->cache.port->s.isAnyAddr();
-                if (portAddressConfigured)
-                    out = al->cache.port->s.toStr(tmp, sizeof(tmp));
-            } else if (al->tcpClient)
-                out = al->tcpClient->local.toStr(tmp, sizeof(tmp));
-        }
-        break;
+        case LFT_LOCAL_LISTENING_IP:
+            if (const auto addr = FindListeningPortAddress(nullptr, al.getRaw()))
+                out = addr->toStr(tmp, sizeof(tmp));
+            break;
 
         case LFT_CLIENT_LOCAL_IP:
             if (al->tcpClient)
@@ -505,11 +495,8 @@ Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logS
             break;
 
         case LFT_LOCAL_LISTENING_PORT:
-            if (al->cache.port) {
-                outint = al->cache.port->s.port();
-                doint = 1;
-            } else if (al->request) {
-                outint = al->request->my_addr.port();
+            if (const auto addr = FindListeningPortAddress(nullptr, al.getRaw())) {
+                outint = addr->port();
                 doint = 1;
             }
             break;