#
# Makefile for the Harvest Object Cache server
#
-# $Id: Makefile.in,v 1.13 1996/04/08 23:35:37 wessels Exp $
+# $Id: Makefile.in,v 1.14 1996/04/09 18:18:45 wessels Exp $
#
# Uncomment and customize the following to suit your needs:
#
fdstat.o filemap.o ftp.o gopher.o \
hash.o http.o icp.o ipcache.o \
main.o mime.o neighbors.o objcache.o \
- proto.o stack.o stat.o stmem.o \
+ proto.o send-announce.o stack.o stat.o stmem.o \
store.o storetoString.o tools.o ttl.o \
url.o wais.o $(XTRA_OBJS)
-/* $Id: cache_cf.cc,v 1.25 1996/04/08 23:25:20 wessels Exp $ */
+/* $Id: cache_cf.cc,v 1.26 1996/04/09 18:18:46 wessels Exp $ */
/* DEBUG: Section 3 cache_cf: Configuration file parsing */
char *pidFilename;
char *visibleHostname;
char *ftpUser;
+ struct {
+ char *host;
+ int port;
+ char *file;
+ int rate;
+ } Announce;
} Config;
#define DefaultMemMaxSize (16 << 20) /* 16 MB */
#define DefaultPidFilename (char *)NULL /* default NONE */
#define DefaultVisibleHostname (char *)NULL /* default NONE */
#define DefaultFtpUser "cached@" /* Default without domain */
+#define DefaultAnnounceHost "sd.cache.nlanr.net"
+#define DefaultAnnouncePort 3131
+#define DefaultAnnounceFile (char *)NULL /* default NONE */
+#define DefaultAnnounceRate 86400 /* every 24 hours */
extern char *config_file;
{
char *token;
token = strtok(NULL, w_space);
- safe_free(Config.ftpUser);
if (token == (char *) NULL)
self_destruct(line_in);
+ safe_free(Config.ftpUser);
Config.ftpUser = xstrdup(token);
}
{
char *token;
static char origPortList = 1;
-
if (origPortList) {
connect_port_list = NULL;
origPortList = 0;
}
}
+static void parseCacheAnnounceLine(line_in)
+ char *line_in;
+{
+ char *token;
+ int i;
+ GetInteger(i);
+ Config.Announce.rate = i * 3600; /* hours to seconds */
+}
+
+static void parseAnnounceToLine(line_in)
+ char *line_in;
+{
+ char *token;
+ int i;
+ token = strtok(NULL, w_space);
+ if (token == (char *) NULL)
+ self_destruct(line_in);
+ safe_free(Config.Announce.host);
+ Config.Announce.host = xstrdup(token);
+ if ((token = strchr(Config.Announce.host, ':'))) {
+ *token++ = '\0';
+ if (sscanf(token, "%d", &i) != 1)
+ Config.Announce.port = i;
+ }
+ token = strtok(NULL, w_space);
+ if (token == (char *) NULL)
+ return;
+ safe_free(Config.Announce.file);
+ Config.Announce.file = xstrdup(token);
+}
+
int parseConfigFile(file_name)
char *file_name;
else if (!strcmp(token, "connect_ports"))
parseConnectPortsLine(line_in);
+ else if (!strcmp(token, "cache_announce"))
+ parseCacheAnnounceLine(line_in);
+
+ else if (!strcmp(token, "announce_to"))
+ parseAnnounceToLine(line_in);
+
/* If unknown, treat as a comment line */
else {
/* EMPTY */ ;
{
return Config.ftpUser;
}
+char *getAnnounceHost()
+{
+ return Config.Announce.host;
+}
+int getAnnouncePort()
+{
+ return Config.Announce.port;
+}
+char *getAnnounceFile()
+{
+ return Config.Announce.file;
+}
+int getAnnounceRate()
+{
+ return Config.Announce.rate;
+}
int setAsciiPortNum(p)
int p;
Config.pidFilename = safe_xstrdup(DefaultPidFilename);
Config.visibleHostname = safe_xstrdup(DefaultVisibleHostname);
Config.ftpUser = safe_xstrdup(DefaultFtpUser);
+ Config.Announce.host = safe_xstrdup(DefaultAnnounceHost);
+ Config.Announce.port = DefaultAnnouncePort;
+ Config.Announce.file = safe_xstrdup(DefaultAnnounceFile);
+ Config.Announce.rate = DefaultAnnounceRate;
}
static void configDoConfigure()
-/* $Id: comm.cc,v 1.18 1996/04/08 17:10:43 wessels Exp $ */
+/* $Id: comm.cc,v 1.19 1996/04/09 18:18:48 wessels Exp $ */
/* DEBUG: Section 5 comm: socket level functions */
/* Select on all sockets; call handlers for those that are ready. */
-int comm_select(sec, usec, failtime)
- long sec, usec;
+int comm_select(sec, failtime)
+ time_t sec;
time_t failtime;
{
- int fd;
- int i;
+ fd_set exceptfds;
+ fd_set read_mask;
fd_set readfds;
+ fd_set write_mask;
fd_set writefds;
- fd_set exceptfds;
+ int (*tmp) () = NULL;
+ int fd;
+ int i;
+ int maxfd;
+ int nfds;
int num;
- time_t timeout;
+ int sel_fd_width;
static time_t last_timeout = 0;
struct timeval poll_time;
struct timeval zero_tv;
- int sel_fd_width;
- int nfds;
-
- fd_set read_mask, write_mask;
- int (*tmp) () = NULL;
- int maxfd;
+ time_t timeout;
/* assume all process are very fast (less than 1 second). Call
* time() only once */
while (1) {
poll_time.tv_sec = 1;
poll_time.tv_usec = 0;
- num = select(fdstat_biggest_fd() + 1,
- &readfds, &writefds, &exceptfds, &poll_time);
+ num = select(maxfd, &readfds, &writefds, &exceptfds, &poll_time);
if (num >= 0)
break;
-
/* break on interrupt so outer loop will reset FD_SET's */
if (errno == EINTR)
break;
checkTimeouts();
checkLifetimes();
}
+ if (num == 0)
+ continue;
+
/* scan each socket but the accept socket. Poll this
* more frequently to minimiize losses due to the 5 connect
* limit in SunOS */
- if (num) {
- maxfd = fdstat_biggest_fd() + 1;
- for (fd = 0; fd < maxfd && num > 0; fd++) {
-
- if (!(FD_ISSET(fd, &readfds) || FD_ISSET(fd, &writefds) ||
- FD_ISSET(fd, &exceptfds)))
- continue;
+ maxfd = fdstat_biggest_fd() + 1;
+ for (fd = 0; fd < maxfd && num > 0; fd++) {
+
+ if (!(FD_ISSET(fd, &readfds) || FD_ISSET(fd, &writefds) ||
+ FD_ISSET(fd, &exceptfds)))
+ continue;
+ else
+ --num;
+
+ /*
+ * Admit more connections quickly until we hit the hard limit.
+ * Don't forget to keep the UDP acks coming and going.
+ */
+
+ FD_ZERO(&read_mask);
+ FD_ZERO(&write_mask);
+
+ if (theAsciiConnection >= 0) {
+ if ((fdstat_are_n_free_fd(RESERVED_FD))
+ && (fd_table[theAsciiConnection].read_handler))
+ FD_SET(theAsciiConnection, &read_mask);
else
- --num;
-
- /*
- * Admit more connections quickly until we hit the hard limit.
- * Don't forget to keep the UDP acks coming and going.
- */
- {
-
- FD_ZERO(&read_mask);
- FD_ZERO(&write_mask);
-
- if (theAsciiConnection >= 0) {
- if ((fdstat_are_n_free_fd(RESERVED_FD))
- && (fd_table[theAsciiConnection].read_handler))
- FD_SET(theAsciiConnection, &read_mask);
- else
- FD_CLR(theAsciiConnection, &read_mask);
- }
- if (theUdpConnection >= 0) {
- if (fd_table[theUdpConnection].read_handler)
- FD_SET(theUdpConnection, &read_mask);
- if (fd_table[theUdpConnection].write_handler)
- FD_SET(theUdpConnection, &write_mask);
+ FD_CLR(theAsciiConnection, &read_mask);
+ }
+ if (theUdpConnection >= 0) {
+ if (fd_table[theUdpConnection].read_handler)
+ FD_SET(theUdpConnection, &read_mask);
+ if (fd_table[theUdpConnection].write_handler)
+ FD_SET(theUdpConnection, &write_mask);
+ }
+ sel_fd_width = max(theAsciiConnection, theUdpConnection) + 1;
+ if (select(sel_fd_width, &read_mask, &write_mask, NULL, &zero_tv) > 0) {
+ if (FD_ISSET(theAsciiConnection, &read_mask)) {
+ tmp = fd_table[theAsciiConnection].read_handler;
+ fd_table[theAsciiConnection].read_handler = 0;
+ tmp(theAsciiConnection, fd_table[theAsciiConnection].read_data);
+ }
+ if ((theUdpConnection >= 0)) {
+ if (FD_ISSET(theUdpConnection, &read_mask)) {
+ tmp = fd_table[theUdpConnection].read_handler;
+ fd_table[theUdpConnection].read_handler = 0;
+ tmp(theUdpConnection, fd_table[theUdpConnection].read_data);
}
- sel_fd_width = max(theAsciiConnection, theUdpConnection) + 1;
- if (select(sel_fd_width, &read_mask, &write_mask, NULL, &zero_tv) > 0) {
- if (FD_ISSET(theAsciiConnection, &read_mask)) {
- tmp = fd_table[theAsciiConnection].read_handler;
- fd_table[theAsciiConnection].read_handler = 0;
- tmp(theAsciiConnection, fd_table[theAsciiConnection].read_data);
- }
- if ((theUdpConnection >= 0)) {
- if (FD_ISSET(theUdpConnection, &read_mask)) {
- tmp = fd_table[theUdpConnection].read_handler;
- fd_table[theUdpConnection].read_handler = 0;
- tmp(theUdpConnection, fd_table[theUdpConnection].read_data);
- }
- if (FD_ISSET(theUdpConnection, &write_mask)) {
- tmp = fd_table[theUdpConnection].write_handler;
- fd_table[theUdpConnection].write_handler = 0;
- tmp(theUdpConnection, fd_table[theUdpConnection].write_data);
- }
- }
+ if (FD_ISSET(theUdpConnection, &write_mask)) {
+ tmp = fd_table[theUdpConnection].write_handler;
+ fd_table[theUdpConnection].write_handler = 0;
+ tmp(theUdpConnection, fd_table[theUdpConnection].write_data);
}
}
-
- if ((fd == theUdpConnection) || (fd == theAsciiConnection))
- continue;
-
- if (FD_ISSET(fd, &readfds)) {
- debug(5, 6, "comm_select: FD %d ready for reading\n", fd);
- if (fd_table[fd].read_handler) {
- tmp = fd_table[fd].read_handler;
- fd_table[fd].read_handler = 0;
- debug(5, 10, "calling read handler %p(%d,%p)\n",
- tmp, fd, fd_table[fd].read_data);
- tmp(fd, fd_table[fd].read_data);
- }
+ }
+ if ((fd == theUdpConnection) || (fd == theAsciiConnection))
+ continue;
+
+ if (FD_ISSET(fd, &readfds)) {
+ debug(5, 6, "comm_select: FD %d ready for reading\n", fd);
+ if (fd_table[fd].read_handler) {
+ tmp = fd_table[fd].read_handler;
+ fd_table[fd].read_handler = 0;
+ debug(5, 10, "calling read handler %p(%d,%p)\n",
+ tmp, fd, fd_table[fd].read_data);
+ tmp(fd, fd_table[fd].read_data);
}
- if (FD_ISSET(fd, &writefds)) {
- debug(5, 5, "comm_select: FD %d ready for writing\n", fd);
- if (fd_table[fd].write_handler) {
- tmp = fd_table[fd].write_handler;
- fd_table[fd].write_handler = 0;
- debug(5, 10, "calling write handler %p(%d,%p)\n",
- tmp, fd, fd_table[fd].write_data);
- tmp(fd, fd_table[fd].write_data);
- }
+ }
+ if (FD_ISSET(fd, &writefds)) {
+ debug(5, 5, "comm_select: FD %d ready for writing\n", fd);
+ if (fd_table[fd].write_handler) {
+ tmp = fd_table[fd].write_handler;
+ fd_table[fd].write_handler = 0;
+ debug(5, 10, "calling write handler %p(%d,%p)\n",
+ tmp, fd, fd_table[fd].write_data);
+ tmp(fd, fd_table[fd].write_data);
}
- if (FD_ISSET(fd, &exceptfds)) {
- debug(5, 5, "comm_select: FD %d has an exception\n", fd);
- if (fd_table[fd].except_handler) {
- tmp = fd_table[fd].except_handler;
- fd_table[fd].except_handler = 0;
- debug(5, 10, "calling except handler %p(%d,%p)\n",
- tmp, fd, fd_table[fd].except_data);
- tmp(fd, fd_table[fd].except_data);
- }
+ }
+ if (FD_ISSET(fd, &exceptfds)) {
+ debug(5, 5, "comm_select: FD %d has an exception\n", fd);
+ if (fd_table[fd].except_handler) {
+ tmp = fd_table[fd].except_handler;
+ fd_table[fd].except_handler = 0;
+ debug(5, 10, "calling except handler %p(%d,%p)\n",
+ tmp, fd, fd_table[fd].except_data);
+ tmp(fd, fd_table[fd].except_data);
}
}
- return COMM_OK;
}
+ return COMM_OK;
}
debug(5, 8, "comm_select: time out: %d.\n", cached_curtime);
-/* $Id: main.cc,v 1.23 1996/04/08 23:25:21 wessels Exp $ */
+/* $Id: main.cc,v 1.24 1996/04/09 18:18:50 wessels Exp $ */
/* DEBUG: Section 1 main: startup and main loop */
int errcount = 0;
int n; /* # of GC'd objects */
time_t last_maintain = 0;
+ time_t last_announce = 0;
errorInitialize();
storeMaintainSwapSpace();
last_maintain = cached_curtime;
}
- switch (comm_select((long) 60, (long) 0, next_cleaning)) {
+ switch (comm_select((time_t) 60, next_cleaning)) {
case COMM_OK:
/* do nothing */
break;
debug(1, 1, "Garbage collection done, %d objects removed\n", n);
next_cleaning = cached_curtime + getCleanRate();
}
+ if ((n = getAnnounceRate()) > 0) {
+ if (cached_curtime > last_announce + n)
+ send_announce();
+ last_announce = cached_curtime;
+ }
/* house keeping */
break;
case COMM_SHUTDOWN:
-/* $Id: send-announce.cc,v 1.4 1996/03/27 01:46:18 wessels Exp $ */
+/* $Id: send-announce.cc,v 1.5 1996/04/09 18:18:50 wessels Exp $ */
-#include "config.h"
+/*
+ * DEBUG: Section 27 send-announce
+ */
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
+#include "squid.h"
-#include "util.h"
-
-char *databuf = NULL;
-int quiet = 0;
-int debug = 0;
-char *announce_to_host = "sd.cache.nlanr.net";
-int announce_to_port = 3131;
-
-int http_port = CACHE_HTTP_PORT;
-int icp_port = CACHE_ICP_PORT;
-
-
-int read_config(fname)
- char *fname;
-{
- FILE *fp = NULL;
- char buf[BUFSIZ];
- char munge[BUFSIZ];
- char *t = NULL;
- char *tag = NULL;
- char *w_space = " \t\n";
-
- if ((fp = fopen(fname, "r")) == (FILE *) NULL)
- return 0;
-
- while (fgets(buf, BUFSIZ, fp)) {
- if ((t = strchr(buf, '#')))
- *t = '\0';
- if (buf[0] == '\0')
- continue;
- strcpy(munge, buf);
- if ((tag = strtok(munge, w_space)) == NULL)
- continue;
- if (!strcasecmp(tag, "cache_announce")) {
- if ((t = strtok(NULL, w_space)) == NULL)
- exit(0);
- if (strcasecmp(t, "on"))
- exit(0);
- } else if (!strcasecmp(tag, "announce_to")) {
- if ((t = strtok(NULL, w_space)) == NULL)
- continue;
- announce_to_host = xstrdup(t);
- if ((t = strchr(announce_to_host, ':'))) {
- announce_to_port = atoi(t + 1);
- *t = '\0';
- }
- } else if (!strncasecmp(tag, "announce_", 9)) {
- strcat(databuf, buf);
- } else if (!strcasecmp(tag, "ascii_port")) {
- if ((t = strtok(NULL, w_space)))
- http_port = atoi(t);
- } else if (!strcasecmp(tag, "udp_port")) {
- if ((t = strtok(NULL, w_space)))
- icp_port = atoi(t);
- }
- }
- fclose(fp);
- return 1;
-}
-
-
-int send_packet(host, port)
- char *host;
- int port;
+void send_announce()
{
- char buf[256];
- time_t t;
- int s;
- struct sockaddr_in R;
- struct sockaddr_in L;
+ static char tbuf[256];
+ static char sndbuf[BUFSIZ];
+ icpUdpData *qdata = NULL;
struct hostent *hp = NULL;
-
- sprintf(buf, "cache_version HARVEST/%s\n", SQUID_VERSION);
- strcat(databuf, buf);
- sprintf(buf, "Running on %s %d %d\n",
- getfullhostname(),
- http_port,
- icp_port);
- strcat(databuf, buf);
- t = time(NULL);
- sprintf(buf, "generated %d [%s]\n",
- (int) t, mkhttpdlogtime(&t));
- strcat(databuf, buf);
-
- if ((hp = gethostbyname(host)) == NULL) {
- if (!quiet)
- fprintf(stderr, "%s: Unknown host\n", host);
- return 0;
+ char *host = NULL;
+ char *file = NULL;
+ int port;
+ int fd;
+ int l;
+ int n;
+
+ sndbuf[0] = '\0';
+
+ sprintf(tbuf, "cache_version HARVEST/%s\n", SQUID_VERSION);
+ strcat(sndbuf, tbuf);
+ sprintf(tbuf, "Running on %s %d %d\n",
+ getMyHostname(),
+ getAsciiPortNum(),
+ getUdpPortNum());
+ strcat(sndbuf, tbuf);
+ sprintf(tbuf, "generated %d [%s]\n",
+ (int) cached_curtime,
+ mkhttpdlogtime(&cached_curtime));
+ strcat(sndbuf, tbuf);
+ l = strlen(buf);
+
+ host = getAnnounceHost();
+ port = getAnnouncePort();
+
+ if ((hp = ipcache_gethostbyname(host))== NULL) {
+ debug(27,1,"send_announce: Unknown host '%s'\n", host);
+ return;
}
- memset(&L, '\0', sizeof(L));
- L.sin_family = AF_INET;
- L.sin_port = 0;
- L.sin_addr.s_addr = INADDR_ANY;
-
- if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
- if (!quiet)
- perror("socket");
- return 0;
- }
- if (bind(s, (struct sockaddr *) &L, sizeof(L)) < 0) {
- if (!quiet)
- perror("bind");
- return 0;
- }
- memset(&R, '\0', sizeof(R));
- R.sin_family = AF_INET;
- R.sin_port = htons(port);
- memcpy(&R.sin_addr, hp->h_addr_list[0], 4);
-
- if (debug) {
- close(s);
- printf("This would be sent to %s [%s] port %d\n",
- host, inet_ntoa(R.sin_addr), port);
- puts(databuf);
- return 0;
- }
- if (sendto(s, databuf, strlen(databuf), 0, (struct sockaddr *) &R, sizeof(R)) < 0) {
- if (!quiet)
- perror(host);
- return 0;
- }
- close(s);
- return 1;
-}
-
-
-main(argc, argv)
- int argc;
- char *argv[];
-
-{
- char config[256];
- char *s = NULL;
- int c;
- extern int optind;
- while ((c = getopt(argc, argv, "dqh")) != -1) {
- switch (c) {
- case 'd':
- debug = 1;
- break;
- case 'q':
- quiet = 1;
- break;
- case 'h':
- fprintf(stderr, "usage: %s -d -q -h [cached.conf]\n",
- argv[0]);
- exit(0);
- break;
+ if ((file = getAnnounceFile())) {
+ /* XXX could block */
+ fd = file_open(file, NULL, O_RDONLY);
+ if (fd > -1 && (n = read(fd, sndbuf+l, BUFSIZ-l-1)) > 0);
+ l += n;
+ sndbuf[l] = '\0';
+ } else {
+ debug(27,1,"send_announce: %s: %s\n", file, xstrerror());
}
}
- argv += (optind - 1);
- argc -= (optind - 1);
- if (argc > 1) {
- strcpy(config, argv[1]);
- } else if ((s = getenv("HARVEST_HOME"))) {
- sprintf(config, "%s/lib/cached.conf", s);
- } else {
- strcpy(config, "/usr/local/harvest/lib/cached.conf");
- }
-
- databuf = (char *) xcalloc(8192, 1);
- if (!read_config(config)) {
- if (!quiet)
- perror(config);
- exit(1);
- }
- send_packet(announce_to_host, announce_to_port);
- return 0;
+ qdata = (icpUdpData *) xcalloc(1, sizeof(icpUdpData));
+ qdata->msg = xstrdup(sndbuf);
+ qdata->len = strlen(sndbuf)+1;
+ qdata->address.sin_family = AF_INET;
+ qdata->address.sin_port = htons(port);
+ memcpy(&qdata->address.sin_addr, hp->h_addr_list[0], hp->h_length);
+ AppendUdp(qdata);
+ comm_set_select_handler(theUdpConnection,
+ COMM_SELECT_WRITE,
+ (PF) icpUdpReply,
+ (void *) qdata);
}
-/* $Id: squid.h,v 1.11 1996/04/08 19:32:41 wessels Exp $ */
+/* $Id: squid.h,v 1.12 1996/04/09 18:18:52 wessels Exp $ */
#include "config.h"
#include "autoconf.h"
#include "wais.h"
#include "connect.h"
#include "objcache.h"
+#include "send-announce.h"
#include "util.h"
extern time_t cached_starttime; /* main.c */