]>
Commit | Line | Data |
---|---|---|
f892c2bf | 1 | /* |
bf95c10a | 2 | * Copyright (C) 1996-2022 The Squid Software Foundation and contributors |
e25c139f | 3 | * |
bbc27441 AJ |
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. | |
f892c2bf | 7 | */ |
8 | ||
bbc27441 AJ |
9 | /* DEBUG: section 46 Access Log */ |
10 | ||
582c2af2 | 11 | #include "squid.h" |
450e0c10 | 12 | #include "AccessLogEntry.h" |
3ad63615 | 13 | #include "acl/Checklist.h" |
cf1f23ee | 14 | #include "sbuf/Algorithms.h" |
d7f4a0b7 CT |
15 | #if USE_ADAPTATION |
16 | #include "adaptation/Config.h" | |
17 | #endif | |
cf1f23ee | 18 | #include "base/PackableStream.h" |
a011edee | 19 | #include "CachePeer.h" |
83b053a0 | 20 | #include "error/Detail.h" |
a011edee | 21 | #include "errorpage.h" |
31971e6a | 22 | #include "format/Token.h" |
582c2af2 | 23 | #include "globals.h" |
bbaf2685 | 24 | #include "hier_code.h" |
7684c4b1 | 25 | #include "HttpReply.h" |
26 | #include "HttpRequest.h" | |
1c7ae5ff | 27 | #include "log/access_log.h" |
38e16f92 | 28 | #include "log/Config.h" |
8f645002 | 29 | #include "log/CustomLog.h" |
82b7abe3 | 30 | #include "log/File.h" |
20efa1c2 | 31 | #include "log/Formats.h" |
0eb49b6d | 32 | #include "MemBuf.h" |
8822ebee | 33 | #include "mgr/Registration.h" |
1fa9b1a7 | 34 | #include "rfc1738.h" |
cf1f23ee | 35 | #include "sbuf/SBuf.h" |
4d5904f7 | 36 | #include "SquidConfig.h" |
a011edee | 37 | #include "Store.h" |
7684c4b1 | 38 | |
3d41e53a FC |
39 | #if USE_SQUID_EUI |
40 | #include "eui/Eui48.h" | |
41 | #include "eui/Eui64.h" | |
42 | #endif | |
43 | ||
cf1f23ee FC |
44 | #include <unordered_map> |
45 | ||
c3609322 | 46 | #if HEADERS_LOG |
47 | static Logfile *headerslog = NULL; | |
48 | #endif | |
a7c05555 | 49 | |
e66d7923 | 50 | #if MULTICAST_MISS_STREAM |
51 | static int mcast_miss_fd = -1; | |
62e76326 | 52 | |
e66d7923 | 53 | static struct sockaddr_in mcast_miss_to; |
9bea1d5b | 54 | static void mcast_encode(unsigned int *, size_t, const unsigned int *); |
e66d7923 | 55 | #endif |
56 | ||
20efa1c2 | 57 | #if USE_FORW_VIA_DB |
3ff65596 | 58 | |
2081cefa | 59 | using HeaderValueCountsElement = std::pair<const SBuf, uint64_t>; |
cf1f23ee FC |
60 | /// counts the number of header field value occurrences |
61 | using HeaderValueCounts = std::unordered_map<SBuf, uint64_t, std::hash<SBuf>, std::equal_to<SBuf>, PoolingAllocator<HeaderValueCountsElement> >; | |
62 | ||
63 | /// counts the number of HTTP Via header field value occurrences | |
64 | static HeaderValueCounts TheViaCounts; | |
9386f99d FC |
65 | /// counts the number of HTTP X-Forwarded-For header field value occurrences |
66 | static HeaderValueCounts TheForwardedCounts; | |
cf1f23ee | 67 | |
20efa1c2 | 68 | static OBJH fvdbDumpVia; |
9386f99d | 69 | static OBJH fvdbDumpForwarded; |
20efa1c2 AJ |
70 | static void fvdbClear(void); |
71 | static void fvdbRegisterWithCacheManager(); | |
3ff65596 AR |
72 | #endif |
73 | ||
20efa1c2 | 74 | int LogfileStatus = LOG_DISABLE; |
3ff65596 | 75 | |
e1381638 | 76 | void |
63ed9e8e | 77 | accessLogLogTo(CustomLog *log, const AccessLogEntryPointer &al, ACLChecklist *checklist) |
3ff65596 | 78 | { |
62e76326 | 79 | |
f57ae909 NH |
80 | if (al->url.isEmpty()) |
81 | al->url = Format::Dash; | |
62e76326 | 82 | |
9bea1d5b | 83 | if (!al->http.content_type || *al->http.content_type == '\0') |
62e76326 | 84 | al->http.content_type = dash_str; |
85 | ||
9bea1d5b | 86 | if (al->hier.host[0] == '\0') |
62e76326 | 87 | xstrncpy(al->hier.host, dash_str, SQUIDHOSTNAMELEN); |
9bea1d5b | 88 | |
3ff65596 | 89 | for (; log; log = log->next) { |
06bf5384 | 90 | if (log->aclList && checklist && !checklist->fastCheck(log->aclList).allowed()) |
7684c4b1 | 91 | continue; |
62e76326 | 92 | |
80b2b3c5 AJ |
93 | // The special-case "none" type has no logfile object set |
94 | if (log->type == Log::Format::CLF_NONE) | |
95 | return; | |
96 | ||
82b7abe3 AJ |
97 | if (log->logfile) { |
98 | logfileLineStart(log->logfile); | |
7684c4b1 | 99 | |
82b7abe3 | 100 | switch (log->type) { |
7684c4b1 | 101 | |
20efa1c2 AJ |
102 | case Log::Format::CLF_SQUID: |
103 | Log::Format::SquidNative(al, log->logfile); | |
104 | break; | |
105 | ||
106 | case Log::Format::CLF_COMBINED: | |
107 | Log::Format::HttpdCombined(al, log->logfile); | |
108 | break; | |
109 | ||
110 | case Log::Format::CLF_COMMON: | |
111 | Log::Format::HttpdCommon(al, log->logfile); | |
82b7abe3 | 112 | break; |
7684c4b1 | 113 | |
20efa1c2 AJ |
114 | case Log::Format::CLF_REFERER: |
115 | Log::Format::SquidReferer(al, log->logfile); | |
82b7abe3 | 116 | break; |
7684c4b1 | 117 | |
20efa1c2 AJ |
118 | case Log::Format::CLF_USERAGENT: |
119 | Log::Format::SquidUserAgent(al, log->logfile); | |
82b7abe3 | 120 | break; |
7684c4b1 | 121 | |
20efa1c2 AJ |
122 | case Log::Format::CLF_CUSTOM: |
123 | Log::Format::SquidCustom(al, log); | |
82b7abe3 | 124 | break; |
7684c4b1 | 125 | |
3ff65596 | 126 | #if ICAP_CLIENT |
20efa1c2 AJ |
127 | case Log::Format::CLF_ICAP_SQUID: |
128 | Log::Format::SquidIcap(al, log->logfile); | |
82b7abe3 | 129 | break; |
3ff65596 AR |
130 | #endif |
131 | ||
82b7abe3 AJ |
132 | default: |
133 | fatalf("Unknown log format %d\n", log->type); | |
134 | break; | |
135 | } | |
7684c4b1 | 136 | |
82b7abe3 | 137 | logfileLineEnd(log->logfile); |
7684c4b1 | 138 | } |
139 | ||
82b7abe3 | 140 | // NP: WTF? if _any_ log line has no checklist ignore the following ones? |
7684c4b1 | 141 | if (!checklist) |
142 | break; | |
f892c2bf | 143 | } |
3ff65596 | 144 | } |
7684c4b1 | 145 | |
3ff65596 | 146 | void |
63ed9e8e | 147 | accessLogLog(const AccessLogEntryPointer &al, ACLChecklist *checklist) |
3ff65596 AR |
148 | { |
149 | if (LogfileStatus != LOG_ENABLE) | |
150 | return; | |
e1381638 | 151 | |
3ff65596 | 152 | accessLogLogTo(Config.Log.accesslogs, al, checklist); |
e66d7923 | 153 | #if MULTICAST_MISS_STREAM |
62e76326 | 154 | |
9bea1d5b | 155 | if (al->cache.code != LOG_TCP_MISS) |
62e76326 | 156 | (void) 0; |
9bea1d5b | 157 | else if (al->http.method != METHOD_GET) |
62e76326 | 158 | (void) 0; |
9bea1d5b | 159 | else if (mcast_miss_fd < 0) |
62e76326 | 160 | (void) 0; |
9bea1d5b | 161 | else { |
62e76326 | 162 | unsigned int ibuf[365]; |
163 | size_t isize; | |
f57ae909 NH |
164 | xstrncpy((char *) ibuf, al->url.c_str(), 364 * sizeof(int)); |
165 | isize = ((al->url.length() + 8) / 8) * 2; | |
62e76326 | 166 | |
167 | if (isize > 364) | |
168 | isize = 364; | |
169 | ||
170 | mcast_encode((unsigned int *) ibuf, isize, | |
171 | (const unsigned int *) Config.mcast_miss.encode_key); | |
172 | ||
173 | comm_udp_sendto(mcast_miss_fd, | |
174 | &mcast_miss_to, sizeof(mcast_miss_to), | |
175 | ibuf, isize * sizeof(int)); | |
e66d7923 | 176 | } |
62e76326 | 177 | |
e66d7923 | 178 | #endif |
f892c2bf | 179 | } |
180 | ||
181 | void | |
9bea1d5b | 182 | accessLogRotate(void) |
f892c2bf | 183 | { |
87ddff6e | 184 | CustomLog *log; |
21f6708d | 185 | #if USE_FORW_VIA_DB |
7684c4b1 | 186 | |
9bea1d5b | 187 | fvdbClear(); |
d21f1c54 | 188 | #endif |
62e76326 | 189 | |
7684c4b1 | 190 | for (log = Config.Log.accesslogs; log; log = log->next) { |
39d7714a | 191 | log->rotate(); |
7684c4b1 | 192 | } |
62e76326 | 193 | |
c3609322 | 194 | #if HEADERS_LOG |
62e76326 | 195 | |
efc23871 | 196 | logfileRotate(headerslog, Config.Log.rotateNumber); |
62e76326 | 197 | |
c3609322 | 198 | #endif |
f892c2bf | 199 | } |
200 | ||
201 | void | |
9bea1d5b | 202 | accessLogClose(void) |
f892c2bf | 203 | { |
87ddff6e | 204 | CustomLog *log; |
62e76326 | 205 | |
7684c4b1 | 206 | for (log = Config.Log.accesslogs; log; log = log->next) { |
207 | if (log->logfile) { | |
208 | logfileClose(log->logfile); | |
aee3523a | 209 | log->logfile = nullptr; |
7684c4b1 | 210 | } |
211 | } | |
62e76326 | 212 | |
c3609322 | 213 | #if HEADERS_LOG |
62e76326 | 214 | |
9bea1d5b | 215 | logfileClose(headerslog); |
62e76326 | 216 | |
9bea1d5b | 217 | headerslog = NULL; |
62e76326 | 218 | |
c3609322 | 219 | #endif |
f892c2bf | 220 | } |
221 | ||
b24880fe | 222 | HierarchyLogEntry::HierarchyLogEntry() : |
f53969cc SM |
223 | code(HIER_NONE), |
224 | cd_lookup(LOOKUP_NONE), | |
225 | n_choices(0), | |
226 | n_ichoices(0), | |
227 | peer_reply_status(Http::scNone), | |
aee3523a | 228 | tcpServer(nullptr), |
f53969cc | 229 | bodyBytesRead(-1) |
b24880fe | 230 | { |
231 | memset(host, '\0', SQUIDHOSTNAMELEN); | |
232 | memset(cd_host, '\0', SQUIDHOSTNAMELEN); | |
233 | ||
234 | peer_select_start.tv_sec =0; | |
235 | peer_select_start.tv_usec =0; | |
236 | ||
237 | store_complete_stop.tv_sec =0; | |
238 | store_complete_stop.tv_usec =0; | |
3ff65596 | 239 | |
d8165775 | 240 | clearPeerNotes(); |
01bd87d8 CT |
241 | |
242 | totalResponseTime_.tv_sec = -1; | |
243 | totalResponseTime_.tv_usec = 0; | |
244 | ||
16b70e2a CT |
245 | firstConnStart_.tv_sec = 0; |
246 | firstConnStart_.tv_usec = 0; | |
b24880fe | 247 | } |
248 | ||
f892c2bf | 249 | void |
d8165775 | 250 | HierarchyLogEntry::resetPeerNotes(const Comm::ConnectionPointer &server, const char *requestedHost) |
f892c2bf | 251 | { |
d8165775 AR |
252 | clearPeerNotes(); |
253 | ||
a14f38d0 | 254 | tcpServer = server; |
aee3523a | 255 | if (tcpServer == nullptr) { |
c69ef286 A |
256 | code = HIER_NONE; |
257 | xstrncpy(host, requestedHost, sizeof(host)); | |
a14f38d0 AJ |
258 | } else { |
259 | code = tcpServer->peerType; | |
260 | ||
261 | if (tcpServer->getPeer()) { | |
262 | // went to peer, log peer host name | |
263 | xstrncpy(host, tcpServer->getPeer()->name, sizeof(host)); | |
264 | } else { | |
8652f8e7 | 265 | xstrncpy(host, requestedHost, sizeof(host)); |
a14f38d0 AJ |
266 | } |
267 | } | |
f892c2bf | 268 | } |
7a2f978b | 269 | |
d8165775 AR |
270 | /// forget previous notePeerRead() and notePeerWrite() calls (if any) |
271 | void | |
272 | HierarchyLogEntry::clearPeerNotes() | |
273 | { | |
274 | peer_last_read_.tv_sec = 0; | |
275 | peer_last_read_.tv_usec = 0; | |
276 | ||
277 | peer_last_write_.tv_sec = 0; | |
278 | peer_last_write_.tv_usec = 0; | |
279 | ||
280 | bodyBytesRead = -1; | |
281 | } | |
282 | ||
283 | void | |
284 | HierarchyLogEntry::notePeerRead() | |
285 | { | |
286 | peer_last_read_ = current_time; | |
287 | } | |
288 | ||
289 | void | |
290 | HierarchyLogEntry::notePeerWrite() | |
291 | { | |
292 | peer_last_write_ = current_time; | |
293 | } | |
294 | ||
16b70e2a CT |
295 | void |
296 | HierarchyLogEntry::startPeerClock() | |
297 | { | |
298 | if (!firstConnStart_.tv_sec) | |
299 | firstConnStart_ = current_time; | |
300 | } | |
301 | ||
302 | void | |
bd1be2ae A |
303 | HierarchyLogEntry::stopPeerClock(const bool force) |
304 | { | |
d8ee9e8d | 305 | debugs(46, 5, "First connection started: " << firstConnStart_ << |
01bd87d8 | 306 | ", current total response time value: " << (totalResponseTime_.tv_sec * 1000 + totalResponseTime_.tv_usec/1000) << |
16b70e2a | 307 | (force ? ", force fixing" : "")); |
01bd87d8 | 308 | if (!force && totalResponseTime_.tv_sec != -1) |
16b70e2a CT |
309 | return; |
310 | ||
01bd87d8 CT |
311 | if (firstConnStart_.tv_sec) |
312 | tvSub(totalResponseTime_, firstConnStart_, current_time); | |
16b70e2a CT |
313 | } |
314 | ||
d8165775 AR |
315 | bool |
316 | HierarchyLogEntry::peerResponseTime(struct timeval &responseTime) | |
317 | { | |
318 | // no I/O whatsoever | |
319 | if (peer_last_write_.tv_sec <= 0 && peer_last_read_.tv_sec <= 0) | |
320 | return false; | |
321 | ||
322 | // accommodate read without (completed) write | |
323 | const auto last_write = peer_last_write_.tv_sec > 0 ? | |
ee1d6f66 | 324 | peer_last_write_ : peer_last_read_; |
d8165775 AR |
325 | |
326 | // accommodate write without (completed) read | |
327 | const auto last_read = peer_last_read_.tv_sec > 0 ? | |
ee1d6f66 | 328 | peer_last_read_ : peer_last_write_; |
d8165775 AR |
329 | |
330 | tvSub(responseTime, last_write, last_read); | |
331 | // The peer response time (%<pt) stopwatch is currently defined to start | |
332 | // when we wrote the entire request. Thus, if we wrote something after the | |
333 | // last read, report zero peer response time. | |
334 | if (responseTime.tv_sec < 0) { | |
335 | responseTime.tv_sec = 0; | |
336 | responseTime.tv_usec = 0; | |
337 | } | |
338 | ||
339 | return true; | |
340 | } | |
341 | ||
342 | bool | |
01bd87d8 | 343 | HierarchyLogEntry::totalResponseTime(struct timeval &responseTime) |
16b70e2a CT |
344 | { |
345 | // This should not really happen, but there may be rare code | |
346 | // paths that lead to FwdState discarded (or transaction logged) | |
347 | // without (or before) a stopPeerClock() call. | |
01bd87d8 | 348 | if (firstConnStart_.tv_sec && totalResponseTime_.tv_sec == -1) |
16b70e2a CT |
349 | stopPeerClock(false); |
350 | ||
01bd87d8 | 351 | responseTime = totalResponseTime_; |
d8165775 | 352 | return responseTime.tv_sec >= 0 && responseTime.tv_usec >= 0; |
16b70e2a CT |
353 | } |
354 | ||
5f5e883f FC |
355 | static void |
356 | accessLogRegisterWithCacheManager(void) | |
357 | { | |
21f6708d | 358 | #if USE_FORW_VIA_DB |
5f5e883f FC |
359 | fvdbRegisterWithCacheManager(); |
360 | #endif | |
361 | } | |
362 | ||
7a2f978b | 363 | void |
9bea1d5b | 364 | accessLogInit(void) |
7a2f978b | 365 | { |
87ddff6e | 366 | CustomLog *log; |
caf0eda4 FC |
367 | |
368 | accessLogRegisterWithCacheManager(); | |
369 | ||
190d8192 | 370 | #if USE_ADAPTATION |
38e16f92 | 371 | Log::TheConfig.hasAdaptToken = false; |
190d8192 AJ |
372 | #endif |
373 | #if ICAP_CLIENT | |
38e16f92 | 374 | Log::TheConfig.hasIcapToken = false; |
190d8192 AJ |
375 | #endif |
376 | ||
7684c4b1 | 377 | for (log = Config.Log.accesslogs; log; log = log->next) { |
20efa1c2 | 378 | if (log->type == Log::Format::CLF_NONE) |
7684c4b1 | 379 | continue; |
62e76326 | 380 | |
fb0c2f17 | 381 | log->logfile = logfileOpen(log->filename, log->bufferSize, log->fatal); |
62e76326 | 382 | |
7684c4b1 | 383 | LogfileStatus = LOG_ENABLE; |
3ff65596 | 384 | |
3ff65596 | 385 | #if USE_ADAPTATION |
aee3523a | 386 | for (Format::Token * curr_token = (log->logFormat?log->logFormat->format:nullptr); curr_token; curr_token = curr_token->next) { |
31971e6a AJ |
387 | if (curr_token->type == Format::LFT_ADAPTATION_SUM_XACT_TIMES || |
388 | curr_token->type == Format::LFT_ADAPTATION_ALL_XACT_TIMES || | |
38e16f92 AJ |
389 | curr_token->type == Format::LFT_ADAPTATION_LAST_HEADER || |
390 | curr_token->type == Format::LFT_ADAPTATION_LAST_HEADER_ELEM || | |
d7f4a0b7 CT |
391 | curr_token->type == Format::LFT_ADAPTATION_LAST_ALL_HEADERS|| |
392 | (curr_token->type == Format::LFT_NOTE && !Adaptation::Config::metaHeaders.empty())) { | |
38e16f92 | 393 | Log::TheConfig.hasAdaptToken = true; |
3ff65596 | 394 | } |
3ff65596 | 395 | #if ICAP_CLIENT |
38e16f92 AJ |
396 | if (curr_token->type == Format::LFT_ICAP_TOTAL_TIME) { |
397 | Log::TheConfig.hasIcapToken = true; | |
3ff65596 AR |
398 | } |
399 | #endif | |
400 | } | |
401 | #endif | |
7684c4b1 | 402 | } |
62e76326 | 403 | |
c3609322 | 404 | #if HEADERS_LOG |
62e76326 | 405 | |
9bea1d5b | 406 | headerslog = logfileOpen("/usr/local/squid/logs/headers.log", 512); |
62e76326 | 407 | |
9bea1d5b | 408 | assert(NULL != headerslog); |
62e76326 | 409 | |
d21f1c54 | 410 | #endif |
e66d7923 | 411 | #if MULTICAST_MISS_STREAM |
62e76326 | 412 | |
9bea1d5b | 413 | if (Config.mcast_miss.addr.s_addr != no_addr.s_addr) { |
62e76326 | 414 | memset(&mcast_miss_to, '\0', sizeof(mcast_miss_to)); |
415 | mcast_miss_to.sin_family = AF_INET; | |
416 | mcast_miss_to.sin_port = htons(Config.mcast_miss.port); | |
417 | mcast_miss_to.sin_addr.s_addr = Config.mcast_miss.addr.s_addr; | |
418 | mcast_miss_fd = comm_open(SOCK_DGRAM, | |
bdb741f4 | 419 | IPPROTO_UDP, |
62e76326 | 420 | Config.Addrs.udp_incoming, |
421 | Config.mcast_miss.port, | |
422 | COMM_NONBLOCKING, | |
423 | "Multicast Miss Stream"); | |
424 | ||
425 | if (mcast_miss_fd < 0) | |
426 | fatal("Cannot open Multicast Miss Stream Socket"); | |
427 | ||
e0236918 | 428 | debugs(46, DBG_IMPORTANT, "Multicast Miss Stream Socket opened on FD " << mcast_miss_fd); |
62e76326 | 429 | |
430 | mcastSetTtl(mcast_miss_fd, Config.mcast_miss.ttl); | |
431 | ||
432 | if (strlen(Config.mcast_miss.encode_key) < 16) | |
433 | fatal("mcast_encode_key is too short, must be 16 characters"); | |
e66d7923 | 434 | } |
62e76326 | 435 | |
62ee09ca | 436 | #endif |
437 | } | |
438 | ||
21f6708d | 439 | #if USE_FORW_VIA_DB |
1afe05c5 | 440 | |
62ee09ca | 441 | static void |
caf0eda4 | 442 | fvdbRegisterWithCacheManager(void) |
62ee09ca | 443 | { |
8822ebee AR |
444 | Mgr::RegisterAction("via_headers", "Via Request Headers", fvdbDumpVia, 0, 1); |
445 | Mgr::RegisterAction("forw_headers", "X-Forwarded-For Request Headers", | |
9386f99d | 446 | fvdbDumpForwarded, 0, 1); |
d21f1c54 | 447 | } |
448 | ||
449 | void | |
cf1f23ee | 450 | fvdbCountVia(const SBuf &headerValue) |
d21f1c54 | 451 | { |
cf1f23ee | 452 | ++TheViaCounts[headerValue]; |
d21f1c54 | 453 | } |
454 | ||
455 | void | |
9386f99d | 456 | fvdbCountForwarded(const SBuf &key) |
d21f1c54 | 457 | { |
9386f99d | 458 | ++TheForwardedCounts[key]; |
d21f1c54 | 459 | } |
460 | ||
cf1f23ee FC |
461 | static void |
462 | fvdbDumpCounts(StoreEntry &e, const HeaderValueCounts &counts) | |
463 | { | |
464 | PackableStream os(e); | |
465 | for (const auto &i : counts) | |
466 | os << std::setw(9) << i.second << ' ' << i.first << "\n"; | |
467 | } | |
468 | ||
d21f1c54 | 469 | static void |
9bea1d5b | 470 | fvdbDumpVia(StoreEntry * e) |
d21f1c54 | 471 | { |
cf1f23ee FC |
472 | assert(e); |
473 | fvdbDumpCounts(*e, TheViaCounts); | |
d21f1c54 | 474 | } |
1afe05c5 | 475 | |
d21f1c54 | 476 | static void |
9386f99d | 477 | fvdbDumpForwarded(StoreEntry * e) |
d21f1c54 | 478 | { |
9386f99d FC |
479 | assert(e); |
480 | fvdbDumpCounts(*e, TheForwardedCounts); | |
d21f1c54 | 481 | } |
482 | ||
483 | static void | |
9bea1d5b | 484 | fvdbClear(void) |
d21f1c54 | 485 | { |
cf1f23ee | 486 | TheViaCounts.clear(); |
9386f99d | 487 | TheForwardedCounts.clear(); |
d21f1c54 | 488 | } |
489 | ||
1afe05c5 | 490 | #endif |
e66d7923 | 491 | |
492 | #if MULTICAST_MISS_STREAM | |
493 | /* | |
494 | * From http://www.io.com/~paulhart/game/algorithms/tea.html | |
495 | * | |
496 | * size of 'ibuf' must be a multiple of 2. | |
497 | * size of 'key' must be 4. | |
498 | * 'ibuf' is modified in place, encrypted data is written in | |
499 | * network byte order. | |
500 | */ | |
501 | static void | |
9bea1d5b | 502 | mcast_encode(unsigned int *ibuf, size_t isize, const unsigned int *key) |
e66d7923 | 503 | { |
9bea1d5b | 504 | unsigned int y; |
505 | unsigned int z; | |
506 | unsigned int sum; | |
507 | const unsigned int delta = 0x9e3779b9; | |
508 | unsigned int n = 32; | |
509 | const unsigned int k0 = htonl(key[0]); | |
510 | const unsigned int k1 = htonl(key[1]); | |
511 | const unsigned int k2 = htonl(key[2]); | |
512 | const unsigned int k3 = htonl(key[3]); | |
513 | int i; | |
62e76326 | 514 | |
9bea1d5b | 515 | for (i = 0; i < isize; i += 2) { |
62e76326 | 516 | y = htonl(ibuf[i]); |
517 | z = htonl(ibuf[i + 1]); | |
518 | sum = 0; | |
519 | ||
5e263176 | 520 | for (n = 32; n; --n) { |
62e76326 | 521 | sum += delta; |
522 | y += (z << 4) + (k0 ^ z) + (sum ^ (z >> 5)) + k1; | |
523 | z += (y << 4) + (k2 ^ y) + (sum ^ (y >> 5)) + k3; | |
524 | } | |
525 | ||
526 | ibuf[i] = htonl(y); | |
527 | ibuf[i + 1] = htonl(z); | |
e66d7923 | 528 | } |
529 | } | |
530 | ||
531 | #endif | |
c3609322 | 532 | |
533 | #if HEADERS_LOG | |
534 | void | |
60745f24 | 535 | headersLog(int cs, int pq, const HttpRequestMethod& method, void *data) |
c3609322 | 536 | { |
9bea1d5b | 537 | HttpReply *rep; |
190154cf | 538 | HttpRequest *req; |
9bea1d5b | 539 | unsigned short magic = 0; |
540 | unsigned char M = (unsigned char) m; | |
9bea1d5b | 541 | char *hmask; |
542 | int ccmask = 0; | |
62e76326 | 543 | |
9bea1d5b | 544 | if (0 == pq) { |
62e76326 | 545 | /* reply */ |
546 | rep = data; | |
547 | req = NULL; | |
548 | magic = 0x0050; | |
549 | hmask = rep->header.mask; | |
550 | ||
551 | if (rep->cache_control) | |
552 | ccmask = rep->cache_control->mask; | |
9bea1d5b | 553 | } else { |
62e76326 | 554 | /* request */ |
555 | req = data; | |
556 | rep = NULL; | |
557 | magic = 0x0051; | |
558 | hmask = req->header.mask; | |
559 | ||
560 | if (req->cache_control) | |
561 | ccmask = req->cache_control->mask; | |
c3609322 | 562 | } |
62e76326 | 563 | |
9bea1d5b | 564 | if (0 == cs) { |
62e76326 | 565 | /* client */ |
566 | magic |= 0x4300; | |
9bea1d5b | 567 | } else { |
62e76326 | 568 | /* server */ |
569 | magic |= 0x5300; | |
c3609322 | 570 | } |
62e76326 | 571 | |
9bea1d5b | 572 | magic = htons(magic); |
573 | ccmask = htonl(ccmask); | |
62e76326 | 574 | |
9b769c67 | 575 | unsigned short S = 0; |
9bea1d5b | 576 | if (0 == pq) |
9b769c67 | 577 | S = static_cast<unsigned short>(rep->sline.status()); |
62e76326 | 578 | |
9bea1d5b | 579 | logfileWrite(headerslog, &magic, sizeof(magic)); |
580 | logfileWrite(headerslog, &M, sizeof(M)); | |
581 | logfileWrite(headerslog, &S, sizeof(S)); | |
582 | logfileWrite(headerslog, hmask, sizeof(HttpHeaderMask)); | |
583 | logfileWrite(headerslog, &ccmask, sizeof(int)); | |
c3609322 | 584 | } |
585 | ||
586 | #endif | |
f53969cc | 587 |