From: wessels <> Date: Sat, 21 Sep 1996 05:26:47 +0000 (+0000) Subject: - Moved ICMP socket to external 'pinger' program. X-Git-Tag: SQUID_3_0_PRE1~5751 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9d90e6654711ff3cc842698737db21948de09868;p=thirdparty%2Fsquid.git - Moved ICMP socket to external 'pinger' program. - Moved tvSubMsec() to lib/util.c. - Moved accessLogTime() to debug.c. --- diff --git a/ChangeLog b/ChangeLog index 636606e997..28ab3d9d5d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,6 +5,11 @@ Changes to squid-1.1.beta4 (): - Added more stuff to net_db.c. - Fixed memory leak in stat_ipcache_get(). - Changed __P back to _PARAMS. + - Fixed authorization parsing bug in ftp.c (Yoichi Shinoda). + - Allow ICP socket on priveledged ports. + - Added trap for STORE_PENDING objects when lock_count == 0. + - Replaced 'cache_hot_vm_factor' with 'max_hotvm_obj_size'. + - Moved ICMP socket to external 'pinger' program. Changes to squid-1.1.beta3 (September 16, 1996): diff --git a/include/util.h b/include/util.h index 565d51893c..b4c840bbc5 100644 --- a/include/util.h +++ b/include/util.h @@ -1,5 +1,5 @@ /* - * $Id: util.h,v 1.20 1996/09/20 06:28:18 wessels Exp $ + * $Id: util.h,v 1.21 1996/09/20 23:26:52 wessels Exp $ * * AUTHOR: Harvest Derived * @@ -107,6 +107,12 @@ #include "config.h" #include #include +#if HAVE_TIME_H +#include +#endif +#if HAVE_SYS_TIME_H +#include +#endif #if !defined(SQUIDHOSTNAMELEN) #include @@ -124,18 +130,21 @@ #if !HAVE_STRDUP extern char *strdup _PARAMS((char *)); #endif -extern char *xstrdup _PARAMS((char *)); /* Duplicate a string */ +extern char *xstrdup _PARAMS((char *)); /* from xmalloc.c */ -void *xmalloc _PARAMS((size_t)); /* Wrapper for malloc(3) */ -void *xrealloc _PARAMS((void *, size_t)); /* Wrapper for realloc(3) */ -void *xcalloc _PARAMS((int, size_t)); /* Wrapper for calloc(3) */ -void xfree _PARAMS((void *)); /* Wrapper for free(3) */ -void xxfree _PARAMS((void *)); /* Wrapper for free(3) */ -char *xstrdup _PARAMS((char *)); -char *xstrerror _PARAMS((void)); -char *getfullhostname _PARAMS((void)); -void xmemcpy _PARAMS((void *, void *, int)); +extern void *xmalloc _PARAMS((size_t)); +extern void *xrealloc _PARAMS((void *, size_t)); +extern void *xcalloc _PARAMS((int, size_t)); +extern void xfree _PARAMS((void *)); +extern void xxfree _PARAMS((void *)); +extern char *xstrdup _PARAMS((char *)); +extern char *xstrerror _PARAMS((void)); +extern char *getfullhostname _PARAMS((void)); +extern void xmemcpy _PARAMS((void *, void *, int)); + +extern int tvSubMsec _PARAMS((struct timeval, struct timeval)); + #if XMALLOC_STATISTICS void malloc_statistics _PARAMS((void (*)_PARAMS((int, int, void *)), void *)); diff --git a/lib/util.c b/lib/util.c index 1616b9ef38..b184937651 100644 --- a/lib/util.c +++ b/lib/util.c @@ -1,5 +1,5 @@ /* - * $Id: util.c,v 1.19 1996/09/20 06:28:22 wessels Exp $ + * $Id: util.c,v 1.20 1996/09/20 23:26:53 wessels Exp $ * * DEBUG: * AUTHOR: Harvest Derived @@ -479,3 +479,10 @@ Tolower(char *q) s++; } } + +int +tvSubMsec(struct timeval t1, struct timeval t2) +{ + return (t2.tv_sec - t1.tv_sec) * 1000 + + (t2.tv_usec - t1.tv_usec) / 1000; +} diff --git a/src/Makefile.in b/src/Makefile.in index 547b4d106a..8b28eb26b4 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -1,7 +1,7 @@ # # Makefile for the Squid Object Cache server # -# $Id: Makefile.in,v 1.42 1996/09/20 06:28:23 wessels Exp $ +# $Id: Makefile.in,v 1.43 1996/09/20 23:26:54 wessels Exp $ # # Uncomment and customize the following to suit your needs: # @@ -56,14 +56,15 @@ LIBS = -L../lib -lregex -lmiscutil $(XTRA_LIBS) CLIENT_LIBS = -L../lib -lmiscutil $(XTRA_LIBS) PROGS = squid client -UTILS = dnsserver ftpget +UTILS = dnsserver ftpget pinger CGIPROGS = cachemgr.cgi OBJS = acl.o async_io.o background.o cache_cf.o errorpage.o \ client_side.o comm.o debug.o disk.o dns.o \ fdstat.o filemap.o ftp.o fqdncache.o gopher.o \ hash.o http.o icmp.o icp.o ident.o ipcache.o \ main.o mime.o neighbors.o net_db.o objcache.o \ - proto.o redirect.o send-announce.o ssl.o stack.o stat.o stmem.o \ + proto.o redirect.o send-announce.o ssl.o \ + stack.o stat.o stmem.o \ store.o store_clean.o storetoString.o tools.o ttl.o \ url.o wais.o $(XTRA_OBJS) @@ -96,6 +97,9 @@ cachemgr.cgi: cachemgr.o ftpget: ftpget.o $(CC) -o $@ $(LDFLAGS) ftpget.o $(LIBS) +pinger: pinger.o + $(CC) -o debug.o $@ $(LDFLAGS) pinger.o $(LIBS) + squid.conf: squid.conf.pre Makefile sed "\ s%@DEFAULT_CONFIG_FILE@%$(DEFAULT_CONFIG_FILE)%g;\ diff --git a/src/debug.cc b/src/debug.cc index 7ad8a311f0..524a1aab39 100644 --- a/src/debug.cc +++ b/src/debug.cc @@ -1,5 +1,5 @@ /* - * $Id: debug.cc,v 1.27 1996/09/20 06:28:33 wessels Exp $ + * $Id: debug.cc,v 1.28 1996/09/20 23:26:55 wessels Exp $ * * DEBUG: section 0 Debug Routines * AUTHOR: Harvest Derived @@ -274,3 +274,17 @@ _db_rotate_log(void) if (debug_log != stderr) debugOpenLog(Config.Log.log); } + +char * +accessLogTime(time_t t) +{ + struct tm *tm; + static char buf[128]; + static time_t last_t = 0; + if (t != last_t) { + tm = localtime(&t); + strftime(buf, 127, "%y/%m/%d %T", tm); + last_t = t; + } + return buf; +} diff --git a/src/icmp.cc b/src/icmp.cc index d277df78c7..b715910d09 100644 --- a/src/icmp.cc +++ b/src/icmp.cc @@ -1,6 +1,6 @@ /* - * $Id: icmp.cc,v 1.9 1996/09/20 07:38:15 wessels Exp $ + * $Id: icmp.cc,v 1.10 1996/09/20 23:26:56 wessels Exp $ * * DEBUG: section 37 ICMP Routines * AUTHOR: Duane Wessels @@ -32,275 +32,153 @@ #if USE_ICMP #include "squid.h" - -#include -#include -#include -#include - -#ifndef _SQUID_LINUX_ -#define icmphdr icmp -#define iphdr ip -#endif - -#ifdef _SQUID_LINUX_ -#define icmp_type type -#define icmp_code code -#define icmp_cksum checksum -#define icmp_id un.echo.id -#define icmp_seq un.echo.sequence -#define icmp_gwaddr un.gateway -#define ip_hl ihl -#define ip_v version -#define ip_tos tos -#define ip_len tot_len -#define ip_id id -#define ip_off frag_off -#define ip_ttl ttl -#define ip_p protocol -#define ip_sum check -#define ip_src saddr -#define ip_dst daddr -#endif +#include "pinger.h" #define S_ICMP_ECHO 1 #define S_ICMP_ICP 2 #define S_ICMP_DOM 3 typedef struct _icmpQueueData { - struct sockaddr_in to; char *msg; int len; struct _icmpQueueData *next; void (*free) _PARAMS((void *)); } icmpQueueData; -#define MAX_PAYLOAD (8192 - sizeof(struct icmphdr) - sizeof (char) - sizeof(struct timeval) - 1) - -typedef struct { - struct timeval tv; - unsigned char opcode; - char payload[MAX_PAYLOAD]; -} icmpEchoData; - static icmpQueueData *IcmpQueueHead = NULL; int icmp_sock = -1; -static int icmp_ident = -1; -static int icmp_pkts_sent = 0; - -static char *icmpPktStr[] = -{ - "Echo Reply", - "ICMP 1", - "ICMP 2", - "Destination Unreachable", - "Source Quench", - "Redirect", - "ICMP 6", - "ICMP 7", - "Echo", - "ICMP 9", - "ICMP 10", - "Time Exceeded", - "Parameter Problem", - "Timestamp", - "Timestamp Reply", - "Info Request", - "Info Reply", - "Out of Range Type" -}; - -static int in_cksum _PARAMS((unsigned short *ptr, int size)); static void icmpRecv _PARAMS((int, void *)); -static void icmpQueueSend _PARAMS((struct in_addr, - char *msg, +static void icmpQueueSend _PARAMS((pingerEchoData * pkt, int len, void (*free) _PARAMS((void *)))); static void icmpSend _PARAMS((int fd, icmpQueueData * queue)); -static void icmpLog _PARAMS((struct icmphdr * icmp, - struct in_addr addr, - int rtt, - int hops)); -static int ipHops _PARAMS((int ttl)); -static void icmpProcessReply _PARAMS((struct sockaddr_in * from, - struct icmphdr * icmp, - int hops)); static void icmpHandleSourcePing _PARAMS((struct sockaddr_in * from, char *buf)); void icmpOpen(void) { - struct protoent *proto = NULL; - if ((proto = getprotobyname("icmp")) == 0) { - debug(37, 0, "icmpOpen: unknown protocol: icmp\n"); - return; - } - enter_suid(); - icmp_sock = comm_open(SOCK_RAW, - proto->p_proto, - Config.Addrs.udp_outgoing, + struct sockaddr_in S; + int namelen = sizeof(struct sockaddr_in); + pid_t pid; + char *command = "pinger"; + int child_sock; + icmp_sock = comm_open(SOCK_DGRAM, + 0, + local_addr, 0, COMM_NONBLOCKING, "ICMP Socket"); - leave_suid(); if (icmp_sock < 0) { debug(37, 0, "icmpOpen: icmp_sock: %s\n", xstrerror()); return; } - icmp_ident = getpid() & 0xffff; + child_sock = comm_open(SOCK_DGRAM, + 0, + local_addr, + 0, + 0, + "ICMP Socket"); + if (child_sock < 0) { + debug(37, 0, "icmpOpen: child_sock: %s\n", xstrerror()); + return; + } + getsockname(icmp_sock, &S, &namelen); + if (comm_connect_addr(child_sock, &S) != COMM_OK) + fatal_dump(xstrerror()); + getsockname(child_sock, &S, &namelen); + if (comm_connect_addr(icmp_sock, &S) != COMM_OK) + fatal_dump(xstrerror()); + if ((pid = fork()) < 0) { + debug(29, 0, "icmpOpen: fork: %s\n", xstrerror()); + comm_close(icmp_sock); + comm_close(child_sock); + return; + } + if (pid == 0) { /* child */ + comm_close(icmp_sock); + dup2(child_sock, 0); + dup2(child_sock, 1); + comm_close(child_sock); + dup2(fileno(debug_log), 2); + fclose(debug_log); + enter_suid(); + execlp(command, "(pinger)", NULL); + debug(29, 0, "icmpOpen: %s: %s\n", command, xstrerror()); + _exit(1); + } + comm_close(child_sock); comm_set_select_handler(icmp_sock, COMM_SELECT_READ, (PF) icmpRecv, (void *) -1); - debug(37, 0, "ICMP socket opened on FD %d\n", icmp_sock); + comm_set_fd_lifetime(icmp_sock, -1); } void icmpClose(void) { comm_close(icmp_sock); - icmp_sock = -1; - icmp_ident = 0; } static void icmpSendEcho(struct in_addr to, int opcode, char *payload, int len) { - char *pkt = NULL; - struct icmphdr *icmp = NULL; - icmpEchoData *echo; - int icmp_pktsize = sizeof(struct icmphdr); - pkt = get_free_8k_page(); - memset(pkt, '\0', 8192); - icmp = (struct icmphdr *) (void *) pkt; - icmp->icmp_type = ICMP_ECHO; - icmp->icmp_code = 0; - icmp->icmp_cksum = 0; - icmp->icmp_id = icmp_ident; - icmp->icmp_seq = icmp_pkts_sent++; - echo = (icmpEchoData *) (icmp + 1); - /* echo = (icmpEchoData *) (pkt + icmp_pktsize); */ - echo->opcode = (unsigned char) opcode; - echo->tv = current_time; - icmp_pktsize += sizeof(icmpEchoData) - MAX_PAYLOAD; - if (payload) { - if (len == 0) - len = strlen(payload); - if (len > MAX_PAYLOAD) - len = MAX_PAYLOAD; - memcpy(echo->payload, payload, len); - icmp_pktsize += len; - } - icmp->icmp_cksum = in_cksum((u_short *) icmp, icmp_pktsize); - icmpQueueSend(to, pkt, icmp_pktsize, put_free_8k_page); + pingerEchoData *pecho = xcalloc(1, sizeof(pingerEchoData)); + if (payload && len == 0) + len = strlen(payload); + pecho->to = to; + pecho->opcode = (unsigned char) opcode; + pecho->psize = len; + memcpy(pecho->payload, payload, len); + icmpQueueSend(pecho, sizeof(pingerEchoData) - 8192 + len, xfree); } static void -icmpProcessReply(struct sockaddr_in *from, struct icmphdr *icmp, int hops) +icmpRecv(int unused1, void *unused2) { - int rtt; - icmpEchoData *echo = (icmpEchoData *) (icmp + 1); - rtt = tvSubMsec(echo->tv, current_time); - icmpLog(icmp, from->sin_addr, rtt, hops); - switch (echo->opcode) { + int n; + pingerReplyData preply; + static struct sockaddr_in F; + + comm_set_select_handler(icmp_sock, + COMM_SELECT_READ, + (PF) icmpRecv, + (void *) -1); + n = recv(icmp_sock, + (char *) &preply, + sizeof(pingerReplyData), + 0); + F.sin_family = AF_INET; + F.sin_addr = preply.from; + F.sin_port = 0; + switch (preply.opcode) { case S_ICMP_ECHO: break; case S_ICMP_ICP: - icmpHandleSourcePing(from, echo->payload); + icmpHandleSourcePing(&F, preply.payload); break; case S_ICMP_DOM: - netdbHandlePingReply(from, hops, rtt); + netdbHandlePingReply(&F, preply.hops, preply.rtt); break; default: - debug(37, 0, "icmpProcessReply: Bad opcode: %d\n", (int) echo->opcode); + debug(37, 0, "icmpRecv: Bad opcode: %d\n", (int) preply.opcode); break; } } -static void -icmpRecv(int unused1, void *unused2) -{ - int n; - int fromlen; - struct sockaddr_in from; - int iphdrlen = 20; - struct iphdr *ip = NULL; - register struct icmphdr *icmp = NULL; - char *pkt = get_free_8k_page(); - int hops; - - comm_set_select_handler(icmp_sock, - COMM_SELECT_READ, - (PF) icmpRecv, - (void *) -1); - fromlen = sizeof(from); - n = recvfrom(icmp_sock, - pkt, - 8192, - 0, - (struct sockaddr *) &from, - &fromlen); - debug(37, 9, "icmpRecv: %d bytes from %s\n", n, inet_ntoa(from.sin_addr)); - ip = (struct iphdr *) (void *) pkt; -#if HAVE_IP_HL - iphdrlen = ip->ip_hl << 2; -#else -#if BYTE_ORDER == BIG_ENDIAN - iphdrlen = (ip->ip_vhl >> 4) << 2; -#endif -#if BYTE_ORDER == LITTLE_ENDIAN - iphdrlen = (ip->ip_vhl & 0xF) << 2; -#endif -#endif - icmp = (struct icmphdr *) (void *) (pkt + iphdrlen); - if (icmp->icmp_type == ICMP_ECHOREPLY) { - if (icmp->icmp_id == icmp_ident) { - hops = ipHops(ip->ip_ttl); - icmpProcessReply(&from, icmp, hops); - } - } - put_free_8k_page(pkt); -} - - -static int -in_cksum(unsigned short *ptr, int size) -{ - - register long sum; - unsigned short oddbyte; - register unsigned short answer; - sum = 0; - while (size > 1) { - sum += *ptr++; - size -= 2; - } - if (size == 1) { - oddbyte = 0; - *((unsigned char *) &oddbyte) = *(unsigned char *) ptr; - sum += oddbyte; - } - sum = (sum >> 16) + (sum & 0xffff); - sum += (sum >> 16); - answer = ~sum; - return (answer); -} static void -icmpQueueSend(struct in_addr to, - char *pkt, +icmpQueueSend(pingerEchoData * pkt, int len, void (*free) _PARAMS((void *))) { icmpQueueData *q = NULL; icmpQueueData **H = NULL; - debug(37, 3, "icmpQueueSend: Queueing %d bytes for %s\n", len, inet_ntoa(to)); + debug(37, 3, "icmpQueueSend: Queueing %d bytes\n", len); q = xcalloc(1, sizeof(icmpQueueData)); - q->to.sin_family = AF_INET; - q->to.sin_addr = to; - q->msg = pkt; + q->msg = (char *) pkt; q->len = len; q->free = free; for (H = &IcmpQueueHead; *H; H = &(*H)->next); @@ -316,22 +194,19 @@ icmpSend(int fd, icmpQueueData * queue) { int x; while ((queue = IcmpQueueHead)) { - x = sendto(fd, + x = send(icmp_sock, queue->msg, queue->len, - 0, - (struct sockaddr *) &queue->to, - sizeof(struct sockaddr_in)); + 0); if (x < 0) { if (errno == EWOULDBLOCK || errno == EAGAIN) break; /* don't de-queue */ else - debug(37, 0, "icmpSend: sendto: %s\n", xstrerror()); + debug(37, 0, "icmpSend: send: %s\n", xstrerror()); } else if (x != queue->len) { debug(37, 0, "icmpSend: Wrote %d of %d bytes\n", x, queue->len); } IcmpQueueHead = queue->next; - icmpLog((struct icmphdr *) (void *) queue->msg, queue->to.sin_addr, 0, 0); if (queue->free) queue->free(queue->msg); safe_free(queue); @@ -350,33 +225,6 @@ icmpSend(int fd, icmpQueueData * queue) } } -static void -icmpLog(struct icmphdr *icmp, struct in_addr addr, int rtt, int hops) -{ - debug(37, 2, "icmpLog: %9d.%06d %-16s %d %-15.15s %dms %d hops\n", - (int) current_time.tv_sec, - (int) current_time.tv_usec, - inet_ntoa(addr), - (int) icmp->icmp_type, - icmpPktStr[icmp->icmp_type], - rtt, - hops); -} - -static int -ipHops(int ttl) -{ - if (ttl < 32) - return 32 - ttl; - if (ttl < 64) - return 62 - ttl; /* 62 = (64+60)/2 */ - if (ttl < 128) - return 128 - ttl; - if (ttl < 192) - return 192 - ttl; - return 255 - ttl; -} - void icmpPing(struct in_addr to) { @@ -404,6 +252,7 @@ icmpSourcePing(struct in_addr to, icp_common_t * header, char *url) void icmpDomainPing(struct in_addr to, char *domain) { + debug(37, 3, "icmpDomainPing: '%s'\n", domain); icmpSendEcho(to, S_ICMP_DOM, domain, 0); } diff --git a/src/main.cc b/src/main.cc index 98964f8966..3ef32947ae 100644 --- a/src/main.cc +++ b/src/main.cc @@ -1,5 +1,5 @@ /* - * $Id: main.cc,v 1.84 1996/09/20 20:27:49 wessels Exp $ + * $Id: main.cc,v 1.85 1996/09/20 23:26:57 wessels Exp $ * * DEBUG: section 1 Startup and Main Loop * AUTHOR: Harvest Derived @@ -370,7 +370,7 @@ serverConnectionsOpen(void) port, COMM_NONBLOCKING, "ICP Port"); - leave_suid(); + leave_suid(); if (theOutIcpConnection < 0) fatal("Cannot open Outgoing ICP Port"); comm_set_select_handler(theOutIcpConnection, diff --git a/src/net_db.cc b/src/net_db.cc index bba179a077..d15bbac726 100644 --- a/src/net_db.cc +++ b/src/net_db.cc @@ -13,8 +13,8 @@ static struct in_addr networkFromInaddr _PARAMS((struct in_addr a)); void netdbInit(void) { - addr_table = hash_create(strcmp, 229, hash_string); - host_table = hash_create(strcmp, 467, hash_string); + addr_table = hash_create((int (*)_PARAMS((char *, char *))) strcmp, 229, hash_string); + host_table = hash_create((int (*)_PARAMS((char *, char *))) strcmp, 467, hash_string); } static void diff --git a/src/pinger.cc b/src/pinger.cc new file mode 100644 index 0000000000..32d32eecee --- /dev/null +++ b/src/pinger.cc @@ -0,0 +1,355 @@ + +/* + * $Id: pinger.cc,v 1.1 1996/09/20 23:26:58 wessels Exp $ + * + * DEBUG: section 37 ICMP Routines + * AUTHOR: Duane Wessels + * + * SQUID Internet Object Cache http://www.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. + * + */ + +#if USE_ICMP + +#include "squid.h" +#include "pinger.h" + +#include +#include +#include +#include + +#ifndef _SQUID_LINUX_ +#define icmphdr icmp +#define iphdr ip +#endif + +#ifdef _SQUID_LINUX_ +#define icmp_type type +#define icmp_code code +#define icmp_cksum checksum +#define icmp_id un.echo.id +#define icmp_seq un.echo.sequence +#define icmp_gwaddr un.gateway +#define ip_hl ihl +#define ip_v version +#define ip_tos tos +#define ip_len tot_len +#define ip_id id +#define ip_off frag_off +#define ip_ttl ttl +#define ip_p protocol +#define ip_sum check +#define ip_src saddr +#define ip_dst daddr +#endif + +#define MAX_PAYLOAD (8192 - sizeof(struct icmphdr) - sizeof (char) - sizeof(struct timeval) - 1) + +typedef struct { + struct timeval tv; + unsigned char opcode; + char payload[MAX_PAYLOAD]; +} icmpEchoData; + +static int icmp_sock = -1; +static int icmp_ident = -1; +static int icmp_pkts_sent = 0; + +static char *icmpPktStr[] = +{ + "Echo Reply", + "ICMP 1", + "ICMP 2", + "Destination Unreachable", + "Source Quench", + "Redirect", + "ICMP 6", + "ICMP 7", + "Echo", + "ICMP 9", + "ICMP 10", + "Time Exceeded", + "Parameter Problem", + "Timestamp", + "Timestamp Reply", + "Info Request", + "Info Reply", + "Out of Range Type" +}; + +static int in_cksum _PARAMS((unsigned short *ptr, int size)); +static void pingerRecv _PARAMS((void)); +static void pingerLog _PARAMS((struct icmphdr * icmp, + struct in_addr addr, + int rtt, + int hops)); +static int ipHops _PARAMS((int ttl)); +static void pingerSendtoSquid _PARAMS((pingerReplyData * preply)); + +void +pingerOpen(void) +{ + struct protoent *proto = NULL; + if ((proto = getprotobyname("icmp")) == 0) { + debug(37, 0, "pingerOpen: unknown protocol: icmp\n"); + exit(1); + } + icmp_sock = socket(PF_INET, SOCK_RAW, proto->p_proto); + if (icmp_sock < 0) { + debug(37, 0, "pingerOpen: icmp_sock: %s\n", xstrerror()); + exit(1); + } + icmp_ident = getpid() & 0xffff; + debug(37, 0, "ICMP socket opened on FD %d\n", icmp_sock); +} + +/* Junk so we can link with debug.o */ +int opt_syslog_enable = 0; +int unbuffered_logs = 1; +char w_space[] = " \t\n\r"; +char appname[] = "pinger"; +struct timeval current_time; +time_t squid_curtime; +struct SquidConfig Config; + +void +pingerClose(void) +{ + close(icmp_sock); + icmp_sock = -1; + icmp_ident = 0; +} + +static void +pingerSendEcho(struct in_addr to, int opcode, char *payload, int len) +{ + LOCAL_ARRAY(char, pkt, 8192); + struct icmphdr *icmp = NULL; + icmpEchoData *echo; + int icmp_pktsize = sizeof(struct icmphdr); + int x; + struct sockaddr_in S; + memset(pkt, '\0', 8192); + icmp = (struct icmphdr *) (void *) pkt; + icmp->icmp_type = ICMP_ECHO; + icmp->icmp_code = 0; + icmp->icmp_cksum = 0; + icmp->icmp_id = icmp_ident; + icmp->icmp_seq = icmp_pkts_sent++; + echo = (icmpEchoData *) (icmp + 1); + echo->opcode = (unsigned char) opcode; + echo->tv = current_time; + icmp_pktsize += sizeof(icmpEchoData) - MAX_PAYLOAD; + if (payload) { + if (len > MAX_PAYLOAD) + len = MAX_PAYLOAD; + memcpy(echo->payload, payload, len); + icmp_pktsize += len; + } + icmp->icmp_cksum = in_cksum((u_short *) icmp, icmp_pktsize); + S.sin_family = AF_INET; + S.sin_addr = to; + S.sin_port = 0; + x = sendto(icmp_sock, + pkt, + icmp_pktsize, + 0, + (struct sockaddr *) &S, + sizeof(struct sockaddr_in)); + pingerLog(icmp, to, 0, 0); +} + +static void +pingerRecv(void) +{ + int n; + int fromlen; + struct sockaddr_in from; + int iphdrlen = 20; + struct iphdr *ip = NULL; + register struct icmphdr *icmp = NULL; + LOCAL_ARRAY(char, pkt, 8192); + struct timeval now; + icmpEchoData *echo; + static pingerReplyData preply; + + fromlen = sizeof(from); + n = recvfrom(icmp_sock, + pkt, + 8192, + 0, + (struct sockaddr *) &from, + &fromlen); + gettimeofday(&now, NULL); + debug(37, 9, "pingerRecv: %d bytes from %s\n", n, inet_ntoa(from.sin_addr)); + ip = (struct iphdr *) (void *) pkt; +#if HAVE_IP_HL + iphdrlen = ip->ip_hl << 2; +#else +#if BYTE_ORDER == BIG_ENDIAN + iphdrlen = (ip->ip_vhl >> 4) << 2; +#endif +#if BYTE_ORDER == LITTLE_ENDIAN + iphdrlen = (ip->ip_vhl & 0xF) << 2; +#endif +#endif + icmp = (struct icmphdr *) (void *) (pkt + iphdrlen); + if (icmp->icmp_type != ICMP_ECHOREPLY) + return; + if (icmp->icmp_id != icmp_ident) + return; + echo = (icmpEchoData *) (void *) (icmp + 1); + preply.from = from.sin_addr; + preply.opcode = echo->opcode; + preply.hops = ipHops(ip->ip_ttl); + preply.rtt = tvSubMsec(echo->tv, now); + preply.psize = n - iphdrlen - (sizeof(icmpEchoData) - 8192); + pingerSendtoSquid(&preply); + pingerLog(icmp, from.sin_addr, preply.rtt, preply.hops); +} + + +static int +in_cksum(unsigned short *ptr, int size) +{ + register long sum; + unsigned short oddbyte; + register unsigned short answer; + sum = 0; + while (size > 1) { + sum += *ptr++; + size -= 2; + } + if (size == 1) { + oddbyte = 0; + *((unsigned char *) &oddbyte) = *(unsigned char *) ptr; + sum += oddbyte; + } + sum = (sum >> 16) + (sum & 0xffff); + sum += (sum >> 16); + answer = ~sum; + return (answer); +} + +static void +pingerLog(struct icmphdr *icmp, struct in_addr addr, int rtt, int hops) +{ + debug(37, 2, "pingerLog: %9d.%06d %-16s %d %-15.15s %dms %d hops\n", + (int) current_time.tv_sec, + (int) current_time.tv_usec, + inet_ntoa(addr), + (int) icmp->icmp_type, + icmpPktStr[icmp->icmp_type], + rtt, + hops); +} + +static int +ipHops(int ttl) +{ + if (ttl < 32) + return 32 - ttl; + if (ttl < 64) + return 62 - ttl; /* 62 = (64+60)/2 */ + if (ttl < 128) + return 128 - ttl; + if (ttl < 192) + return 192 - ttl; + return 255 - ttl; +} + +static int +pingerReadRequest(void) +{ + static pingerEchoData pecho; + int n; + int guess_size; + n = recv(0, (char *) &pecho, sizeof(pecho), 0); + if (n < 0) { + perror("recv"); + return n; + } + guess_size = n - (sizeof(pingerEchoData) - 8192); + if (guess_size != pecho.psize) + fprintf(stderr, "size mismatch, guess=%d psize=%d\n", + guess_size, pecho.psize); + pingerSendEcho(pecho.to, + pecho.opcode, + pecho.payload, + pecho.psize); + return n; +} + +static void +pingerSendtoSquid(pingerReplyData * preply) +{ + int len = sizeof(pingerReplyData) - 8192 + preply->psize; + if (send(1, preply, len, 0) < 0) + perror("sendto"); +} + +time_t +getCurrentTime(void) +{ +#if GETTIMEOFDAY_NO_TZP + gettimeofday(¤t_time); +#else + gettimeofday(¤t_time, NULL); +#endif + return squid_curtime = current_time.tv_sec; +} + + +int +main(int argc, char *argv[]) +{ + fd_set R; + int x; + getCurrentTime(); + _db_init(NULL, "ALL,9"); + pingerOpen(); + for (;;) { + FD_ZERO(&R); + FD_SET(0, &R); + FD_SET(icmp_sock, &R); + x = select(icmp_sock + 1, &R, NULL, NULL, NULL); + getCurrentTime(); + if (x <= 0) + return 1; + if (FD_ISSET(0, &R)) + if (pingerReadRequest() < 0) + return 1; + if (FD_ISSET(icmp_sock, &R)) + pingerRecv(); + } +} +#else +#include +int +main(int argc, char *argv[]) +{ + fprintf(stderr, "%s: ICMP support not compiled in.\n", argv[0]); + return 1; +} +#endif /* USE_ICMP */ diff --git a/src/store.cc b/src/store.cc index c1c58259e6..05c26aa244 100644 --- a/src/store.cc +++ b/src/store.cc @@ -1,6 +1,6 @@ /* - * $Id: store.cc,v 1.119 1996/09/20 20:55:31 wessels Exp $ + * $Id: store.cc,v 1.120 1996/09/20 23:27:00 wessels Exp $ * * DEBUG: section 20 Storeage Manager * AUTHOR: Harvest Derived @@ -221,7 +221,7 @@ static void storeHashMemInsert _PARAMS((StoreEntry *)); static void storeHashMemDelete _PARAMS((StoreEntry *)); static int storeCopy _PARAMS((StoreEntry *, int, int, char *, int *)); static int storeGetMemSpace _PARAMS((int size)); -static int storeShouldPurgeMem _PARAMS((StoreEntry *e)); +static int storeShouldPurgeMem _PARAMS((StoreEntry * e)); /* Now, this table is inaccessible to outsider. They have to use a method * to access a value in internal storage data structure. */ @@ -566,7 +566,7 @@ storeUnlockObject(StoreEntry * e) return (int) e->lock_count; if (e->store_status == STORE_PENDING) { debug_trap("storeUnlockObject: Someone unlocked STORE_PENDING object"); - e->store_status = STORE_ABORTED; + e->store_status = STORE_ABORTED; } if (e->flag & RELEASE_REQUEST) { storeRelease(e); @@ -1886,8 +1886,8 @@ storeGetMemSpace(int size) /* Kick LRU out until we have enough memory space */ for (i = 0; i < list_count; i++) { - if (store_mem_size + size < store_mem_low) - break; + if (store_mem_size + size < store_mem_low) + break; e = *(list + i); if (storeCheckPurgeMem(e)) { storePurgeMem(e); @@ -2774,7 +2774,7 @@ storeRotateLog(void) } static int -storeShouldPurgeMem(StoreEntry *e) +storeShouldPurgeMem(StoreEntry * e) { if (storeCheckPurgeMem(e) == 0) return 0; diff --git a/src/tools.cc b/src/tools.cc index d08f3e09fd..af2e6b7850 100644 --- a/src/tools.cc +++ b/src/tools.cc @@ -1,6 +1,6 @@ /* - * $Id: tools.cc,v 1.62 1996/09/20 06:29:17 wessels Exp $ + * $Id: tools.cc,v 1.63 1996/09/20 23:27:01 wessels Exp $ * * DEBUG: section 21 Misc Functions * AUTHOR: Harvest Derived @@ -580,13 +580,6 @@ getCurrentTime(void) return squid_curtime = current_time.tv_sec; } -int -tvSubMsec(struct timeval t1, struct timeval t2) -{ - return (t2.tv_sec - t1.tv_sec) * 1000 + - (t2.tv_usec - t1.tv_usec) / 1000; -} - int percent(int a, int b) { @@ -608,20 +601,6 @@ squid_signal(int sig, void (*func) _PARAMS((int)), int flags) #endif } -char * -accessLogTime(time_t t) -{ - struct tm *tm; - static char buf[128]; - static time_t last_t = 0; - if (t != last_t) { - tm = localtime(&t); - strftime(buf, 127, "%y/%m/%d %T", tm); - last_t = t; - } - return buf; -} - struct in_addr inaddrFromHostent(struct hostent *hp) {