]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
mega-patch for ICMP support
authorwessels <>
Tue, 17 Sep 1996 03:11:02 +0000 (03:11 +0000)
committerwessels <>
Tue, 17 Sep 1996 03:11:02 +0000 (03:11 +0000)
21 files changed:
src/Makefile.in
src/acl.cc
src/cache_cf.cc
src/client_side.cc
src/comm.cc
src/dns.cc
src/ftp.cc
src/gopher.cc
src/http.cc
src/icmp.cc
src/ident.cc
src/ipcache.cc
src/main.cc
src/neighbors.cc
src/redirect.cc
src/send-announce.cc
src/squid.h
src/ssl.cc
src/tools.cc
src/tunnel.cc
src/wais.cc

index c492173f2f8fc25eb8bd70e644ce5dfc2dc5fbef..821d5570c968649527407a7d8d5ba1de4d4c6ade 100644 (file)
@@ -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 \
index e88ff0a9749038c6bca4d728a326065555c49a2e..f106b8f8c46d7e0c44d50975e66d1cff0fe88b4b 100644 (file)
@@ -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;
            }
index 3809058a9e3a198bc6cdb398c79ff2be937bfce8..c5c18aea8f438f461e41e0f470682bf7c60e1355 100644 (file)
@@ -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();
 }
index c8625969df71da6b67c42bc83eeb1aeb7e8ebfc0..589eae56e46fb3af004e5fc28adcca6ed6cf2580 100644 (file)
@@ -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));
index d9af2fbab40e662c202d209b7d0759eaa44526a2..5139f45cda83c9c414415b1059bd6c958ee02850 100644 (file)
@@ -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) {
index f331d99ffac349ac2ddb64184c599d40eea6cdd4..0f80c9ee76f34c274003c16ab347105c68527277 100644 (file)
@@ -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) {
index add32921372ed51de33d16ddb777458f9c78b7d8..014ffd14a2be520e91ffad555f4310c6e192766b 100644 (file)
@@ -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) {
index b514e25a710d8b28b5ec8088f63fc10f687bbbd2..437e9738c335111a35d7ec2a7da949994967a1c1 100644 (file)
@@ -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());
index 87eff3c8b037c38cacf7286705df5cd9b8703026..67c3396569f93740edea330d0ee87bea1949fe4d 100644 (file)
@@ -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());
index effd62960f072e942a35e72774eb168c966ee90e..d9e9d6abcecbb6a2b076533be97ce6a5f08fcdfd 100644 (file)
 #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);
+}
index dac2e46e4c14c58d1a1841bc6aa80f1946bc7e15..b4a3ca3dc3c47f3b99c5c41b97aaab07b5e77b2a 100644 (file)
@@ -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;
     }
index 204830ed7a9e0bc4ff5e7db3f97eeccdd0290e4a..2582748d6fdeeafe587e9323ba37807ec3a9e8c9 100644 (file)
@@ -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);
 }
 
index 2dc34cbde9a407ca936758661b39f1e83eb974f1..ce9b7a56ef24660580610b5fe09e80540e404d90 100644 (file)
@@ -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
index be0a5ae2842f07cf64c973d8568127c20370b9b9..b87476316936aa1382d360a39b313732132f9abe 100644 (file)
@@ -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);
index 666d171ed96d84314d1f18f9d11cb59d01aebf2f..f2ce4622ea0daea98420d40c11b43a73bf28e860 100644 (file)
@@ -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) {
index 0dc3d012e01c2e4b8951d7ce7fcd3eae5b955cbf..421e495a74394306b51f7e14d5b471aad61f5c7c 100644 (file)
@@ -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,
index c352a7de90ba2b4fd72e0c56858bb93384c46d8d..9ac08387e5879e6f45ae4bdc0a99a92eead08a68 100644 (file)
@@ -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"
index 966b10371966f4f9ba056bed62885e4847989895..a92afbe2520788024684aa0b1ac2806d9b955cd0 100644 (file)
@@ -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,
index 2ea1758203489b67dd39ad546535f4911d74bfd0..f29a91f4c48cfc6fbc9adb59109e3ff5a142894c 100644 (file)
@@ -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;
+}
index ee4278800d7b571062c93e2fe2abc2a15de792c5..327f6465f8f0927a569a48cf497245110ee48b00 100644 (file)
@@ -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,
index 6b5f759bae93696a179085abf95fef0306db8a9e..e5e42754df935be6065ac0065cb66a59c413a0ac 100644 (file)
@@ -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());