/*
- * $Id: icmp.cc,v 1.20 1996/10/11 23:11:56 wessels Exp $
+ * $Id: icmp.cc,v 1.21 1996/10/15 04:57:52 wessels Exp $
*
* DEBUG: section 37 ICMP Routines
* AUTHOR: Duane Wessels
*
*/
-#if USE_ICMP
#include "squid.h"
#include "pinger.h"
+int icmp_sock = -1;
+
+#if USE_ICMP
+
#define S_ICMP_ECHO 1
#define S_ICMP_ICP 2
#define S_ICMP_DOM 3
static icmpQueueData *IcmpQueueHead = NULL;
-int icmp_sock = -1;
-
static void icmpRecv _PARAMS((int, void *));
static void icmpQueueSend _PARAMS((pingerEchoData * pkt,
int len,
static void icmpSend _PARAMS((int fd, icmpQueueData * queue));
static void icmpHandleSourcePing _PARAMS((struct sockaddr_in * from, char *buf));
-void
-icmpOpen(void)
-{
- struct sockaddr_in S;
- int namelen = sizeof(struct sockaddr_in);
- pid_t pid;
- int child_sock;
- icmp_sock = comm_open(SOCK_DGRAM,
- 0,
- local_addr,
- 0,
- COMM_NONBLOCKING,
- "ICMP Socket");
- if (icmp_sock < 0) {
- debug(37, 0, "icmpOpen: icmp_sock: %s\n", xstrerror());
- return;
- }
- 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, (struct sockaddr *) &S, &namelen);
- if (comm_connect_addr(child_sock, &S) != COMM_OK)
- fatal_dump(xstrerror());
- getsockname(child_sock, (struct sockaddr *) &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 */
- char *x = xcalloc(strlen(Config.debugOptions) + 32, 1);
- sprintf(x, "SQUID_DEBUG=%s\n", Config.debugOptions);
- putenv(x);
- 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(Config.Program.pinger, "(pinger)", NULL);
- debug(29, 0, "icmpOpen: %s: %s\n", Config.Program.pinger, xstrerror());
- _exit(1);
- }
- comm_close(child_sock);
- commSetSelect(icmp_sock,
- COMM_SELECT_READ,
- (PF) icmpRecv,
- (void *) -1, 0);
- comm_set_fd_lifetime(icmp_sock, -1);
- debug(29, 0, "Pinger socket opened on FD %d\n", icmp_sock);
-}
-
-void
-icmpClose(void)
-{
- icmpQueueData *queue;
- debug(29, 0, "Closing ICMP socket on FD %d\n", icmp_sock);
- comm_close(icmp_sock);
- commSetSelect(icmp_sock,
- COMM_SELECT_READ,
- NULL,
- NULL, 0);
- icmp_sock = -1;
- while ((queue = IcmpQueueHead)) {
- IcmpQueueHead = queue->next;
- if (queue->free_func)
- queue->free_func(queue->msg);
- safe_free(queue);
- }
-}
-
static void
icmpSendEcho(struct in_addr to, int opcode, char *payload, int len)
{
int n;
pingerReplyData preply;
static struct sockaddr_in F;
-
commSetSelect(icmp_sock,
COMM_SELECT_READ,
(PF) icmpRecv,
}
}
-
static void
icmpQueueSend(pingerEchoData * pkt,
int len,
}
}
+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);
+}
+#endif /* USE_ICMP */
+
void
icmpPing(struct in_addr to)
{
+#if USE_ICMP
icmpSendEcho(to, S_ICMP_ECHO, NULL, 0);
+#endif
}
void
icmpSourcePing(struct in_addr to, icp_common_t * header, char *url)
{
+#if USE_ICMP
char *payload;
int len;
int ulen;
len += ulen + 1;
icmpSendEcho(to, S_ICMP_ICP, payload, len);
put_free_8k_page(payload);
+#endif
}
void
icmpDomainPing(struct in_addr to, char *domain)
{
+#if USE_ICMP
debug(37, 3, "icmpDomainPing: '%s'\n", domain);
icmpSendEcho(to, S_ICMP_DOM, domain, 0);
+#endif
}
-static void
-icmpHandleSourcePing(struct sockaddr_in *from, char *buf)
+void
+icmpOpen(void)
{
- 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);
+#if USE_ICMP
+ struct sockaddr_in S;
+ int namelen = sizeof(struct sockaddr_in);
+ pid_t pid;
+ int child_sock;
+ icmp_sock = comm_open(SOCK_DGRAM,
+ 0,
+ local_addr,
+ 0,
+ COMM_NONBLOCKING,
+ "ICMP Socket");
+ if (icmp_sock < 0) {
+ debug(37, 0, "icmpOpen: icmp_sock: %s\n", xstrerror());
+ return;
}
- debug(37, 3, "icmpHandleSourcePing: from %s, key=%s\n",
- inet_ntoa(from->sin_addr),
- key);
- if ((entry = storeGet(key)) == NULL)
+ 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;
- if (entry->lock_count == 0)
+ }
+ getsockname(icmp_sock, (struct sockaddr *) &S, &namelen);
+ if (comm_connect_addr(child_sock, &S) != COMM_OK)
+ fatal_dump(xstrerror());
+ getsockname(child_sock, (struct sockaddr *) &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;
- /* call neighborsUdpAck even if ping_status != PING_WAITING */
- neighborsUdpAck(icmp_sock,
- url,
- &header,
- from,
- entry,
- NULL,
- 0);
+ }
+ if (pid == 0) { /* child */
+ char *x = xcalloc(strlen(Config.debugOptions) + 32, 1);
+ sprintf(x, "SQUID_DEBUG=%s\n", Config.debugOptions);
+ putenv(x);
+ 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(Config.Program.pinger, "(pinger)", NULL);
+ debug(29, 0, "icmpOpen: %s: %s\n", Config.Program.pinger, xstrerror());
+ _exit(1);
+ }
+ comm_close(child_sock);
+ commSetSelect(icmp_sock,
+ COMM_SELECT_READ,
+ (PF) icmpRecv,
+ (void *) -1, 0);
+ comm_set_fd_lifetime(icmp_sock, -1);
+ debug(29, 0, "Pinger socket opened on FD %d\n", icmp_sock);
+#endif
}
-#endif /* USE_ICMP */
+void
+icmpClose(void)
+{
+#if USE_ICMP
+ icmpQueueData *queue;
+ debug(29, 0, "Closing ICMP socket on FD %d\n", icmp_sock);
+ comm_close(icmp_sock);
+ commSetSelect(icmp_sock,
+ COMM_SELECT_READ,
+ NULL,
+ NULL, 0);
+ icmp_sock = -1;
+ while ((queue = IcmpQueueHead)) {
+ IcmpQueueHead = queue->next;
+ if (queue->free_func)
+ queue->free_func(queue->msg);
+ safe_free(queue);
+ }
+#endif
+}
-#if USE_ICMP
-
#include "squid.h"
+#if USE_ICMP
+
#define NET_DB_TTL 300
#define NETDB_LOW_MARK 900
static void netdbHashUnlink _PARAMS((char *key));
static void netdbPurgeLRU _PARAMS((void));
-void
-netdbInit(void)
-{
- 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
netdbHashInsert(netdbEntry * n, struct in_addr addr)
{
return (0);
}
-
static void
netdbPurgeLRU(void)
{
xfree(hostname);
}
-void
-netdbPingSite(char *hostname)
-{
- netdbEntry *n;
- if ((n = netdbLookupHost(hostname)) != NULL)
- if (n->next_ping_time > squid_curtime)
- return;
- ipcache_nbgethostbyname(hostname,
- -1,
- netdbSendPing,
- (void *) xstrdup(hostname));
-}
-
-void
-netdbHandlePingReply(struct sockaddr_in *from, int hops, int rtt)
-{
- netdbEntry *n;
- int N;
- debug(37, 3, "netdbHandlePingReply: from %s\n", inet_ntoa(from->sin_addr));
- if ((n = netdbLookupAddr(from->sin_addr)) == NULL)
- return;
- N = ++n->n;
- if (N > 100)
- N = 100;
- n->hops = ((n->hops * (N - 1)) + hops) / N;
- n->rtt = ((n->rtt * (N - 1)) + rtt) / N;
- n->pings_recv++;
- debug(37, 3, "netdbHandlePingReply: %s; rtt=%5.1f hops=%4.1f\n",
- n->network,
- n->rtt,
- n->hops);
-}
-
static struct in_addr
networkFromInaddr(struct in_addr a)
{
return 0;
}
+#endif /* USE_ICMP */
+
+/* PUBLIC FUNCTIONS */
+
void
-netdbDump(StoreEntry * sentry)
+netdbInit(void)
+{
+#if USE_ICMP
+ addr_table = hash_create((int (*)_PARAMS((char *, char *))) strcmp, 229, hash_string);
+ host_table = hash_create((int (*)_PARAMS((char *, char *))) strcmp, 467, hash_string);
+#endif
+}
+
+void
+netdbPingSite(char *hostname)
{
+#if USE_ICMP
netdbEntry *n;
- netdbEntry **list;
- struct _net_db_name *x;
- int k;
- int i;
- storeAppendPrintf(sentry, "{Network DB Statistics:\n");
- storeAppendPrintf(sentry, "{%-16.16s %9s %7s %5s %s}\n",
- "Network",
- "recv/sent",
- "RTT",
- "Hops",
- "Hostnames");
- list = xcalloc(meta_data.netdb_addrs, sizeof(netdbEntry *));
- i = 0;
- for (n = netdbGetFirst(addr_table); n; n = netdbGetNext(addr_table))
- *(list + i++) = n;
- qsort((char *) list,
- i,
- sizeof(netdbEntry *),
- (QS) sortByHops);
- for (k = 0; k < i; k++) {
- n = *(list + k);
- storeAppendPrintf(sentry, "{%-16.16s %4d/%4d %7.1f %5.1f",
- n->network,
- n->pings_recv,
- n->pings_sent,
- n->rtt,
- n->hops);
- for (x = n->hosts; x; x = x->next)
- storeAppendPrintf(sentry, " %s", x->name);
- storeAppendPrintf(sentry, close_bracket);
- }
- storeAppendPrintf(sentry, close_bracket);
- xfree(list);
+ if ((n = netdbLookupHost(hostname)) != NULL)
+ if (n->next_ping_time > squid_curtime)
+ return;
+ ipcache_nbgethostbyname(hostname,
+ -1,
+ netdbSendPing,
+ (void *) xstrdup(hostname));
+#endif
}
-int
-netdbHops(struct in_addr addr)
+void
+netdbHandlePingReply(struct sockaddr_in *from, int hops, int rtt)
{
- netdbEntry *n = netdbLookupAddr(addr);
- if (n && n->pings_recv) {
- n->last_use_time = squid_curtime;
- return (int) (n->hops + 0.5);
- }
- return 256;
+#if USE_ICMP
+ netdbEntry *n;
+ int N;
+ debug(37, 3, "netdbHandlePingReply: from %s\n", inet_ntoa(from->sin_addr));
+ if ((n = netdbLookupAddr(from->sin_addr)) == NULL)
+ return;
+ N = ++n->n;
+ if (N > 100)
+ N = 100;
+ n->hops = ((n->hops * (N - 1)) + hops) / N;
+ n->rtt = ((n->rtt * (N - 1)) + rtt) / N;
+ n->pings_recv++;
+ debug(37, 3, "netdbHandlePingReply: %s; rtt=%5.1f hops=%4.1f\n",
+ n->network,
+ n->rtt,
+ n->hops);
+#endif
}
void
netdbFreeMemory(void)
{
+#if USE_ICMP
netdbEntry *n;
netdbEntry **L1;
hash_link *h;
struct _net_db_name *x;
int i = 0;
int j;
-
L1 = xcalloc(meta_data.netdb_addrs, sizeof(netdbEntry *));
n = (netdbEntry *) hash_first(addr_table);
while (n && i < meta_data.netdb_addrs) {
xfree(n);
}
xfree(L1);
-
i = 0;
L2 = xcalloc(meta_data.netdb_hosts, sizeof(hash_link *));
h = hash_first(host_table);
xfree(h);
}
xfree(L2);
-
hashFreeMemory(addr_table);
hashFreeMemory(host_table);
+#endif
}
-#endif /* USE_ICMP */
+int
+netdbHops(struct in_addr addr)
+{
+#if USE_ICMP
+ netdbEntry *n = netdbLookupAddr(addr);
+ if (n && n->pings_recv) {
+ n->last_use_time = squid_curtime;
+ return (int) (n->hops + 0.5);
+ }
+#endif
+ return 256;
+}
+
+void
+netdbDump(StoreEntry * sentry)
+{
+#if USE_ICMP
+ netdbEntry *n;
+ netdbEntry **list;
+ struct _net_db_name *x;
+ int k;
+ int i;
+ storeAppendPrintf(sentry, "{Network DB Statistics:\n"); */ } */
+ storeAppendPrintf(sentry, "{%-16.16s %9s %7s %5s %s}\n",
+ "Network",
+ "recv/sent",
+ "RTT",
+ "Hops",
+ "Hostnames");
+ list = xcalloc(meta_data.netdb_addrs, sizeof(netdbEntry *));
+ i = 0;
+ for (n = netdbGetFirst(addr_table); n; n = netdbGetNext(addr_table))
+ *(list + i++) = n;
+ qsort((char *) list,
+ i,
+ sizeof(netdbEntry *),
+ (QS) sortByHops);
+ for (k = 0; k < i; k++) {
+ n = *(list + k);
+ storeAppendPrintf(sentry, "{%-16.16s %4d/%4d %7.1f %5.1f", /* } */
+ n->network,
+ n->pings_recv,
+ n->pings_sent,
+ n->rtt,
+ n->hops);
+ for (x = n->hosts; x; x = x->next)
+ storeAppendPrintf(sentry, " %s", x->name);
+ storeAppendPrintf(sentry, close_bracket);
+ }
+ storeAppendPrintf(sentry, close_bracket);
+ xfree(list);
+#endif
+}