From: wessels <> Date: Sat, 21 Jun 1997 08:36:47 +0000 (+0000) Subject: adding X-Git-Tag: SQUID_3_0_PRE1~4919 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f892c2bf269d12e4c8eb7b58889735b6429e8f85;p=thirdparty%2Fsquid.git adding --- diff --git a/src/access_log.cc b/src/access_log.cc new file mode 100644 index 0000000000..eb0b05ae66 --- /dev/null +++ b/src/access_log.cc @@ -0,0 +1,270 @@ + +/* + * $Id: access_log.cc,v 1.1 1997/06/21 02:36:47 wessels Exp $ + * + * DEBUG: section 46 Access Log + * AUTHOR: Duane Wessels + * + * SQUID Internet Object Cache http://squid.nlanr.net/Squid/ + * -------------------------------------------------------- + * + * Squid is the result of efforts by numerous individuals from the + * Internet community. Development is led by Duane Wessels of the + * National Laboratory for Applied Network Research and funded by + * the National Science Foundation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + + +#include "squid.h" + +#define MAX_LINELEN (4096) +#define max(a,b) ((a)>(b)? (a): (b)) + +static int LogfileStatus = LOG_DISABLE; +static int LogfileFD = -1; +static char LogfileName[SQUID_MAXPATHLEN]; +#define LOG_BUF_SZ (MAX_URL<<2) +static char log_buf[LOG_BUF_SZ]; + +static const char c2x[] = +"000102030405060708090a0b0c0d0e0f" +"101112131415161718191a1b1c1d1e1f" +"202122232425262728292a2b2c2d2e2f" +"303132333435363738393a3b3c3d3e3f" +"404142434445464748494a4b4c4d4e4f" +"505152535455565758595a5b5c5d5e5f" +"606162636465666768696a6b6c6d6e6f" +"707172737475767778797a7b7c7d7e7f" +"808182838485868788898a8b8c8d8e8f" +"909192939495969798999a9b9c9d9e9f" +"a0a1a2a3a4a5a6a7a8a9aaabacadaeaf" +"b0b1b2b3b4b5b6b7b8b9babbbcbdbebf" +"c0c1c2c3c4c5c6c7c8c9cacbcccdcecf" +"d0d1d2d3d4d5d6d7d8d9dadbdcdddedf" +"e0e1e2e3e4e5e6e7e8e9eaebecedeeef" +"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"; + +/* log_quote -- URL-style encoding on MIME headers. */ + +static char * +log_quote(const char *header) +{ + int c, i; + char *buf, *buf_cursor; + if (header == NULL) { + buf = xcalloc(1, 1); + *buf = '\0'; + return buf; + } + buf = xcalloc((strlen(header) * 3) + 1, 1); + buf_cursor = buf; + /* + * We escape: \x00-\x1F"#%;<>?{}|\\\\^~`\[\]\x7F-\xFF + * which is the default escape list for the CPAN Perl5 URI module + * modulo the inclusion of space (x40) to make the raw logs a bit + * more readable. + */ + while ((c = *(const unsigned char *) header++)) { + if (c <= 0x1F + || c >= 0x7F + || c == '"' + || c == '#' + || c == '%' + || c == ';' + || c == '<' + || c == '>' + || c == '?' + || c == '{' + || c == '}' + || c == '|' + || c == '\\' + || c == '^' + || c == '~' + || c == '`' + || c == '[' + || c == ']') { + *buf_cursor++ = '%'; + i = c * 2; + *buf_cursor++ = c2x[i]; + *buf_cursor++ = c2x[i + 1]; + } else { + *buf_cursor++ = c; + } + } + *buf_cursor = '\0'; + return buf; +} + +static int +accessLogSquid(AccessLogEntry * al) +{ + const char *client = dash_str; + if (Config.Log.log_fqdn) + client = fqdncache_gethostbyaddr(al->cache.caddr, 0); + if (client == NULL) + client = inet_ntoa(al->cache.caddr); + return snprintf(log_buf, LOG_BUF_SZ, + "%9d.%03d %6d %s %s/%03d %d %s %s %s %s%s/%s %s\n", + (int) current_time.tv_sec, + (int) current_time.tv_usec / 1000, + al->cache.msec, + client, + log_tags[al->cache.code], + al->http.code, + al->cache.size, + al->private.method_str, + al->url, + al->cache.ident, + al->hier.icp.timeout ? "TIMEOUT_" : "", + hier_strings[al->hier.code], + al->hier.host, + al->http.content_type); +} + +static int +accessLogCommon(AccessLogEntry * al) +{ + const char *client = dash_str; + if (Config.Log.log_fqdn) + client = fqdncache_gethostbyaddr(al->cache.caddr, 0); + if (client == NULL) + client = inet_ntoa(al->cache.caddr); + return snprintf(log_buf, LOG_BUF_SZ, + "%s %s - [%s] \"%s %s\" %d %d %s:%s\n", + client, + al->cache.ident, + mkhttpdlogtime(&squid_curtime), + al->private.method_str, + al->url, + al->http.code, + al->cache.size, + log_tags[al->cache.code], + hier_strings[al->hier.code]); +} + +void +accessLogLog(AccessLogEntry * al) +{ + int x; + int l; + if (LogfileStatus != LOG_ENABLE) + return; + if (al->url == NULL) + al->url = dash_str; + if (!al->http.content_type || *al->http.content_type == '\0') + al->http.content_type = dash_str; + if (!al->cache.ident || *al->cache.ident == '\0') + al->cache.ident = dash_str; + if (al->icp.opcode) + al->private.method_str = IcpOpcodeStr[al->icp.opcode]; + else + al->private.method_str = RequestMethodStr[al->http.method]; + if (Config.commonLogFormat) + l = accessLogCommon(al); + else + l = accessLogSquid(al); + if (Config.logMimeHdrs) { + char *ereq = log_quote(al->headers.request); + char *erep = log_quote(al->headers.reply); + if (LOG_BUF_SZ - l > 0) + l += snprintf(log_buf + l, LOG_BUF_SZ - l, " [%s] [%s]\n", + ereq, erep); + safe_free(ereq); + safe_free(erep); + } + x = file_write(LogfileFD, + xstrdup(log_buf), + l, + NULL, + NULL, + xfree); + if (x != DISK_OK) + debug(46, 1) ("log_append: File write failed.\n"); +} + +void +accessLogRotate(void) +{ + int i; + LOCAL_ARRAY(char, from, MAXPATHLEN); + LOCAL_ARRAY(char, to, MAXPATHLEN); + char *fname = NULL; + struct stat sb; + if ((fname = LogfileName) == NULL) + return; +#ifdef S_ISREG + if (stat(fname, &sb) == 0) + if (S_ISREG(sb.st_mode) == 0) + return; +#endif + debug(46, 1) ("accessLogRotate: Rotating\n"); + /* Rotate numbers 0 through N up one */ + for (i = Config.Log.rotateNumber; i > 1;) { + i--; + snprintf(from, MAXPATHLEN, "%s.%d", fname, i - 1); + snprintf(to, MAXPATHLEN, "%s.%d", fname, i); + rename(from, to); + } + /* Rotate the current log to .0 */ + if (Config.Log.rotateNumber > 0) { + snprintf(to, MAXPATHLEN, "%s.%d", fname, 0); + rename(fname, to); + } + /* Close and reopen the log. It may have been renamed "manually" + * before HUP'ing us. */ + file_close(LogfileFD); + LogfileFD = file_open(fname, O_WRONLY | O_CREAT, NULL, NULL); + if (LogfileFD == DISK_ERROR) { + debug(46, 0) ("accessLogRotate: Cannot open logfile: %s\n", fname); + LogfileStatus = LOG_DISABLE; + fatal("Cannot open logfile."); + } +} + +void +accessLogClose(void) +{ + file_close(LogfileFD); +} + +void +accessLogOpen(const char *fname) +{ + assert(fname); + xstrncpy(LogfileName, fname, SQUID_MAXPATHLEN); + LogfileFD = file_open(LogfileName, O_WRONLY | O_CREAT, NULL, NULL); + if (LogfileFD == DISK_ERROR) { + debug(50, 0) ("%s: %s\n", LogfileName, xstrerror()); + fatal("Cannot open logfile."); + } + LogfileStatus = LOG_ENABLE; +} + +void +hierarchyNote(HierarchyLogEntry *hl, + hier_code code, + icp_ping_data * icpdata, + const char *cache_host) +{ + assert(hl != NULL); + hl->code = code; + if (icpdata) + hl->icp = *icpdata; + xstrncpy(hl->host, cache_host, SQUIDHOSTNAMELEN); + hl->icp.stop = current_time; +} diff --git a/src/enums.h b/src/enums.h new file mode 100644 index 0000000000..339764d940 --- /dev/null +++ b/src/enums.h @@ -0,0 +1,240 @@ + + +typedef enum { + LOG_TAG_NONE, /* 0 */ + LOG_TCP_HIT, /* 1 */ + LOG_TCP_MISS, /* 2 */ + LOG_TCP_REFRESH_HIT, /* 3 */ + LOG_TCP_REFRESH_FAIL_HIT, /* 4 */ + LOG_TCP_REFRESH_MISS, /* 5 */ + LOG_TCP_CLIENT_REFRESH, /* 6 */ + LOG_TCP_IMS_HIT, /* 7 */ + LOG_TCP_IMS_MISS, /* 8 */ + LOG_TCP_SWAPFAIL_MISS, /* 9 */ + LOG_TCP_DENIED, /* 10 */ + LOG_UDP_HIT, /* 11 */ + LOG_UDP_HIT_OBJ, /* 12 */ + LOG_UDP_MISS, /* 13 */ + LOG_UDP_DENIED, /* 14 */ + LOG_UDP_INVALID, /* 15 */ + LOG_UDP_MISS_NOFETCH, /* 16 */ + ERR_READ_TIMEOUT, /* 17 */ + ERR_LIFETIME_EXP, /* 18 */ + ERR_NO_CLIENTS_BIG_OBJ, /* 19 */ + ERR_READ_ERROR, /* 20 */ + ERR_WRITE_ERROR, /* 21 */ + ERR_CLIENT_ABORT, /* 22 */ + ERR_CONNECT_FAIL, /* 23 */ + ERR_INVALID_REQ, /* 24 */ + ERR_UNSUP_REQ, /* 25 */ + ERR_INVALID_URL, /* 26 */ + ERR_NO_FDS, /* 27 */ + ERR_DNS_FAIL, /* 28 */ + ERR_NOT_IMPLEMENTED, /* 29 */ + ERR_CANNOT_FETCH, /* 30 */ + ERR_NO_RELAY, /* 31 */ + ERR_DISK_IO, /* 32 */ + ERR_ZERO_SIZE_OBJECT, /* 33 */ + ERR_FTP_DISABLED, /* 34 */ + ERR_PROXY_DENIED /* 35 */ +} log_type; + +typedef enum { + ACL_NONE, + ACL_SRC_IP, + ACL_DST_IP, + ACL_SRC_DOMAIN, + ACL_DST_DOMAIN, + ACL_TIME, + ACL_URLPATH_REGEX, + ACL_URL_REGEX, + ACL_URL_PORT, + ACL_USER, + ACL_PROTO, + ACL_METHOD, + ACL_BROWSER, + ACL_ENUM_MAX +} squid_acl; + +typedef enum { + ACL_LOOKUP_NONE, + ACL_LOOKUP_NEEDED, + ACL_LOOKUP_PENDING, + ACL_LOOKUP_DONE +} acl_lookup_state; + +typedef enum { + IP_ALLOW, + IP_DENY +} ip_access_type; + +enum { + FD_NONE, + FD_LOG, + FD_FILE, + FD_SOCKET, + FD_PIPE, + FD_UNKNOWN +}; + +enum { + FD_READ, + FD_WRITE +}; + +enum { + FD_CLOSE, + FD_OPEN +}; + +enum { + FQDN_CACHED, + FQDN_NEGATIVE_CACHED, + FQDN_PENDING, /* waiting to be dispatched */ + FQDN_DISPATCHED /* waiting for reply from dnsserver */ +}; +typedef unsigned int fqdncache_status_t; + +enum { + IP_CACHED, + IP_NEGATIVE_CACHED, + IP_PENDING, /* waiting to be dispatched */ + IP_DISPATCHED /* waiting for reply from dnsserver */ +}; +typedef unsigned int ipcache_status_t; + +typedef enum { + PEER_NONE, + PEER_SIBLING, + PEER_PARENT, + PEER_MULTICAST +} peer_t; + +typedef enum { + MGR_NONE, + MGR_CLIENT_LIST, + MGR_CONFIG, + MGR_CONFIG_FILE, + MGR_DNSSERVERS, + MGR_FILEDESCRIPTORS, + MGR_FQDNCACHE, + MGR_INFO, + MGR_IO, + MGR_IPCACHE, + MGR_LOG_CLEAR, + MGR_LOG_DISABLE, + MGR_LOG_ENABLE, + MGR_LOG_STATUS, + MGR_LOG_VIEW, + MGR_NETDB, + MGR_OBJECTS, + MGR_REDIRECTORS, + MGR_REFRESH, + MGR_REMOVE, + MGR_REPLY_HDRS, + MGR_SERVER_LIST, + MGR_SHUTDOWN, + MGR_UTILIZATION, + MGR_VM_OBJECTS, + MGR_STOREDIR, + MGR_CBDATA, + MGR_MAX +} objcache_op; + +typedef enum { + HIER_NONE, + DIRECT, + SIBLING_HIT, + PARENT_HIT, + DEFAULT_PARENT, + SINGLE_PARENT, + FIRSTUP_PARENT, + NO_PARENT_DIRECT, + FIRST_PARENT_MISS, + CLOSEST_PARENT_MISS, + CLOSEST_DIRECT, + NO_DIRECT_FAIL, + SOURCE_FASTEST, + SIBLING_UDP_HIT_OBJ, + PARENT_UDP_HIT_OBJ, + PASS_PARENT, + SSL_PARENT, + ROUNDROBIN_PARENT, + HIER_MAX +} hier_code; + +typedef enum { + ICP_OP_INVALID, /* 00 to insure 0 doesn't get accidently interpreted. */ + ICP_OP_QUERY, /* 01 query opcode (cl->sv) */ + ICP_OP_HIT, /* 02 hit (cl<-sv) */ + ICP_OP_MISS, /* 03 miss (cl<-sv) */ + ICP_OP_ERR, /* 04 error (cl<-sv) */ + ICP_OP_SEND, /* 05 send object non-auth (cl->sv) */ + ICP_OP_SENDA, /* 06 send object authoritative (cl->sv) */ + ICP_OP_DATABEG, /* 07 first data, but not last (sv<-cl) */ + ICP_OP_DATA, /* 08 data middle of stream (sv<-cl) */ + ICP_OP_DATAEND, /* 09 last data (sv<-cl) */ + ICP_OP_SECHO, /* 10 echo from source (sv<-os) */ + ICP_OP_DECHO, /* 11 echo from dumb cache (sv<-dc) */ + ICP_OP_UNUSED0, /* 12 */ + ICP_OP_UNUSED1, /* 13 */ + ICP_OP_UNUSED2, /* 14 */ + ICP_OP_UNUSED3, /* 15 */ + ICP_OP_UNUSED4, /* 16 */ + ICP_OP_UNUSED5, /* 17 */ + ICP_OP_UNUSED6, /* 18 */ + ICP_OP_UNUSED7, /* 19 */ + ICP_OP_UNUSED8, /* 20 */ + ICP_OP_MISS_NOFETCH, /* 21 access denied while reloading */ + ICP_OP_DENIED, /* 22 access denied (cl<-sv) */ + ICP_OP_HIT_OBJ, /* 23 hit with object data (cl<-sv) */ + ICP_OP_END /* 24 marks end of opcodes */ +} icp_opcode; + +enum { + NOT_IN_MEMORY, + SWAPPING_IN, + IN_MEMORY +}; + +enum { + PING_NONE, + PING_WAITING, + PING_TIMEOUT, + PING_DONE +}; + +enum { + STORE_OK, + STORE_PENDING, + STORE_ABORTED +}; + +enum { + NO_SWAP, + SWAPPING_OUT, + SWAP_OK +}; + +enum { + METHOD_NONE, /* 000 */ + METHOD_GET, /* 001 */ + METHOD_POST, /* 010 */ + METHOD_PUT, /* 011 */ + METHOD_HEAD, /* 100 */ + METHOD_CONNECT, /* 101 */ + METHOD_TRACE, /* 110 */ + METHOD_PURGE /* 111 */ +}; +typedef unsigned int method_t; + +typedef enum { + PROTO_NONE, + PROTO_HTTP, + PROTO_FTP, + PROTO_GOPHER, + PROTO_WAIS, + PROTO_CACHEOBJ, + PROTO_ICP, + PROTO_MAX +} protocol_t;