]> git.ipfire.org Git - thirdparty/squid.git/blame - src/AccessLogEntry.cc
Detail client closures of CONNECT tunnels during TLS handshake (#691)
[thirdparty/squid.git] / src / AccessLogEntry.cc
CommitLineData
bbc27441 1/*
77b1029d 2 * Copyright (C) 1996-2020 The Squid Software Foundation and contributors
bbc27441
AJ
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
7 */
8
f7f3304a 9#include "squid.h"
d4204018 10#include "AccessLogEntry.h"
582c2af2 11#include "HttpReply.h"
d4204018 12#include "HttpRequest.h"
49f57088 13#include "MemBuf.h"
36c774f7 14#include "proxyp/Header.h"
4d5904f7 15#include "SquidConfig.h"
f3d7d090
AJ
16#include "ssl/support.h"
17
d4204018
AJ
18void
19AccessLogEntry::getLogClientIp(char *buf, size_t bufsz) const
20{
998ef291
AJ
21 Ip::Address log_ip;
22
d4204018
AJ
23#if FOLLOW_X_FORWARDED_FOR
24 if (Config.onoff.log_uses_indirect_client && request)
998ef291 25 log_ip = request->indirect_client_addr;
d4204018
AJ
26 else
27#endif
705c36c6 28 if (tcpClient)
998ef291 29 log_ip = tcpClient->remote;
705c36c6 30 else
998ef291
AJ
31 log_ip = cache.caddr;
32
705c36c6
AJ
33 // internally generated requests (and some ICAP) lack client IP
34 if (log_ip.isNoAddr()) {
35 strncpy(buf, "-", bufsz);
36 return;
37 }
38
998ef291
AJ
39 // Apply so-called 'privacy masking' to IPv4 clients
40 // - localhost IP is always shown in full
41 // - IPv4 clients masked with client_netmask
42 // - IPv6 clients use 'privacy addressing' instead.
43
36c774f7 44 log_ip.applyClientMask(Config.Addrs.client_netmask);
998ef291
AJ
45
46 log_ip.toStr(buf, bufsz);
d4204018 47}
41ebd397 48
58b148e1
AJ
49SBuf
50AccessLogEntry::getLogMethod() const
51{
ec2c4acf 52 static const SBuf dash("-");
58b148e1
AJ
53 SBuf method;
54 if (icp.opcode)
55 method.append(icp_opcode_str[icp.opcode]);
56 else if (htcp.opcode)
57 method.append(htcp.opcode);
ec2c4acf 58 else if (http.method)
58b148e1 59 method = http.method.image();
ec2c4acf
AR
60 else
61 method = dash;
58b148e1
AJ
62 return method;
63}
64
75d47340
CT
65void
66AccessLogEntry::syncNotes(HttpRequest *req)
67{
68 // XXX: auth code only has access to HttpRequest being authenticated
69 // so we must handle the case where HttpRequest is set without ALE being set.
70 assert(req);
71 if (!notes)
72 notes = req->notes();
73 else
74 assert(notes == req->notes());
75}
76
e3bf07f5
AJ
77const char *
78AccessLogEntry::getClientIdent() const
79{
80 if (tcpClient)
81 return tcpClient->rfc931;
82
83 if (cache.rfc931 && *cache.rfc931)
84 return cache.rfc931;
85
86 return nullptr;
87}
88
89const char *
90AccessLogEntry::getExtUser() const
91{
92 if (request && request->extacl_user.size())
93 return request->extacl_user.termedBuf();
94
95 if (cache.extuser && *cache.extuser)
96 return cache.extuser;
97
98 return nullptr;
99}
100
36c774f7
EB
101AccessLogEntry::AccessLogEntry() {}
102
41ebd397
CT
103AccessLogEntry::~AccessLogEntry()
104{
105 safe_free(headers.request);
106
f5d0906a 107#if USE_ADAPTATION
41ebd397
CT
108 safe_free(adapt.last_meta);
109#endif
110
41ebd397
CT
111 safe_free(headers.adapted_request);
112 HTTPMSGUNLOCK(adapted_request);
113
4ff6370b 114 safe_free(lastAclName);
4ff6370b 115
41ebd397
CT
116 HTTPMSGUNLOCK(request);
117#if ICAP_CLIENT
118 HTTPMSGUNLOCK(icap.reply);
119 HTTPMSGUNLOCK(icap.request);
120#endif
41ebd397 121}
f53969cc 122
ccfbe8f4
AR
123ScopedId
124AccessLogEntry::codeContextGist() const
125{
126 if (request) {
127 if (const auto &mx = request->masterXaction)
128 return mx->id.detach();
129 }
130 // TODO: Carefully merge ALE and MasterXaction.
131 return ScopedId("ALE w/o master");
132}
133
134std::ostream &
135AccessLogEntry::detailCodeContext(std::ostream &os) const
136{
137 // TODO: Consider printing all instead of the first most important detail.
138
139 if (request) {
140 if (const auto &mx = request->masterXaction)
141 return os << Debug::Extra << "current master transaction: " << mx->id;
142 }
143
144 // provide helpful details since we cannot identify the transaction exactly
145
146 if (tcpClient)
147 return os << Debug::Extra << "current from-client connection: " << tcpClient;
148 else if (!cache.caddr.isNoAddr())
149 return os << Debug::Extra << "current client: " << cache.caddr;
150
151 const auto optionalMethod = [this,&os]() {
152 if (hasLogMethod())
153 os << getLogMethod() << ' ';
154 return "";
155 };
156 if (const auto uri = effectiveVirginUrl())
157 return os << Debug::Extra << "current client request: " << optionalMethod() << *uri;
158 else if (!url.isEmpty())
159 return os << Debug::Extra << "current request: " << optionalMethod() << url;
160 else if (hasLogMethod())
161 return os << Debug::Extra << "current request method: " << getLogMethod();
162
163 return os;
164}
165
bec110e4
EB
166const SBuf *
167AccessLogEntry::effectiveVirginUrl() const
168{
57a5679b 169 const SBuf *effectiveUrl = request ? &request->effectiveRequestUri() : &virginUrlForMissingRequest_;
bec110e4
EB
170 if (effectiveUrl && !effectiveUrl->isEmpty())
171 return effectiveUrl;
172 // We can not use ALE::url here because it may contain a request URI after
173 // adaptation/redirection. When the request is missing, a non-empty ALE::url
174 // means that we missed a setVirginUrlForMissingRequest() call somewhere.
175 return nullptr;
176}
177
83b053a0
CT
178const Error *
179AccessLogEntry::error() const
180{
181 // the order ensures that the first-imported error is returned
182 if (error_) // updateError() was called before importing the request
183 return &error_;
184 if (request && request->error) // request was imported before updateError()
185 return &request->error;
186 return nullptr; // we imported no errors and no requests
187}
188
189void
190AccessLogEntry::updateError(const Error &err)
191{
192 // the order ensures that error() returns the first-imported error
193 if (request)
194 request->error.update(err);
195 else
196 error_.update(err);
197}
198
49f57088
EB
199void
200AccessLogEntry::packReplyHeaders(MemBuf &mb) const
201{
202 if (reply)
203 reply->packHeadersUsingFastPacker(mb);
204}
205