]>
Commit | Line | Data |
---|---|---|
f892c2bf | 1 | |
2 | /* | |
528b2c61 | 3 | * $Id: access_log.cc,v 1.79 2003/01/23 00:37:15 robertc Exp $ |
f892c2bf | 4 | * |
5 | * DEBUG: section 46 Access Log | |
6 | * AUTHOR: Duane Wessels | |
7 | * | |
2b6662ba | 8 | * SQUID Web Proxy Cache http://www.squid-cache.org/ |
e25c139f | 9 | * ---------------------------------------------------------- |
f892c2bf | 10 | * |
2b6662ba | 11 | * Squid is the result of efforts by numerous individuals from |
12 | * the Internet community; see the CONTRIBUTORS file for full | |
13 | * details. Many organizations have provided support for Squid's | |
14 | * development; see the SPONSORS file for full details. Squid is | |
15 | * Copyrighted (C) 2001 by the Regents of the University of | |
16 | * California; see the COPYRIGHT file for full details. Squid | |
17 | * incorporates software developed and/or copyrighted by other | |
18 | * sources; see the CREDITS file for full details. | |
f892c2bf | 19 | * |
20 | * This program is free software; you can redistribute it and/or modify | |
21 | * it under the terms of the GNU General Public License as published by | |
22 | * the Free Software Foundation; either version 2 of the License, or | |
23 | * (at your option) any later version. | |
24 | * | |
25 | * This program is distributed in the hope that it will be useful, | |
26 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
27 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
28 | * GNU General Public License for more details. | |
29 | * | |
30 | * You should have received a copy of the GNU General Public License | |
31 | * along with this program; if not, write to the Free Software | |
cbdec147 | 32 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. |
e25c139f | 33 | * |
f892c2bf | 34 | */ |
35 | ||
36 | ||
37 | #include "squid.h" | |
38 | ||
9bea1d5b | 39 | static void accessLogSquid(AccessLogEntry * al); |
40 | static void accessLogCommon(AccessLogEntry * al); | |
5673c2e2 | 41 | static Logfile *logfile = NULL; |
c3609322 | 42 | #if HEADERS_LOG |
43 | static Logfile *headerslog = NULL; | |
44 | #endif | |
a7c05555 | 45 | |
e66d7923 | 46 | #if MULTICAST_MISS_STREAM |
47 | static int mcast_miss_fd = -1; | |
48 | static struct sockaddr_in mcast_miss_to; | |
9bea1d5b | 49 | static void mcast_encode(unsigned int *, size_t, const unsigned int *); |
e66d7923 | 50 | #endif |
51 | ||
7a2f978b | 52 | const char *log_tags[] = |
53 | { | |
9bea1d5b | 54 | "NONE", |
55 | "TCP_HIT", | |
56 | "TCP_MISS", | |
57 | "TCP_REFRESH_HIT", | |
58 | "TCP_REF_FAIL_HIT", | |
59 | "TCP_REFRESH_MISS", | |
60 | "TCP_CLIENT_REFRESH_MISS", | |
61 | "TCP_IMS_HIT", | |
62 | "TCP_SWAPFAIL_MISS", | |
63 | "TCP_NEGATIVE_HIT", | |
64 | "TCP_MEM_HIT", | |
65 | "TCP_DENIED", | |
66 | "TCP_OFFLINE_HIT", | |
efd900cb | 67 | #if LOG_TCP_REDIRECTS |
9bea1d5b | 68 | "TCP_REDIRECT", |
efd900cb | 69 | #endif |
9bea1d5b | 70 | "UDP_HIT", |
71 | "UDP_MISS", | |
72 | "UDP_DENIED", | |
73 | "UDP_INVALID", | |
74 | "UDP_MISS_NOFETCH", | |
75 | "ICP_QUERY", | |
76 | "LOG_TYPE_MAX" | |
7a2f978b | 77 | }; |
78 | ||
d21f1c54 | 79 | #if FORW_VIA_DB |
9bea1d5b | 80 | typedef struct { |
6c40d272 | 81 | hash_link hash; |
1afe05c5 | 82 | int n; |
9bea1d5b | 83 | } fvdb_entry; |
d21f1c54 | 84 | static hash_table *via_table = NULL; |
85 | static hash_table *forw_table = NULL; | |
9bea1d5b | 86 | static void fvdbInit(void); |
87 | static void fvdbDumpTable(StoreEntry * e, hash_table * hash); | |
88 | static void fvdbCount(hash_table * hash, const char *key); | |
d21f1c54 | 89 | static OBJH fvdbDumpVia; |
90 | static OBJH fvdbDumpForw; | |
91 | static FREE fvdbFreeEntry; | |
9bea1d5b | 92 | static void fvdbClear(void); |
d21f1c54 | 93 | #endif |
f892c2bf | 94 | |
95 | static int LogfileStatus = LOG_DISABLE; | |
f892c2bf | 96 | #define LOG_BUF_SZ (MAX_URL<<2) |
f892c2bf | 97 | |
98 | static const char c2x[] = | |
99 | "000102030405060708090a0b0c0d0e0f" | |
100 | "101112131415161718191a1b1c1d1e1f" | |
101 | "202122232425262728292a2b2c2d2e2f" | |
102 | "303132333435363738393a3b3c3d3e3f" | |
103 | "404142434445464748494a4b4c4d4e4f" | |
104 | "505152535455565758595a5b5c5d5e5f" | |
105 | "606162636465666768696a6b6c6d6e6f" | |
106 | "707172737475767778797a7b7c7d7e7f" | |
107 | "808182838485868788898a8b8c8d8e8f" | |
108 | "909192939495969798999a9b9c9d9e9f" | |
109 | "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf" | |
110 | "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf" | |
111 | "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf" | |
112 | "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf" | |
113 | "e0e1e2e3e4e5e6e7e8e9eaebecedeeef" | |
114 | "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"; | |
115 | ||
116 | /* log_quote -- URL-style encoding on MIME headers. */ | |
117 | ||
592da4ec | 118 | char * |
9bea1d5b | 119 | log_quote(const char *header) |
f892c2bf | 120 | { |
9bea1d5b | 121 | int c; |
122 | int i; | |
123 | char *buf; | |
124 | char *buf_cursor; | |
125 | if (header == NULL) { | |
e6ccf245 | 126 | buf = static_cast<char *>(xcalloc(1, 1)); |
9bea1d5b | 127 | *buf = '\0'; |
128 | return buf; | |
f892c2bf | 129 | } |
e6ccf245 | 130 | buf = static_cast<char *>(xcalloc(1, (strlen(header) * 3) + 1)); |
9bea1d5b | 131 | buf_cursor = buf; |
132 | /* | |
133 | * We escape: \x00-\x1F"#%;<>?{}|\\\\^~`\[\]\x7F-\xFF | |
134 | * which is the default escape list for the CPAN Perl5 URI module | |
135 | * modulo the inclusion of space (x40) to make the raw logs a bit | |
136 | * more readable. | |
137 | */ | |
138 | while ((c = *(const unsigned char *) header++) != '\0') { | |
7e3ce7b9 | 139 | #if !OLD_LOG_MIME |
9bea1d5b | 140 | if (c == '\r') { |
141 | *buf_cursor++ = '\\'; | |
142 | *buf_cursor++ = 'r'; | |
143 | } else if (c == '\n') { | |
144 | *buf_cursor++ = '\\'; | |
145 | *buf_cursor++ = 'n'; | |
146 | } else | |
7e3ce7b9 | 147 | #endif |
9bea1d5b | 148 | if (c <= 0x1F |
149 | || c >= 0x7F | |
7e3ce7b9 | 150 | #if OLD_LOG_MIME |
9bea1d5b | 151 | || c == '"' |
152 | || c == '#' | |
153 | || c == '%' | |
154 | || c == ';' | |
155 | || c == '<' | |
156 | || c == '>' | |
157 | || c == '?' | |
158 | || c == '{' | |
159 | || c == '}' | |
160 | || c == '|' | |
161 | || c == '\\' | |
162 | || c == '^' | |
163 | || c == '~' | |
164 | || c == '`' | |
7e3ce7b9 | 165 | #endif |
9bea1d5b | 166 | || c == '[' |
167 | || c == ']') { | |
168 | *buf_cursor++ = '%'; | |
169 | i = c * 2; | |
170 | *buf_cursor++ = c2x[i]; | |
171 | *buf_cursor++ = c2x[i + 1]; | |
7e3ce7b9 | 172 | #if !OLD_LOG_MIME |
9bea1d5b | 173 | } else if (c == '\\') { |
174 | *buf_cursor++ = '\\'; | |
175 | *buf_cursor++ = '\\'; | |
7e3ce7b9 | 176 | #endif |
9bea1d5b | 177 | } else { |
178 | *buf_cursor++ = (char) c; | |
f892c2bf | 179 | } |
180 | } | |
9bea1d5b | 181 | *buf_cursor = '\0'; |
182 | return buf; | |
f892c2bf | 183 | } |
184 | ||
2d72d4fd | 185 | static char * |
9bea1d5b | 186 | username_quote(const char *header) |
94439e4e | 187 | /* copy of log_quote. Bugs there will be found here */ |
188 | { | |
9bea1d5b | 189 | int c; |
190 | int i; | |
191 | char *buf; | |
192 | char *buf_cursor; | |
193 | if (header == NULL) { | |
e6ccf245 | 194 | buf = static_cast<char *>(xcalloc(1, 1)); |
9bea1d5b | 195 | *buf = '\0'; |
196 | return buf; | |
94439e4e | 197 | } |
e6ccf245 | 198 | buf = static_cast<char *>(xcalloc(1, (strlen(header) * 3) + 1)); |
9bea1d5b | 199 | buf_cursor = buf; |
200 | /* | |
201 | * We escape: space \x00-\x1F and space (0x40) and \x7F-\xFF | |
202 | * to prevent garbage in the logs. CR and LF are also there just in case. | |
203 | */ | |
204 | while ((c = *(const unsigned char *) header++) != '\0') { | |
205 | if (c == '\r') { | |
206 | *buf_cursor++ = '\\'; | |
207 | *buf_cursor++ = 'r'; | |
208 | } else if (c == '\n') { | |
209 | *buf_cursor++ = '\\'; | |
210 | *buf_cursor++ = 'n'; | |
211 | } else if (c <= 0x1F | |
212 | || c >= 0x7F | |
213 | || c == ' ') { | |
214 | *buf_cursor++ = '%'; | |
215 | i = c * 2; | |
216 | *buf_cursor++ = c2x[i]; | |
217 | *buf_cursor++ = c2x[i + 1]; | |
218 | } else { | |
219 | *buf_cursor++ = (char) c; | |
94439e4e | 220 | } |
221 | } | |
9bea1d5b | 222 | *buf_cursor = '\0'; |
223 | return buf; | |
94439e4e | 224 | } |
225 | ||
2d72d4fd | 226 | static char * |
9bea1d5b | 227 | accessLogFormatName(const char *name) |
94439e4e | 228 | { |
9bea1d5b | 229 | if (NULL == name) |
230 | return NULL; | |
231 | return username_quote(name); | |
94439e4e | 232 | } |
233 | ||
137ee196 | 234 | static void |
9bea1d5b | 235 | accessLogSquid(AccessLogEntry * al) |
f892c2bf | 236 | { |
9bea1d5b | 237 | const char *client = NULL; |
a7ad6e4e | 238 | const char *user = NULL; |
9bea1d5b | 239 | if (Config.onoff.log_fqdn) |
240 | client = fqdncache_gethostbyaddr(al->cache.caddr, FQDN_LOOKUP_IF_MISS); | |
241 | if (client == NULL) | |
242 | client = inet_ntoa(al->cache.caddr); | |
a7ad6e4e | 243 | user = accessLogFormatName(al->cache.authuser); |
244 | #if USE_SSL | |
245 | if (!user) | |
246 | user = accessLogFormatName(al->cache.ssluser); | |
247 | #endif | |
248 | if (!user) | |
249 | user = accessLogFormatName(al->cache.rfc931); | |
250 | if (user && !*user) | |
251 | safe_free(user); | |
84f2d773 | 252 | logfilePrintf(logfile, "%9d.%03d %6d %s %s/%03d %ld %s %s %s %s%s/%s %s", |
9bea1d5b | 253 | (int) current_time.tv_sec, |
254 | (int) current_time.tv_usec / 1000, | |
255 | al->cache.msec, | |
256 | client, | |
257 | log_tags[al->cache.code], | |
258 | al->http.code, | |
84f2d773 | 259 | (long int) al->cache.size, |
29b8d8d6 | 260 | al->_private.method_str, |
9bea1d5b | 261 | al->url, |
a7ad6e4e | 262 | user ? user : dash_str, |
9bea1d5b | 263 | al->hier.ping.timedout ? "TIMEOUT_" : "", |
264 | hier_strings[al->hier.code], | |
265 | al->hier.host, | |
266 | al->http.content_type); | |
267 | safe_free(user); | |
f892c2bf | 268 | } |
269 | ||
137ee196 | 270 | static void |
9bea1d5b | 271 | accessLogCommon(AccessLogEntry * al) |
f892c2bf | 272 | { |
9bea1d5b | 273 | const char *client = NULL; |
274 | char *user1 = NULL, *user2 = NULL; | |
275 | if (Config.onoff.log_fqdn) | |
276 | client = fqdncache_gethostbyaddr(al->cache.caddr, 0); | |
277 | if (client == NULL) | |
278 | client = inet_ntoa(al->cache.caddr); | |
279 | user1 = accessLogFormatName(al->cache.authuser); | |
280 | user2 = accessLogFormatName(al->cache.rfc931); | |
84f2d773 | 281 | logfilePrintf(logfile, "%s %s %s [%s] \"%s %s HTTP/%d.%d\" %d %ld %s:%s", |
9bea1d5b | 282 | client, |
283 | user2 ? user2 : dash_str, | |
284 | user1 ? user1 : dash_str, | |
285 | mkhttpdlogtime(&squid_curtime), | |
29b8d8d6 | 286 | al->_private.method_str, |
9bea1d5b | 287 | al->url, |
288 | al->http.version.major, al->http.version.minor, | |
289 | al->http.code, | |
84f2d773 | 290 | (long int) al->cache.size, |
9bea1d5b | 291 | log_tags[al->cache.code], |
292 | hier_strings[al->hier.code]); | |
293 | safe_free(user1); | |
294 | safe_free(user2); | |
f892c2bf | 295 | } |
296 | ||
297 | void | |
9bea1d5b | 298 | accessLogLog(AccessLogEntry * al) |
f892c2bf | 299 | { |
9bea1d5b | 300 | if (LogfileStatus != LOG_ENABLE) |
301 | return; | |
302 | if (al->url == NULL) | |
303 | al->url = dash_str; | |
304 | if (!al->http.content_type || *al->http.content_type == '\0') | |
305 | al->http.content_type = dash_str; | |
306 | if (al->icp.opcode) | |
29b8d8d6 | 307 | al->_private.method_str = icp_opcode_str[al->icp.opcode]; |
9bea1d5b | 308 | else |
29b8d8d6 | 309 | al->_private.method_str = RequestMethodStr[al->http.method]; |
9bea1d5b | 310 | if (al->hier.host[0] == '\0') |
311 | xstrncpy(al->hier.host, dash_str, SQUIDHOSTNAMELEN); | |
312 | ||
313 | if (Config.onoff.common_log) | |
314 | accessLogCommon(al); | |
315 | else | |
316 | accessLogSquid(al); | |
317 | if (Config.onoff.log_mime_hdrs) { | |
318 | char *ereq = log_quote(al->headers.request); | |
319 | char *erep = log_quote(al->headers.reply); | |
320 | logfilePrintf(logfile, " [%s] [%s]\n", ereq, erep); | |
321 | safe_free(ereq); | |
322 | safe_free(erep); | |
323 | } else { | |
324 | logfilePrintf(logfile, "\n"); | |
f892c2bf | 325 | } |
9bea1d5b | 326 | logfileFlush(logfile); |
e66d7923 | 327 | #if MULTICAST_MISS_STREAM |
9bea1d5b | 328 | if (al->cache.code != LOG_TCP_MISS) |
329 | (void) 0; | |
330 | else if (al->http.method != METHOD_GET) | |
331 | (void) 0; | |
332 | else if (mcast_miss_fd < 0) | |
333 | (void) 0; | |
334 | else { | |
335 | unsigned int ibuf[365]; | |
336 | size_t isize; | |
337 | xstrncpy((char *) ibuf, al->url, 364 * sizeof(int)); | |
338 | isize = ((strlen(al->url) + 8) / 8) * 2; | |
339 | if (isize > 364) | |
340 | isize = 364; | |
341 | mcast_encode((unsigned int *) ibuf, isize, | |
342 | (const unsigned int *) Config.mcast_miss.encode_key); | |
343 | comm_udp_sendto(mcast_miss_fd, | |
344 | &mcast_miss_to, sizeof(mcast_miss_to), | |
345 | ibuf, isize * sizeof(int)); | |
e66d7923 | 346 | } |
347 | #endif | |
f892c2bf | 348 | } |
349 | ||
350 | void | |
9bea1d5b | 351 | accessLogRotate(void) |
f892c2bf | 352 | { |
d21f1c54 | 353 | #if FORW_VIA_DB |
9bea1d5b | 354 | fvdbClear(); |
d21f1c54 | 355 | #endif |
9bea1d5b | 356 | if (NULL == logfile) |
357 | return; | |
358 | logfileRotate(logfile); | |
c3609322 | 359 | #if HEADERS_LOG |
9bea1d5b | 360 | logfileRotate(headerslog); |
c3609322 | 361 | #endif |
f892c2bf | 362 | } |
363 | ||
364 | void | |
9bea1d5b | 365 | accessLogClose(void) |
f892c2bf | 366 | { |
dab0cec3 | 367 | if (NULL == logfile) |
368 | return; | |
9bea1d5b | 369 | logfileClose(logfile); |
370 | logfile = NULL; | |
c3609322 | 371 | #if HEADERS_LOG |
9bea1d5b | 372 | logfileClose(headerslog); |
373 | headerslog = NULL; | |
c3609322 | 374 | #endif |
f892c2bf | 375 | } |
376 | ||
f892c2bf | 377 | void |
9bea1d5b | 378 | hierarchyNote(HierarchyLogEntry * hl, |
379 | hier_code code, | |
380 | const char *cache_peer) | |
f892c2bf | 381 | { |
9bea1d5b | 382 | assert(hl != NULL); |
383 | hl->code = code; | |
384 | xstrncpy(hl->host, cache_peer, SQUIDHOSTNAMELEN); | |
f892c2bf | 385 | } |
7a2f978b | 386 | |
387 | void | |
9bea1d5b | 388 | accessLogInit(void) |
7a2f978b | 389 | { |
9bea1d5b | 390 | assert(sizeof(log_tags) == (LOG_TYPE_MAX + 1) * sizeof(char *)); |
391 | if (strcasecmp(Config.Log.access, "none") == 0) | |
392 | return; | |
393 | logfile = logfileOpen(Config.Log.access, MAX_URL << 1, 1); | |
394 | LogfileStatus = LOG_ENABLE; | |
c3609322 | 395 | #if HEADERS_LOG |
9bea1d5b | 396 | headerslog = logfileOpen("/usr/local/squid/logs/headers.log", 512); |
397 | assert(NULL != headerslog); | |
c3609322 | 398 | #endif |
d21f1c54 | 399 | #if FORW_VIA_DB |
9bea1d5b | 400 | fvdbInit(); |
d21f1c54 | 401 | #endif |
e66d7923 | 402 | #if MULTICAST_MISS_STREAM |
9bea1d5b | 403 | if (Config.mcast_miss.addr.s_addr != no_addr.s_addr) { |
404 | memset(&mcast_miss_to, '\0', sizeof(mcast_miss_to)); | |
405 | mcast_miss_to.sin_family = AF_INET; | |
406 | mcast_miss_to.sin_port = htons(Config.mcast_miss.port); | |
407 | mcast_miss_to.sin_addr.s_addr = Config.mcast_miss.addr.s_addr; | |
408 | mcast_miss_fd = comm_open(SOCK_DGRAM, | |
409 | 0, | |
410 | Config.Addrs.udp_incoming, | |
411 | Config.mcast_miss.port, | |
412 | COMM_NONBLOCKING, | |
413 | "Multicast Miss Stream"); | |
414 | if (mcast_miss_fd < 0) | |
415 | fatal("Cannot open Multicast Miss Stream Socket"); | |
416 | debug(46, 1) ("Multicast Miss Stream Socket opened on FD %d\n", | |
417 | mcast_miss_fd); | |
418 | mcastSetTtl(mcast_miss_fd, Config.mcast_miss.ttl); | |
419 | if (strlen(Config.mcast_miss.encode_key) < 16) | |
420 | fatal("mcast_encode_key is too short, must be 16 characters"); | |
e66d7923 | 421 | } |
422 | #endif | |
7a2f978b | 423 | } |
c6e7cab0 | 424 | |
425 | const char * | |
9bea1d5b | 426 | accessLogTime(time_t t) |
c6e7cab0 | 427 | { |
9bea1d5b | 428 | struct tm *tm; |
429 | static char buf[128]; | |
430 | static time_t last_t = 0; | |
431 | if (t != last_t) { | |
432 | tm = localtime(&t); | |
433 | strftime(buf, 127, "%Y/%m/%d %H:%M:%S", tm); | |
434 | last_t = t; | |
c6e7cab0 | 435 | } |
9bea1d5b | 436 | return buf; |
c6e7cab0 | 437 | } |
d21f1c54 | 438 | |
439 | ||
440 | #if FORW_VIA_DB | |
1afe05c5 | 441 | |
d21f1c54 | 442 | static void |
9bea1d5b | 443 | fvdbInit(void) |
d21f1c54 | 444 | { |
9bea1d5b | 445 | via_table = hash_create((HASHCMP *) strcmp, 977, hash4); |
446 | forw_table = hash_create((HASHCMP *) strcmp, 977, hash4); | |
447 | cachemgrRegister("via_headers", "Via Request Headers", fvdbDumpVia, 0, 1); | |
448 | cachemgrRegister("forw_headers", "X-Forwarded-For Request Headers", | |
449 | fvdbDumpForw, 0, 1); | |
d21f1c54 | 450 | } |
451 | ||
452 | static void | |
9bea1d5b | 453 | fvdbCount(hash_table * hash, const char *key) |
1afe05c5 | 454 | { |
9bea1d5b | 455 | fvdb_entry *fv; |
456 | if (NULL == hash) | |
457 | return; | |
458 | fv = hash_lookup(hash, key); | |
459 | if (NULL == fv) { | |
e6ccf245 | 460 | fv = static_cast <fvdb_entry *>(xcalloc(1, sizeof(fvdb_entry))); |
9bea1d5b | 461 | fv->hash.key = xstrdup(key); |
462 | hash_join(hash, &fv->hash); | |
1afe05c5 | 463 | } |
9bea1d5b | 464 | fv->n++; |
d21f1c54 | 465 | } |
466 | ||
467 | void | |
9bea1d5b | 468 | fvdbCountVia(const char *key) |
d21f1c54 | 469 | { |
9bea1d5b | 470 | fvdbCount(via_table, key); |
d21f1c54 | 471 | } |
472 | ||
473 | void | |
9bea1d5b | 474 | fvdbCountForw(const char *key) |
d21f1c54 | 475 | { |
9bea1d5b | 476 | fvdbCount(forw_table, key); |
d21f1c54 | 477 | } |
478 | ||
1afe05c5 | 479 | static void |
9bea1d5b | 480 | fvdbDumpTable(StoreEntry * e, hash_table * hash) |
d21f1c54 | 481 | { |
9bea1d5b | 482 | hash_link *h; |
483 | fvdb_entry *fv; | |
484 | if (hash == NULL) | |
485 | return; | |
486 | hash_first(hash); | |
487 | while ((h = hash_next(hash))) { | |
488 | fv = (fvdb_entry *) h; | |
489 | storeAppendPrintf(e, "%9d %s\n", fv->n, hashKeyStr(&fv->hash)); | |
1afe05c5 | 490 | } |
d21f1c54 | 491 | } |
492 | ||
493 | static void | |
9bea1d5b | 494 | fvdbDumpVia(StoreEntry * e) |
d21f1c54 | 495 | { |
9bea1d5b | 496 | fvdbDumpTable(e, via_table); |
d21f1c54 | 497 | } |
1afe05c5 | 498 | |
d21f1c54 | 499 | static void |
9bea1d5b | 500 | fvdbDumpForw(StoreEntry * e) |
d21f1c54 | 501 | { |
9bea1d5b | 502 | fvdbDumpTable(e, forw_table); |
d21f1c54 | 503 | } |
504 | ||
505 | static | |
b644367b | 506 | void |
9bea1d5b | 507 | fvdbFreeEntry(void *data) |
d21f1c54 | 508 | { |
9bea1d5b | 509 | fvdb_entry *fv = data; |
510 | xfree(fv->hash.key); | |
511 | xfree(fv); | |
d21f1c54 | 512 | } |
513 | ||
514 | static void | |
9bea1d5b | 515 | fvdbClear(void) |
d21f1c54 | 516 | { |
9bea1d5b | 517 | hashFreeItems(via_table, fvdbFreeEntry); |
518 | hashFreeMemory(via_table); | |
519 | via_table = hash_create((HASHCMP *) strcmp, 977, hash4); | |
520 | hashFreeItems(forw_table, fvdbFreeEntry); | |
521 | hashFreeMemory(forw_table); | |
522 | forw_table = hash_create((HASHCMP *) strcmp, 977, hash4); | |
d21f1c54 | 523 | } |
524 | ||
1afe05c5 | 525 | #endif |
e66d7923 | 526 | |
527 | #if MULTICAST_MISS_STREAM | |
528 | /* | |
529 | * From http://www.io.com/~paulhart/game/algorithms/tea.html | |
530 | * | |
531 | * size of 'ibuf' must be a multiple of 2. | |
532 | * size of 'key' must be 4. | |
533 | * 'ibuf' is modified in place, encrypted data is written in | |
534 | * network byte order. | |
535 | */ | |
536 | static void | |
9bea1d5b | 537 | mcast_encode(unsigned int *ibuf, size_t isize, const unsigned int *key) |
e66d7923 | 538 | { |
9bea1d5b | 539 | unsigned int y; |
540 | unsigned int z; | |
541 | unsigned int sum; | |
542 | const unsigned int delta = 0x9e3779b9; | |
543 | unsigned int n = 32; | |
544 | const unsigned int k0 = htonl(key[0]); | |
545 | const unsigned int k1 = htonl(key[1]); | |
546 | const unsigned int k2 = htonl(key[2]); | |
547 | const unsigned int k3 = htonl(key[3]); | |
548 | int i; | |
549 | for (i = 0; i < isize; i += 2) { | |
550 | y = htonl(ibuf[i]); | |
551 | z = htonl(ibuf[i + 1]); | |
552 | sum = 0; | |
553 | for (n = 32; n; n--) { | |
554 | sum += delta; | |
555 | y += (z << 4) + (k0 ^ z) + (sum ^ (z >> 5)) + k1; | |
556 | z += (y << 4) + (k2 ^ y) + (sum ^ (y >> 5)) + k3; | |
e66d7923 | 557 | } |
9bea1d5b | 558 | ibuf[i] = htonl(y); |
559 | ibuf[i + 1] = htonl(z); | |
e66d7923 | 560 | } |
561 | } | |
562 | ||
563 | #endif | |
c3609322 | 564 | |
565 | #if HEADERS_LOG | |
566 | void | |
9bea1d5b | 567 | headersLog(int cs, int pq, method_t m, void *data) |
c3609322 | 568 | { |
9bea1d5b | 569 | HttpReply *rep; |
570 | request_t *req; | |
571 | unsigned short magic = 0; | |
572 | unsigned char M = (unsigned char) m; | |
573 | unsigned short S; | |
574 | char *hmask; | |
575 | int ccmask = 0; | |
576 | if (0 == pq) { | |
577 | /* reply */ | |
578 | rep = data; | |
579 | req = NULL; | |
580 | magic = 0x0050; | |
581 | hmask = rep->header.mask; | |
582 | if (rep->cache_control) | |
583 | ccmask = rep->cache_control->mask; | |
584 | } else { | |
585 | /* request */ | |
586 | req = data; | |
587 | rep = NULL; | |
588 | magic = 0x0051; | |
589 | hmask = req->header.mask; | |
590 | if (req->cache_control) | |
591 | ccmask = req->cache_control->mask; | |
c3609322 | 592 | } |
9bea1d5b | 593 | if (0 == cs) { |
594 | /* client */ | |
595 | magic |= 0x4300; | |
596 | } else { | |
597 | /* server */ | |
598 | magic |= 0x5300; | |
c3609322 | 599 | } |
9bea1d5b | 600 | magic = htons(magic); |
601 | ccmask = htonl(ccmask); | |
602 | if (0 == pq) | |
603 | S = (unsigned short) rep->sline.status; | |
604 | else | |
605 | S = (unsigned short) HTTP_STATUS_NONE; | |
606 | logfileWrite(headerslog, &magic, sizeof(magic)); | |
607 | logfileWrite(headerslog, &M, sizeof(M)); | |
608 | logfileWrite(headerslog, &S, sizeof(S)); | |
609 | logfileWrite(headerslog, hmask, sizeof(HttpHeaderMask)); | |
610 | logfileWrite(headerslog, &ccmask, sizeof(int)); | |
611 | logfileFlush(headerslog); | |
c3609322 | 612 | } |
613 | ||
614 | #endif | |
c8be6d7b | 615 | |
616 | void | |
617 | accessLogFreeMemory(AccessLogEntry * aLogEntry) | |
618 | { | |
619 | safe_free(aLogEntry->headers.request); | |
620 | safe_free(aLogEntry->headers.reply); | |
621 | safe_free(aLogEntry->cache.authuser); | |
622 | } | |
623 | ||
624 | int | |
625 | logTypeIsATcpHit(log_type code) | |
626 | { | |
627 | /* this should be a bitmap for better optimization */ | |
628 | if (code == LOG_TCP_HIT) | |
629 | return 1; | |
630 | if (code == LOG_TCP_IMS_HIT) | |
631 | return 1; | |
632 | if (code == LOG_TCP_REFRESH_FAIL_HIT) | |
633 | return 1; | |
634 | if (code == LOG_TCP_REFRESH_HIT) | |
635 | return 1; | |
636 | if (code == LOG_TCP_NEGATIVE_HIT) | |
637 | return 1; | |
638 | if (code == LOG_TCP_MEM_HIT) | |
639 | return 1; | |
640 | if (code == LOG_TCP_OFFLINE_HIT) | |
641 | return 1; | |
642 | return 0; | |
643 | } | |
e6ccf245 | 644 |