}
}
+/// 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
+}
+
*/
void UpdateRequestNotes(ConnStateData *csd, HttpRequest &request, NotePairs const ¬es);
+/// \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 */
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
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;
*
\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
}
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)
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;