From: wessels <> Date: Tue, 17 Sep 1996 03:11:02 +0000 (+0000) Subject: mega-patch for ICMP support X-Git-Tag: SQUID_3_0_PRE1~5780 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=16b204c49631dd56570f689ee9ebc4208ed697ae;p=thirdparty%2Fsquid.git mega-patch for ICMP support --- diff --git a/src/Makefile.in b/src/Makefile.in index c492173f2f..821d5570c9 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.38 1996/09/13 20:22:58 wessels Exp $ +# $Id: Makefile.in,v 1.39 1996/09/16 21:11:02 wessels Exp $ # # Uncomment and customize the following to suit your needs: # @@ -58,7 +58,7 @@ 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 icp.o ident.o ipcache.o \ + hash.o http.o icmp.o icp.o ident.o ipcache.o \ main.o mime.o neighbors.o objcache.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 \ diff --git a/src/acl.cc b/src/acl.cc index e88ff0a974..f106b8f8c4 100644 --- a/src/acl.cc +++ b/src/acl.cc @@ -1,5 +1,5 @@ /* - * $Id: acl.cc,v 1.38 1996/09/16 17:21:36 wessels Exp $ + * $Id: acl.cc,v 1.39 1996/09/16 21:11:03 wessels Exp $ * * DEBUG: section 28 Access Control * AUTHOR: Duane Wessels @@ -179,7 +179,7 @@ decode_addr(char *asc, struct in_addr *addr, struct in_addr *mask) default: if ((hp = gethostbyname(asc)) != NULL) { /* We got a host name */ - xmemcpy(addr, hp->h_addr, hp->h_length); + *addr = inaddrFromHostent(hp); } else { /* XXX: Here we could use getnetbyname */ debug(28, 0, "decode_addr: Invalid IP address or hostname '%s'\n", asc); @@ -732,9 +732,7 @@ aclMatchAcl(struct _acl *acl, aclCheck_t * checklist) hp = ipcache_gethostbyname(r->host, IP_LOOKUP_IF_MISS); if (hp) { for (k = 0; *(hp->h_addr_list + k); k++) { - xmemcpy(&checklist->dst_addr.s_addr, - *(hp->h_addr_list + k), - hp->h_length); + checklist->dst_addr = inaddrFromHostent(hp); if (aclMatchIp(acl->data, checklist->dst_addr)) return 1; } diff --git a/src/cache_cf.cc b/src/cache_cf.cc index 3809058a9e..c5c18aea8f 100644 --- a/src/cache_cf.cc +++ b/src/cache_cf.cc @@ -1,5 +1,5 @@ /* - * $Id: cache_cf.cc,v 1.88 1996/09/15 05:04:13 wessels Exp $ + * $Id: cache_cf.cc,v 1.89 1996/09/16 21:11:03 wessels Exp $ * * DEBUG: section 3 Configuration File Parsing * AUTHOR: Harvest Derived @@ -878,7 +878,7 @@ parseAddressLine(struct in_addr *addr) if (inet_addr(token) != INADDR_NONE) (*addr).s_addr = inet_addr(token); else if ((hp = gethostbyname(token))) - xmemcpy(addr, hp->h_addr, hp->h_length); + *addr = inaddrFromHostent(hp); else self_destruct(); } diff --git a/src/client_side.cc b/src/client_side.cc index c8625969df..589eae56e4 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -1,6 +1,6 @@ /* - * $Id: client_side.cc,v 1.27 1996/09/16 17:16:01 wessels Exp $ + * $Id: client_side.cc,v 1.28 1996/09/16 21:11:04 wessels Exp $ * * DEBUG: section 33 Client-side Routines * AUTHOR: Duane Wessels @@ -44,9 +44,7 @@ clientLookupDstIPDone(int fd, struct hostent *hp, void *data) icpState->url); icpState->aclChecklist->state[ACL_DST_IP] = ACL_LOOKUP_DONE; if (hp) { - xmemcpy(&icpState->aclChecklist->dst_addr.s_addr, - *(hp->h_addr_list), - hp->h_length); + icpState->aclChecklist->dst_addr = inaddrFromHostent(hp); debug(33, 5, "clientLookupDstIPDone: %s is %s\n", icpState->request->host, inet_ntoa(icpState->aclChecklist->dst_addr)); diff --git a/src/comm.cc b/src/comm.cc index d9af2fbab4..5139f45cda 100644 --- a/src/comm.cc +++ b/src/comm.cc @@ -1,6 +1,6 @@ /* - * $Id: comm.cc,v 1.70 1996/09/15 08:06:29 wessels Exp $ + * $Id: comm.cc,v 1.71 1996/09/16 21:11:05 wessels Exp $ * * DEBUG: section 5 Socket Functions * AUTHOR: Harvest Derived @@ -224,15 +224,19 @@ commBind(int s, struct in_addr in_addr, u_short port) /* Create a socket. Default is blocking, stream (TCP) socket. IO_TYPE * is OR of flags specified in comm.h. */ int -comm_open(unsigned int io_type, struct in_addr addr, u_short port, char *note) +comm_open(int sock_type, + int proto, + struct in_addr addr, + u_short port, + int flags, + char *note) { int new_socket; FD_ENTRY *conn = NULL; - int sock_type = io_type & COMM_DGRAM ? SOCK_DGRAM : SOCK_STREAM; int tcp_rcv_bufsz = Config.tcpRcvBufsz; /* Create socket for accepting new connections. */ - if ((new_socket = socket(AF_INET, sock_type, 0)) < 0) { + if ((new_socket = socket(AF_INET, sock_type, proto)) < 0) { /* Increase the number of reserved fd's if calls to socket() * are failing because the open file table is full. This * limits the number of simultaneous clients */ @@ -256,7 +260,7 @@ comm_open(unsigned int io_type, struct in_addr addr, u_short port, char *note) fd_note(new_socket, note); conn->openned = 1; - if (!(io_type & COMM_NOCLOEXEC)) + if (!BIT_TEST(flags, COMM_NOCLOEXEC)) commSetCloseOnExec(new_socket); if (port > (u_short) 0) { commSetNoLinger(new_socket); @@ -268,7 +272,7 @@ comm_open(unsigned int io_type, struct in_addr addr, u_short port, char *note) return COMM_ERROR; conn->local_port = port; - if (io_type & COMM_NONBLOCKING) + if (BIT_TEST(flags, COMM_NONBLOCKING)) if (commSetNonBlocking(new_socket) == COMM_ERROR) return COMM_ERROR; #ifdef TCP_NODELAY @@ -277,7 +281,7 @@ comm_open(unsigned int io_type, struct in_addr addr, u_short port, char *note) #endif if (tcp_rcv_bufsz > 0 && sock_type == SOCK_STREAM) commSetTcpRcvbuf(new_socket, tcp_rcv_bufsz); - conn->comm_type = io_type; + conn->comm_type = sock_type; return new_socket; } @@ -315,7 +319,7 @@ comm_connect(int sock, char *dest_host, u_short dest_port) debug(5, 3, "comm_connect: Failure to lookup host: %s.\n", dest_host); return (COMM_ERROR); } - xmemcpy(&to_addr.sin_addr, hp->h_addr, hp->h_length); + to_addr.sin_addr = inaddrFromHostent(hp); to_addr.sin_port = htons(dest_port); if (Config.Log.log_fqdn) fqdncache_gethostbyaddr(to_addr.sin_addr, FQDN_LOOKUP_IF_MISS); @@ -526,7 +530,7 @@ comm_udp_send(int fd, char *host, u_short port, char *buf, int len) host, xstrerror()); return (COMM_ERROR); } - xmemcpy(&to_addr.sin_addr, hp->h_addr, hp->h_length); + to_addr.sin_addr = inaddrFromHostent(hp); to_addr.sin_port = htons(port); if ((bytes_sent = sendto(fd, buf, len, 0, (struct sockaddr *) &to_addr, sizeof(to_addr))) < 0) { diff --git a/src/dns.cc b/src/dns.cc index f331d99ffa..0f80c9ee76 100644 --- a/src/dns.cc +++ b/src/dns.cc @@ -1,5 +1,5 @@ /* - * $Id: dns.cc,v 1.8 1996/09/15 05:04:20 wessels Exp $ + * $Id: dns.cc,v 1.9 1996/09/16 21:11:06 wessels Exp $ * * DEBUG: section 34 Dnsserver interface * AUTHOR: Harvest Derived @@ -129,9 +129,11 @@ dnsOpenServer(char *command) int len; LOCAL_ARRAY(char, buf, 128); - cfd = comm_open(COMM_NOCLOEXEC, + cfd = comm_open(SOCK_STREAM, + 0, local_addr, 0, + COMM_NOCLOEXEC, "socket to dnsserver"); if (cfd == COMM_ERROR) { debug(34, 0, "dnsOpenServer: Failed to create dnsserver\n"); @@ -155,7 +157,12 @@ dnsOpenServer(char *command) if (pid > 0) { /* parent */ comm_close(cfd); /* close shared socket with child */ /* open new socket for parent process */ - sfd = comm_open(0, local_addr, 0, NULL); /* blocking! */ + sfd = comm_open(SOCK_STREAM, + 0, /* protocol */ + local_addr, + 0, /* port */ + 0, /* flags */ + NULL); /* blocking! */ if (sfd == COMM_ERROR) return -1; if (comm_connect(sfd, localhost, port) == COMM_ERROR) { diff --git a/src/ftp.cc b/src/ftp.cc index add3292137..014ffd14a2 100644 --- a/src/ftp.cc +++ b/src/ftp.cc @@ -1,6 +1,6 @@ /* - * $Id: ftp.cc,v 1.56 1996/09/15 05:04:26 wessels Exp $ + * $Id: ftp.cc,v 1.57 1996/09/16 21:11:07 wessels Exp $ * * DEBUG: section 9 File Transfer Protocol (FTP) * AUTHOR: Harvest Derived @@ -615,9 +615,11 @@ ftpStart(int unusedfd, char *url, request_t * request, StoreEntry * entry) unusedfd, data->request->host, data->request->urlpath, data->user, data->password); - data->ftp_fd = comm_open(COMM_NONBLOCKING, + data->ftp_fd = comm_open(SOCK_STREAM, + 0, local_addr, 0, + COMM_NONBLOCKING, url); if (data->ftp_fd == COMM_ERROR) { squid_error_entry(entry, ERR_CONNECT_FAIL, xstrerror()); @@ -724,9 +726,11 @@ ftpInitialize() debug(9, 0, "ftpInitialize: pipe: %s\n", xstrerror()); return -1; } - cfd = comm_open(COMM_NOCLOEXEC, + cfd = comm_open(SOCK_STREAM, + 0, local_addr, 0, + COMM_NOCLOEXEC, "ftpget -S socket"); debug(9, 5, "ftpget -S socket on FD %d\n", cfd); if (cfd == COMM_ERROR) { diff --git a/src/gopher.cc b/src/gopher.cc index b514e25a71..437e9738c3 100644 --- a/src/gopher.cc +++ b/src/gopher.cc @@ -1,5 +1,5 @@ /* - * $Id: gopher.cc,v 1.46 1996/09/15 05:04:28 wessels Exp $ + * $Id: gopher.cc,v 1.47 1996/09/16 21:11:07 wessels Exp $ * * DEBUG: section 10 Gopher * AUTHOR: Harvest Derived @@ -977,7 +977,12 @@ gopherStart(int unusedfd, char *url, StoreEntry * entry) return COMM_ERROR; } /* Create socket. */ - sock = comm_open(COMM_NONBLOCKING, Config.Addrs.tcp_outgoing, 0, url); + sock = comm_open(SOCK_STREAM, + 0, + Config.Addrs.tcp_outgoing, + 0, + COMM_NONBLOCKING, + url); if (sock == COMM_ERROR) { debug(10, 4, "gopherStart: Failed because we're out of sockets.\n"); squid_error_entry(entry, ERR_NO_FDS, xstrerror()); diff --git a/src/http.cc b/src/http.cc index 87eff3c8b0..67c3396569 100644 --- a/src/http.cc +++ b/src/http.cc @@ -1,5 +1,5 @@ /* - * $Id: http.cc,v 1.75 1996/09/15 05:04:31 wessels Exp $ + * $Id: http.cc,v 1.76 1996/09/16 21:11:08 wessels Exp $ * * DEBUG: section 11 Hypertext Transfer Protocol (HTTP) * AUTHOR: Harvest Derived @@ -683,7 +683,12 @@ proxyhttpStart(edge * e, char *url, StoreEntry * entry) storeStartDeleteBehind(entry); /* Create socket. */ - sock = comm_open(COMM_NONBLOCKING, Config.Addrs.tcp_outgoing, 0, url); + sock = comm_open(SOCK_STREAM, + 0, + Config.Addrs.tcp_outgoing, + 0, + COMM_NONBLOCKING, + url); if (sock == COMM_ERROR) { debug(11, 4, "proxyhttpStart: Failed because we're out of sockets.\n"); squid_error_entry(entry, ERR_NO_FDS, xstrerror()); @@ -767,7 +772,12 @@ httpStart(int unusedfd, char *url, request_t * request, char *req_hdr, StoreEntr debug(11, 10, "httpStart: req_hdr '%s'\n", req_hdr); /* Create socket. */ - sock = comm_open(COMM_NONBLOCKING, Config.Addrs.tcp_outgoing, 0, url); + sock = comm_open(SOCK_STREAM, + 0, + Config.Addrs.tcp_outgoing, + 0, + COMM_NONBLOCKING, + url); if (sock == COMM_ERROR) { debug(11, 4, "httpStart: Failed because we're out of sockets.\n"); squid_error_entry(entry, ERR_NO_FDS, xstrerror()); diff --git a/src/icmp.cc b/src/icmp.cc index effd62960f..d9e9d6abce 100644 --- a/src/icmp.cc +++ b/src/icmp.cc @@ -31,12 +31,71 @@ #define ip_dst daddr #endif +#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) __P((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 __P((unsigned short *ptr, int size)); +static void icmpRecv __P((int, void *)); +static void icmpQueueSend __P((struct in_addr, + char *msg, + int len, + void (*free) __P((void *)))); +static void icmpSend __P((int fd, icmpQueueData * queue)); +static void icmpLog __P((struct icmphdr * icmp, + struct in_addr addr, + int rtt, + int hops)); +static int ipHops __P((int ttl)); +static void icmpProcessReply __P((struct sockaddr_in * from, + struct icmphdr * icmp, + int hops)); +static void icmpHandleSourcePing __P((struct sockaddr_in * from, char *buf)); void icmpOpen(void) @@ -47,16 +106,26 @@ icmpOpen(void) return; } enter_suid(); - if ((icmp_sock = socket(AF_INET, SOCK_RAW, proto->p_proto)) < 0) { + icmp_sock = comm_open(SOCK_RAW, + proto->p_proto, + Config.Addrs.udp_outgoing, + 0, + COMM_NONBLOCKING, + "ICMP Socket"); + leave_suid(); + if (icmp_sock < 0) { debug(37, 0, "icmpOpen: icmp_sock: %s\n", xstrerror()); return; } - leave_suid(); icmp_ident = getpid() & 0xffff; + comm_set_select_handler(icmp_sock, + COMM_SELECT_READ, + (PF) icmpRecv, + (void *) -1); debug(37, 0, "icmpOpen: icmp_sock opened on FD %d\n", icmp_sock); } -void +void icmpClose(void) { comm_close(icmp_sock); @@ -64,60 +133,108 @@ icmpClose(void) icmp_ident = 0; } -void -icmpSendEcho(struct in_addr to, char *payload, int len) +static void +icmpSendEcho(struct in_addr to, int opcode, char *payload, int len) { char *pkt = NULL; - struct icmphdr *icp = NULL; - struct timeval *tv; - int icmp_pktsize = sizeof(struct icmphdr) + sizeof(struct timeval); - int i; + struct icmphdr *icmp = NULL; + icmpEchoData *echo; + int icmp_pktsize = sizeof(struct icmphdr); pkt = get_free_8k_page(); memset(pkt, '\0', 8192); - icp = (struct icmphdr *) pkt; - icp->icmp_type = ICMP_ECHO; - icp->icmp_code = 0; - icp->icmp_cksum = 0; - icp->icmp_id = icmp_ident; - icp->icmp_seq = icmp_pkts_sent++; - tv = (struct timeval *) (pkt + sizeof(struct icmphdr)); - *tv = current_time; + icmp = (struct icmphdr *) 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 > (8192 - icmp_pktsize)) - len = 8192 - icmp_pktsize; - memcpy(pkt + icmp_pktsize, payload, len); + if (len == 0) + len = strlen(payload); + if (len > MAX_PAYLOAD) + len = MAX_PAYLOAD; + memcpy(echo->payload, payload, len); icmp_pktsize += len; } - icp->icmp_cksum = in_cksum((u_short *) icp, icmp_pktsize); - i = sendto(icmp_sock, pkt, icmp_pktsize, 0, - (struct sockaddr *) &to, sizeof(struct sockaddr_in)); - if (i < 0) - debug(37, 0, "icmpSendEcho: sendto: %s\n", xstrerror()); - else if (i != icmp_pktsize) - debug(37, 0, "icmpSendEcho: Only wrote %d of %d bytes\n", - i, icmp_pktsize); + icmp->icmp_cksum = in_cksum((u_short *) icmp, icmp_pktsize); + icmpQueueSend(to, pkt, icmp_pktsize, put_free_8k_page); } -void -icmpRecv(void) +static void +icmpProcessReply(struct sockaddr_in *from, struct icmphdr *icmp, int hops) { + int rtt; + icmpEchoData *echo = (icmpEchoData *) (icmp + 1); + rtt = tvSubMsec(echo->tv, current_time); + icmpLog(icmp, from->sin_addr, rtt, hops); + switch (echo->opcode) { + case S_ICMP_ECHO: + break; + case S_ICMP_ICP: + icmpHandleSourcePing(from, echo->payload); + break; + case S_ICMP_DOM: + break; + default: + debug(37, 0, "icmpProcessReply: Bad opcode: %d\n", (int) echo->opcode); + break; + } } +static void +icmpRecv(int unused1, void *unused2) +{ + int n; + int fromlen; + struct sockaddr_in from; + int iphdrlen; + struct iphdr *ip = NULL; + register struct icmphdr *icmp = NULL; + char *pkt = get_free_8k_page(); + int hops; -int + 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 *) pkt; + iphdrlen = ip->ip_hl << 2; + icmp = (struct icmphdr *) (pkt + iphdrlen); + if (icmp->icmp_type != ICMP_ECHOREPLY) + return; + if (icmp->icmp_id != icmp_ident) + return; + 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; @@ -128,3 +245,153 @@ in_cksum(unsigned short *ptr, int size) answer = ~sum; return (answer); } + +static void +icmpQueueSend(struct in_addr to, + char *pkt, + int len, + void (*free) __P((void *))) +{ + icmpQueueData *q = NULL; + icmpQueueData **H = NULL; + debug(37, 3, "icmpQueueSend: Queueing %d bytes for %s\n", len, inet_ntoa(to)); + q = xcalloc(1, sizeof(icmpQueueData)); + q->to.sin_family = AF_INET; + q->to.sin_addr = to; + q->msg = pkt; + q->len = len; + q->free = free; + for (H = &IcmpQueueHead; *H; H = &(*H)->next); + *H = q; + comm_set_select_handler(icmp_sock, + COMM_SELECT_WRITE, + (PF) icmpSend, + (void *) IcmpQueueHead); +} + +void +icmpSend(int fd, icmpQueueData * queue) +{ + int x; + while ((queue = IcmpQueueHead)) { + x = sendto(fd, + queue->msg, + queue->len, + 0, + (struct sockaddr *) &queue->to, + sizeof(struct sockaddr_in)); + if (x < 0) { + if (errno == EWOULDBLOCK || errno == EAGAIN) + break; /* don't de-queue */ + else + debug(37, 0, "icmpSend: sendto: %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 *) queue->msg, queue->to.sin_addr, 0, 0); + if (queue->free) + queue->free(queue->msg); + safe_free(queue); + } + /* Reinstate handler if needed */ + if (IcmpQueueHead) { + comm_set_select_handler(fd, + COMM_SELECT_WRITE, + (PF) icmpSend, + (void *) IcmpQueueHead); + } else { + comm_set_select_handler(fd, + COMM_SELECT_WRITE, + NULL, + NULL); + } +} + +static void +icmpLog(struct icmphdr *icmp, struct in_addr addr, int rtt, int hops) +{ + debug(0, 0, "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) +{ + icmpSendEcho(to, S_ICMP_ECHO, NULL, 0); +} + +void +icmpSourcePing(struct in_addr to, icp_common_t * header, char *url) +{ + char *payload; + int len; + int ulen; + debug(37, 3, "icmpSourcePing: '%s'\n", url); + if ((ulen = strlen(url)) > MAX_URL) + return; + payload = get_free_8k_page(); + len = sizeof(icp_common_t); + memcpy(payload, header, len); + strcpy(payload + len, url); + len += ulen + 1; + icmpSendEcho(to, S_ICMP_ICP, payload, len); + put_free_8k_page(payload); +} + +void +icmpDomainPing(struct in_addr to, char *domain) +{ + icmpSendEcho(to, S_ICMP_DOM, domain, 0); +} + +static void +icmpHandleSourcePing(struct sockaddr_in *from, char *buf) +{ + char *key; + StoreEntry *entry; + icp_common_t header; + char *url; + memcpy(&header, buf, sizeof(icp_common_t)); + url = buf + sizeof(icp_common_t); + if (neighbors_do_private_keys && header.reqnum) { + key = storeGeneratePrivateKey(url, METHOD_GET, header.reqnum); + } else { + key = storeGeneratePublicKey(url, METHOD_GET); + } + debug(37, 3, "icmpHandleSourcePing: from %s, key=%s\n", + inet_ntoa(from->sin_addr), + key); + if ((entry = storeGet(key)) == NULL) + return; + if (entry->lock_count == 0) + return; + /* call neighborsUdpAck even if ping_status != PING_WAITING */ + neighborsUdpAck(icmp_sock, + url, + &header, + from, + entry, + NULL, + 0); +} diff --git a/src/ident.cc b/src/ident.cc index dac2e46e4c..b4a3ca3dc3 100644 --- a/src/ident.cc +++ b/src/ident.cc @@ -1,5 +1,5 @@ /* - * $Id: ident.cc,v 1.12 1996/09/15 05:04:34 wessels Exp $ + * $Id: ident.cc,v 1.13 1996/09/16 21:11:09 wessels Exp $ * * DEBUG: section 30 Ident (RFC 931) * AUTHOR: Duane Wessels @@ -55,7 +55,12 @@ identStart(int sock, icpStateData * icpState) port = ntohs(icpState->peer.sin_port); if (sock < 0) { - sock = comm_open(COMM_NONBLOCKING, Config.Addrs.tcp_outgoing, 0, "ident"); + sock = comm_open(SOCK_STREAM, + 0, + Config.Addrs.tcp_outgoing, + 0, + COMM_NONBLOCKING, + "ident"); if (sock == COMM_ERROR) return; } diff --git a/src/ipcache.cc b/src/ipcache.cc index 204830ed7a..2582748d6f 100644 --- a/src/ipcache.cc +++ b/src/ipcache.cc @@ -1,5 +1,5 @@ /* - * $Id: ipcache.cc,v 1.59 1996/09/16 17:21:42 wessels Exp $ + * $Id: ipcache.cc,v 1.60 1996/09/16 21:11:10 wessels Exp $ * * DEBUG: section 14 IP Cache * AUTHOR: Harvest Derived @@ -880,17 +880,13 @@ ipcacheStatPrint(ipcache_entry * i, StoreEntry * sentry) (int) (squid_curtime - i->lastref), (int) (i->expires - squid_curtime), i->addr_count); - for (k = 0; k < (int) i->addr_count; k++) { - struct in_addr addr; - xmemcpy(&addr, i->entry.h_addr_list[k], i->entry.h_length); - storeAppendPrintf(sentry, " %15s", inet_ntoa(addr)); - } - for (k = 0; k < (int) i->alias_count; k++) { + for (k = 0; k < (int) i->addr_count; k++) + storeAppendPrintf(sentry, " %15s", + inet_ntoa(inaddrFromHostent(&i->entry))); + for (k = 0; k < (int) i->alias_count; k++) storeAppendPrintf(sentry, " %s", i->entry.h_aliases[k]); - } - if (i->entry.h_name && strncmp(i->name, i->entry.h_name, MAX_LINELEN)) { + if (i->entry.h_name && strncmp(i->name, i->entry.h_name, MAX_LINELEN)) storeAppendPrintf(sentry, " %s", i->entry.h_name); - } storeAppendPrintf(sentry, close_bracket); } diff --git a/src/main.cc b/src/main.cc index 2dc34cbde9..ce9b7a56ef 100644 --- a/src/main.cc +++ b/src/main.cc @@ -1,5 +1,5 @@ /* - * $Id: main.cc,v 1.75 1996/09/16 17:21:43 wessels Exp $ + * $Id: main.cc,v 1.76 1996/09/16 21:11:11 wessels Exp $ * * DEBUG: section 1 Startup and Main Loop * AUTHOR: Harvest Derived @@ -320,9 +320,11 @@ serverConnectionsOpen() /* Open server ports */ enter_suid(); - theHttpConnection = comm_open(COMM_NONBLOCKING, + theHttpConnection = comm_open(SOCK_STREAM, + 0, Config.Addrs.tcp_incoming, Config.Port.http, + COMM_NONBLOCKING, "HTTP Port"); leave_suid(); if (theHttpConnection < 0) { @@ -339,9 +341,11 @@ serverConnectionsOpen() if (!httpd_accel_mode || Config.Accel.withProxy) { if ((port = Config.Port.icp) > (u_short) 0) { - theInIcpConnection = comm_open(COMM_NONBLOCKING | COMM_DGRAM, + theInIcpConnection = comm_open(SOCK_DGRAM, + 0, Config.Addrs.udp_incoming, port, + COMM_NONBLOCKING, "ICP Port"); if (theInIcpConnection < 0) fatal("Cannot open ICP Port"); @@ -354,9 +358,11 @@ serverConnectionsOpen() theInIcpConnection); if ((addr = Config.Addrs.udp_outgoing).s_addr != INADDR_NONE) { - theOutIcpConnection = comm_open(COMM_NONBLOCKING | COMM_DGRAM, + theOutIcpConnection = comm_open(SOCK_DGRAM, + 0, addr, port, + COMM_NONBLOCKING, "ICP Port"); if (theOutIcpConnection < 0) fatal("Cannot open Outgoing ICP Port"); @@ -373,6 +379,7 @@ serverConnectionsOpen() } } } + icmpOpen(); } void @@ -408,6 +415,7 @@ serverConnectionsClose() 0); theInIcpConnection = -1; } + icmpClose(); } static void diff --git a/src/neighbors.cc b/src/neighbors.cc index be0a5ae284..b874763169 100644 --- a/src/neighbors.cc +++ b/src/neighbors.cc @@ -1,5 +1,5 @@ /* - * $Id: neighbors.cc,v 1.52 1996/09/15 05:04:37 wessels Exp $ + * $Id: neighbors.cc,v 1.53 1996/09/16 21:11:12 wessels Exp $ * * DEBUG: section 15 Neighbor Routines * AUTHOR: Harvest Derived @@ -506,18 +506,22 @@ neighborsUdpPing(protodispatch_data * proto) } else if ((hep = ipcache_gethostbyname(host, IP_BLOCKING_LOOKUP))) { debug(15, 6, "neighborsUdpPing: Source Ping: to %s for '%s'\n", host, url); - to_addr.sin_family = AF_INET; - xmemcpy(&to_addr.sin_addr, hep->h_addr, hep->h_length); - to_addr.sin_port = htons(echo_port); echo_hdr.reqnum = reqnum; - icpUdpSend(theOutIcpConnection, - url, - &echo_hdr, - &to_addr, - entry->flag, - ICP_OP_SECHO, - LOG_TAG_NONE, - PROTO_NONE); + if (icmp_sock != -1) { + icmpSourcePing(inaddrFromHostent(hep), &echo_hdr, url); + } else { + to_addr.sin_family = AF_INET; + to_addr.sin_addr = inaddrFromHostent(hep); + to_addr.sin_port = htons(echo_port); + icpUdpSend(theOutIcpConnection, + url, + &echo_hdr, + &to_addr, + entry->flag, + ICP_OP_SECHO, + LOG_TAG_NONE, + PROTO_NONE); + } } else { debug(15, 6, "neighborsUdpPing: Source Ping: unknown host: %s\n", host); diff --git a/src/redirect.cc b/src/redirect.cc index 666d171ed9..f2ce4622ea 100644 --- a/src/redirect.cc +++ b/src/redirect.cc @@ -1,5 +1,5 @@ /* - * $Id: redirect.cc,v 1.15 1996/09/15 05:04:40 wessels Exp $ + * $Id: redirect.cc,v 1.16 1996/09/16 21:11:13 wessels Exp $ * * DEBUG: section 29 Redirector * AUTHOR: Duane Wessels @@ -96,9 +96,11 @@ redirectCreateRedirector(char *command) int len; int fd; struct timeval slp; - cfd = comm_open(COMM_NOCLOEXEC, + cfd = comm_open(SOCK_STREAM, + 0, local_addr, 0, + COMM_NOCLOEXEC, "socket to redirector"); if (cfd == COMM_ERROR) { debug(29, 0, "redirect_create_redirector: Failed to create redirector\n"); @@ -121,7 +123,12 @@ redirectCreateRedirector(char *command) if (pid > 0) { /* parent */ comm_close(cfd); /* close shared socket with child */ /* open new socket for parent process */ - sfd = comm_open(0, local_addr, 0, NULL); /* blocking! */ + sfd = comm_open(SOCK_STREAM, + 0, + local_addr, + 0, + 0, + NULL); /* blocking! */ if (sfd == COMM_ERROR) return -1; if (comm_connect(sfd, localhost, port) == COMM_ERROR) { diff --git a/src/send-announce.cc b/src/send-announce.cc index 0dc3d012e0..421e495a74 100644 --- a/src/send-announce.cc +++ b/src/send-announce.cc @@ -1,6 +1,6 @@ /* - * $Id: send-announce.cc,v 1.17 1996/09/14 08:46:22 wessels Exp $ + * $Id: send-announce.cc,v 1.18 1996/09/16 21:11:14 wessels Exp $ * * DEBUG: section 27 Cache Announcer * AUTHOR: Duane Wessels @@ -84,7 +84,7 @@ send_announce() qdata->len = strlen(sndbuf) + 1; qdata->address.sin_family = AF_INET; qdata->address.sin_port = htons(port); - xmemcpy(&qdata->address.sin_addr, *(hp->h_addr_list + 0), hp->h_length); + qdata->address.sin_addr = inaddrFromHostent(hp); AppendUdp(qdata); comm_set_select_handler(theOutIcpConnection, COMM_SELECT_WRITE, diff --git a/src/squid.h b/src/squid.h index c352a7de90..9ac08387e5 100644 --- a/src/squid.h +++ b/src/squid.h @@ -1,6 +1,6 @@ /* - * $Id: squid.h,v 1.48 1996/09/16 17:31:51 wessels Exp $ + * $Id: squid.h,v 1.49 1996/09/16 21:11:14 wessels Exp $ * * AUTHOR: Duane Wessels * @@ -249,6 +249,7 @@ typedef int (*QS) (const void *, const void *); #include "async_io.h" #include "redirect.h" #include "client_side.h" +#include "icmp.h" #if !HAVE_TEMPNAM #include "tempnam.h" diff --git a/src/ssl.cc b/src/ssl.cc index 966b103719..a92afbe252 100644 --- a/src/ssl.cc +++ b/src/ssl.cc @@ -1,6 +1,6 @@ /* - * $Id: ssl.cc,v 1.15 1996/09/15 05:04:42 wessels Exp $ + * $Id: ssl.cc,v 1.16 1996/09/16 21:11:15 wessels Exp $ * * DEBUG: section 26 Secure Sockets Layer Proxy * AUTHOR: Duane Wessels @@ -434,7 +434,12 @@ sslStart(int fd, char *url, request_t * request, char *mime_hdr, int *size_ptr) RequestMethodStr[request->method], url); /* Create socket. */ - sock = comm_open(COMM_NONBLOCKING, Config.Addrs.tcp_outgoing, 0, url); + sock = comm_open(SOCK_STREAM, + 0, + Config.Addrs.tcp_outgoing, + 0, + COMM_NONBLOCKING, + url); if (sock == COMM_ERROR) { debug(26, 4, "sslStart: Failed because we're out of sockets.\n"); buf = squid_error_url(url, diff --git a/src/tools.cc b/src/tools.cc index 2ea1758203..f29a91f4c4 100644 --- a/src/tools.cc +++ b/src/tools.cc @@ -1,6 +1,6 @@ /* - * $Id: tools.cc,v 1.57 1996/09/14 08:46:34 wessels Exp $ + * $Id: tools.cc,v 1.58 1996/09/16 21:11:16 wessels Exp $ * * DEBUG: section 21 Misc Functions * AUTHOR: Harvest Derived @@ -621,3 +621,11 @@ accessLogTime(time_t t) } return buf; } + +struct in_addr +inaddrFromHostent(struct hostent *hp) +{ + struct in_addr s; + memcpy(&s.s_addr, hp->h_addr, sizeof(s.s_addr)); + return s; +} diff --git a/src/tunnel.cc b/src/tunnel.cc index ee4278800d..327f6465f8 100644 --- a/src/tunnel.cc +++ b/src/tunnel.cc @@ -1,6 +1,6 @@ /* - * $Id: tunnel.cc,v 1.15 1996/09/15 05:04:42 wessels Exp $ + * $Id: tunnel.cc,v 1.16 1996/09/16 21:11:15 wessels Exp $ * * DEBUG: section 26 Secure Sockets Layer Proxy * AUTHOR: Duane Wessels @@ -434,7 +434,12 @@ sslStart(int fd, char *url, request_t * request, char *mime_hdr, int *size_ptr) RequestMethodStr[request->method], url); /* Create socket. */ - sock = comm_open(COMM_NONBLOCKING, Config.Addrs.tcp_outgoing, 0, url); + sock = comm_open(SOCK_STREAM, + 0, + Config.Addrs.tcp_outgoing, + 0, + COMM_NONBLOCKING, + url); if (sock == COMM_ERROR) { debug(26, 4, "sslStart: Failed because we're out of sockets.\n"); buf = squid_error_url(url, diff --git a/src/wais.cc b/src/wais.cc index 6b5f759bae..e5e42754df 100644 --- a/src/wais.cc +++ b/src/wais.cc @@ -1,6 +1,6 @@ /* - * $Id: wais.cc,v 1.41 1996/09/15 05:04:49 wessels Exp $ + * $Id: wais.cc,v 1.42 1996/09/16 21:11:17 wessels Exp $ * * DEBUG: section 24 WAIS Relay * AUTHOR: Harvest Derived @@ -385,7 +385,12 @@ waisStart(int unusedfd, char *url, method_t method, char *mime_hdr, StoreEntry * squid_error_entry(entry, ERR_NO_RELAY, NULL); return COMM_ERROR; } - fd = comm_open(COMM_NONBLOCKING, Config.Addrs.tcp_outgoing, 0, url); + fd = comm_open(SOCK_STREAM, + 0, + Config.Addrs.tcp_outgoing, + 0, + COMM_NONBLOCKING, + url); if (fd == COMM_ERROR) { debug(24, 4, "waisStart: Failed because we're out of sockets.\n"); squid_error_entry(entry, ERR_NO_FDS, xstrerror());