static void child_main_loop(void) { char buf[URL_BUF_SZ]; char *t; int n; struct timeval t1; struct timeval t2; if (debug) fprintf(stderr, "Child PID %d entering child_main_loop\n", (int) getpid()); setbuf(stdin, NULL); setbuf(stdout, NULL); setbuf(stderr, NULL); while (fgets(buf, URL_BUF_SZ, stdin)) { t = strchr(buf, '\n'); if (t == NULL) continue; *t = '\0'; if (strncmp(buf, "http://", 7)) continue; gettimeofday(&t1, NULL); n = get_url(buf); gettimeofday(&t2, NULL); printf("%d %d\n", n, tvSubMsec(t1, t2)); } }
static void peerCountHandleIcpReply(peer * p, peer_t type, protocol_t proto, void *hdrnotused, void *data) { ps_state *psstate = data; StoreEntry *fake = psstate->entry; MemObject *mem = fake->mem_obj; int rtt = tvSubMsec(mem->start_ping, current_time); assert(proto == PROTO_ICP); assert(fake); assert(mem); psstate->ping.n_recv++; p->stats.rtt = intAverage(p->stats.rtt, rtt, psstate->ping.n_recv, RTT_AV_FACTOR); }
static void helperStatefulHandleRead(int fd, void *data) { int len; char *t = NULL; helper_stateful_server *srv = data; helper_stateful_request *r; statefulhelper *hlp = srv->parent; assert(fd == srv->rfd); assert(cbdataValid(data)); statCounter.syscalls.sock.reads++; len = FD_READ_METHOD(fd, srv->buf + srv->offset, srv->buf_sz - srv->offset); fd_bytes(fd, len, FD_READ); debug(84, 5) ("helperStatefulHandleRead: %d bytes from %s #%d.\n", len, hlp->id_name, srv->index + 1); if (len <= 0) { if (len < 0) debug(84, 1) ("helperStatefulHandleRead: FD %d read: %s\n", fd, xstrerror()); comm_close(fd); return; } srv->offset += len; srv->buf[srv->offset] = '\0'; r = srv->request; if (r == NULL) { /* someone spoke without being spoken to */ debug(84, 1) ("helperStatefulHandleRead: unexpected read from %s #%d, %d bytes\n", hlp->id_name, srv->index + 1, len); srv->offset = 0; } else if ((t = strchr(srv->buf, '\n'))) { /* end of reply found */ debug(84, 3) ("helperStatefulHandleRead: end of reply found\n"); *t = '\0'; srv->flags.busy = 0; srv->offset = 0; srv->request = NULL; hlp->stats.replies++; hlp->stats.avg_svc_time = intAverage(hlp->stats.avg_svc_time, tvSubMsec(srv->dispatch_time, current_time), hlp->stats.replies, REDIRECT_AV_FACTOR); if (cbdataValid(r->data)) { r->callback(r->data, srv, srv->buf); } else { debug(84, 1) ("StatefulHandleRead: no callback data registered\n"); } helperStatefulRequestFree(r); } else { commSetSelect(srv->rfd, COMM_SELECT_READ, helperStatefulHandleRead, srv, 0); } }
void helperStatefulStats(StoreEntry * sentry, statefulhelper * hlp) { helper_stateful_server *srv; dlink_node *link; double tt; storeAppendPrintf(sentry, "number running: %d of %d\n", hlp->n_running, hlp->n_to_start); storeAppendPrintf(sentry, "requests sent: %d\n", hlp->stats.requests); storeAppendPrintf(sentry, "replies received: %d\n", hlp->stats.replies); storeAppendPrintf(sentry, "queue length: %d\n", hlp->stats.queue_size); storeAppendPrintf(sentry, "avg service time: %d msec\n", hlp->stats.avg_svc_time); storeAppendPrintf(sentry, "\n"); storeAppendPrintf(sentry, "%7s\t%7s\t%7s\t%11s\t%s\t%7s\t%7s\t%7s\n", "#", "FD", "PID", "# Requests", "Flags", "Time", "Offset", "Request"); for (link = hlp->servers.head; link; link = link->next) { srv = link->data; tt = 0.001 * tvSubMsec(srv->dispatch_time, current_time); storeAppendPrintf(sentry, "%7d\t%7d\t%7d\t%11d\t%c%c%c%c%c\t%7.3f\t%7d\t%s\n", srv->index + 1, srv->rfd, srv->pid, srv->stats.uses, srv->flags.alive ? 'A' : ' ', srv->flags.busy ? 'B' : ' ', srv->flags.closing ? 'C' : ' ', srv->flags.reserved ? 'R' : ' ', srv->flags.shutdown ? 'S' : ' ', tt < 0.0 ? 0.0 : tt, (int) srv->offset, srv->request ? log_quote(srv->request->buf) : "(none)"); } storeAppendPrintf(sentry, "\nFlags key:\n\n"); storeAppendPrintf(sentry, " A = ALIVE\n"); storeAppendPrintf(sentry, " B = BUSY\n"); storeAppendPrintf(sentry, " C = CLOSING\n"); storeAppendPrintf(sentry, " R = RESERVED or DEFERRED\n"); storeAppendPrintf(sentry, " S = SHUTDOWN\n"); storeAppendPrintf(sentry, " P = PLACEHOLDER\n"); }
static void neighborUpdateRtt(peer * p, MemObject * mem) { int rtt; if (!mem) return; if (!mem->start_ping.tv_sec) return; rtt = tvSubMsec(mem->start_ping, current_time); if (rtt < 1 || rtt > 10000) return; p->stats.rtt = intAverage(p->stats.rtt, rtt, p->stats.pings_acked, RTT_AV_FACTOR); }
static void netdbSaveState(void *foo) { Logfile *lf; netdbEntry *n; net_db_name *x; struct timeval start = current_time; int count = 0; if (strcmp(Config.netdbFilename, "none") == 0) return; /* * This was nicer when we were using stdio, but thanks to * Solaris bugs, its a bad idea. fopen can fail if more than * 256 FDs are open. */ /* * unlink() is here because there is currently no way to make * logfileOpen() use O_TRUNC. */ unlink(Config.netdbFilename); lf = logfileOpen(Config.netdbFilename, 4096, 0); if (NULL == lf) { debug(50, 1) ("netdbSaveState: %s: %s\n", Config.netdbFilename, xstrerror()); return; } hash_first(addr_table); while ((n = (netdbEntry *) hash_next(addr_table))) { if (n->pings_recv == 0) continue; logfilePrintf(lf, "%s %d %d %10.5f %10.5f %d %d", n->network, n->pings_sent, n->pings_recv, n->hops, n->rtt, (int) n->next_ping_time, (int) n->last_use_time); for (x = n->hosts; x; x = x->next) logfilePrintf(lf, " %s", hashKeyStr(&x->hash)); logfilePrintf(lf, "\n"); count++; #undef RBUF_SZ } logfileClose(lf); getCurrentTime(); debug(38, 1) ("NETDB state saved; %d entries, %d msec\n", count, tvSubMsec(start, current_time)); eventAddIsh("netdbSaveState", netdbSaveState, NULL, 3600.0, 1); }
int main(int argc, char *argv[]) { int conn, c, len, bytesWritten; int port, to_stdout, reload; int ping, pcount; int keep_alive = 0; int opt_noaccept = 0; int opt_verbose = 0; const char *hostname, *localhost; char url[BUFSIZ], msg[BUFSIZ], buf[BUFSIZ]; char extra_hdrs[BUFSIZ]; const char *method = "GET"; extern char *optarg; time_t ims = 0; int max_forwards = -1; struct timeval tv1, tv2; int i = 0, loops; long ping_int; long ping_min = 0, ping_max = 0, ping_sum = 0, ping_mean = 0; char *proxy_user = NULL; char *proxy_password = NULL; char *www_user = NULL; char *www_password = NULL; /* set the defaults */ hostname = "localhost"; localhost = NULL; extra_hdrs[0] = '\0'; port = CACHE_HTTP_PORT; to_stdout = 1; reload = 0; ping = 0; pcount = 0; ping_int = 1 * 1000; if (argc < 2) { usage(argv[0]); /* need URL */ } else if (argc >= 2) { strncpy(url, argv[argc - 1], BUFSIZ); url[BUFSIZ - 1] = '\0'; if (url[0] == '-') usage(argv[0]); while ((c = getopt(argc, argv, "ah:l:P:i:km:p:rsvt:g:p:I:H:T:u:U:w:W:?")) != -1) switch (c) { case 'a': opt_noaccept = 1; break; case 'h': /* remote host */ if (optarg != NULL) hostname = optarg; break; case 'l': /* local host */ if (optarg != NULL) localhost = optarg; break; case 's': /* silent */ to_stdout = 0; break; case 'k': /* backward compat */ keep_alive = 1; break; case 'r': /* reload */ reload = 1; break; case 'p': /* port number */ sscanf(optarg, "%d", &port); if (port < 1) port = CACHE_HTTP_PORT; /* default */ break; case 'P': put_file = xstrdup(optarg); break; case 'i': /* IMS */ ims = (time_t) atoi(optarg); break; case 'm': method = xstrdup(optarg); break; case 't': method = xstrdup("TRACE"); max_forwards = atoi(optarg); break; case 'g': ping = 1; pcount = atoi(optarg); to_stdout = 0; break; case 'I': if ((ping_int = atoi(optarg) * 1000) <= 0) usage(argv[0]); break; case 'H': if (strlen(optarg)) { char *t; strncpy(extra_hdrs, optarg, sizeof(extra_hdrs)); while ((t = strstr(extra_hdrs, "\\n"))) *t = '\r', *(t + 1) = '\n'; } break; case 'T': io_timeout = atoi(optarg); break; case 'u': proxy_user = optarg; break; case 'w': proxy_password = optarg; break; case 'U': www_user = optarg; break; case 'W': www_password = optarg; break; case 'v': /* undocumented: may increase verb-level by giving more -v's */ opt_verbose++; break; case '?': /* usage */ default: usage(argv[0]); break; } } #ifdef _SQUID_MSWIN_ { WSADATA wsaData; WSAStartup(2, &wsaData); } #endif /* Build the HTTP request */ if (strncmp(url, "mgr:", 4) == 0) { char *t = xstrdup(url + 4); snprintf(url, BUFSIZ, "cache_object://%s/%s", hostname, t); xfree(t); } if (put_file) { put_fd = open(put_file, O_RDONLY); set_our_signal(); if (put_fd < 0) { fprintf(stderr, "%s: can't open file (%s)\n", argv[0], xstrerror()); exit(-1); } #ifdef _SQUID_WIN32_ setmode(put_fd, O_BINARY); #endif fstat(put_fd, &sb); } snprintf(msg, BUFSIZ, "%s %s HTTP/1.0\r\n", method, url); if (reload) { snprintf(buf, BUFSIZ, "Pragma: no-cache\r\n"); strcat(msg, buf); } if (put_fd > 0) { snprintf(buf, BUFSIZ, "Content-length: %d\r\n", (int) sb.st_size); strcat(msg, buf); } if (opt_noaccept == 0) { snprintf(buf, BUFSIZ, "Accept: */*\r\n"); strcat(msg, buf); } if (ims) { snprintf(buf, BUFSIZ, "If-Modified-Since: %s\r\n", mkrfc1123(ims)); strcat(msg, buf); } if (max_forwards > -1) { snprintf(buf, BUFSIZ, "Max-Forwards: %d\r\n", max_forwards); strcat(msg, buf); } if (proxy_user) { char *user = proxy_user; char *password = proxy_password; #if HAVE_GETPASS if (!password) password = getpass("Proxy password: "******"ERROR: Proxy password missing\n"); exit(1); } snprintf(buf, BUFSIZ, "%s:%s", user, password); snprintf(buf, BUFSIZ, "Proxy-Authorization: Basic %s\r\n", base64_encode(buf)); strcat(msg, buf); } if (www_user) { char *user = www_user; char *password = www_password; #if HAVE_GETPASS if (!password) password = getpass("WWW password: "******"ERROR: WWW password missing\n"); exit(1); } snprintf(buf, BUFSIZ, "%s:%s", user, password); snprintf(buf, BUFSIZ, "Authorization: Basic %s\r\n", base64_encode(buf)); strcat(msg, buf); } if (keep_alive) { if (port != 80) snprintf(buf, BUFSIZ, "Proxy-Connection: keep-alive\r\n"); else snprintf(buf, BUFSIZ, "Connection: keep-alive\r\n"); strcat(msg, buf); } strcat(msg, extra_hdrs); snprintf(buf, BUFSIZ, "\r\n"); strcat(msg, buf); if (opt_verbose) fprintf(stderr, "headers: '%s'\n", msg); if (ping) { #if HAVE_SIGACTION struct sigaction sa, osa; if (sigaction(SIGINT, NULL, &osa) == 0 && osa.sa_handler == SIG_DFL) { sa.sa_handler = catchSignal; sa.sa_flags = 0; sigemptyset(&sa.sa_mask); (void) sigaction(SIGINT, &sa, NULL); } #else void (*osig) (); if ((osig = signal(SIGINT, catchSignal)) != SIG_DFL) (void) signal(SIGINT, osig); #endif } loops = ping ? pcount : 1; for (i = 0; loops == 0 || i < loops; i++) { squid_off_t fsize = 0; /* Connect to the server */ if ((conn = socket(PF_INET, SOCK_STREAM, 0)) < 0) { perror("client: socket"); exit(1); } if (localhost && client_comm_bind(conn, localhost) < 0) { perror("client: bind"); exit(1); } if (client_comm_connect(conn, hostname, port, (ping || opt_verbose) ? &tv1 : NULL) < 0) { if (errno == 0) { fprintf(stderr, "client: ERROR: Cannot connect to %s:%d: Host unknown.\n", hostname, port); } else { char tbuf[BUFSIZ]; snprintf(tbuf, BUFSIZ, "client: ERROR: Cannot connect to %s:%d", hostname, port); perror(tbuf); } exit(1); } /* Send the HTTP request */ bytesWritten = mywrite(conn, msg, strlen(msg)); if (bytesWritten < 0) { perror("client: ERROR: write"); exit(1); } else if (bytesWritten != strlen(msg)) { fprintf(stderr, "client: ERROR: Cannot send request?: %s\n", msg); exit(1); } if (put_file) { int x; lseek(put_fd, 0, SEEK_SET); #ifdef _SQUID_MSWIN_ while ((x = read(put_fd, buf, sizeof(buf))) > 0) { #else while ((x = myread(put_fd, buf, sizeof(buf))) > 0) { #endif x = mywrite(conn, buf, x); total_bytes += x; if (x <= 0) break; } if (x != 0) fprintf(stderr, "client: ERROR: Cannot send file.\n"); } /* Read the data */ #ifdef _SQUID_MSWIN_ setmode(1, O_BINARY); #endif while ((len = myread(conn, buf, sizeof(buf))) > 0) { fsize += len; if (to_stdout) fwrite(buf, len, 1, stdout); } #ifdef _SQUID_MSWIN_ setmode(1, O_TEXT); #endif (void) close(conn); /* done with socket */ if (interrupted) break; if (ping || opt_verbose) { struct tm *tmp; time_t t2s; long elapsed_msec; (void) Now(&tv2); elapsed_msec = tvSubMsec(tv1, tv2); t2s = tv2.tv_sec; tmp = localtime(&t2s); fprintf(stderr, "%d-%02d-%02d %02d:%02d:%02d [%d]: %ld.%03ld secs, %f KB/s (%" PRINTF_OFF_T "KB)\n", tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday, tmp->tm_hour, tmp->tm_min, tmp->tm_sec, i + 1, elapsed_msec / 1000, elapsed_msec % 1000, elapsed_msec ? (double) fsize / elapsed_msec * 1000 / 1024 : -1.0, (fsize + 1023) / 1024); if (i == 0 || elapsed_msec < ping_min) ping_min = elapsed_msec; if (i == 0 || elapsed_msec > ping_max) ping_max = elapsed_msec; ping_sum += elapsed_msec; /* Delay until next "ping_int" boundary */ if (ping && (loops == 0 || i + 1 < loops) && elapsed_msec < ping_int) { struct timeval tvs; long msec_left = ping_int - elapsed_msec; tvs.tv_sec = msec_left / 1000; tvs.tv_usec = (msec_left % 1000) * 1000; select(0, NULL, NULL, NULL, &tvs); } } } if (ping && i) { ping_mean = ping_sum / i; fprintf(stderr, "%d requests, round-trip (secs) min/avg/max = " "%ld.%03ld/%ld.%03ld/%ld.%03ld\n", i, ping_min / 1000, ping_min % 1000, ping_mean / 1000, ping_mean % 1000, ping_max / 1000, ping_max % 1000); } exit(0); /*NOTREACHED */ return 0; } static int client_comm_bind(int sock, const char *local_host) { static const struct hostent *hp = NULL; static struct sockaddr_in from_addr; /* Set up the source socket address from which to send. */ if (hp == NULL) { from_addr.sin_family = AF_INET; if ((hp = gethostbyname(local_host)) == 0) { return (-1); } xmemcpy(&from_addr.sin_addr, hp->h_addr, hp->h_length); from_addr.sin_port = 0; } return bind(sock, (struct sockaddr *) &from_addr, sizeof(struct sockaddr_in)); } static int client_comm_connect(int sock, const char *dest_host, u_short dest_port, struct timeval *tvp) { static const struct hostent *hp = NULL; static struct sockaddr_in to_addr; /* Set up the destination socket address for message to send to. */ if (hp == NULL) { to_addr.sin_family = AF_INET; if ((hp = gethostbyname(dest_host)) == 0) { return (-1); } xmemcpy(&to_addr.sin_addr, hp->h_addr, hp->h_length); to_addr.sin_port = htons(dest_port); } if (tvp) (void) Now(tvp); return connect(sock, (struct sockaddr *) &to_addr, sizeof(struct sockaddr_in)); } static int Now(struct timeval *tp) { #if GETTIMEOFDAY_NO_TZP return gettimeofday(tp); #else return gettimeofday(tp, NULL); #endif } /* ARGSUSED */ static void catchSignal(int sig) { interrupted = 1; fprintf(stderr, "Interrupted.\n"); }
static void netdbReloadState(void) { char *buf; char *t; char *s; int fd; int l; struct stat sb; netdbEntry *n; netdbEntry N; struct in_addr addr; int count = 0; struct timeval start = current_time; if (strcmp(Config.netdbFilename, "none") == 0) return; /* * This was nicer when we were using stdio, but thanks to * Solaris bugs, its a bad idea. fopen can fail if more than * 256 FDs are open. */ fd = file_open(Config.netdbFilename, O_RDONLY | O_BINARY); if (fd < 0) return; if (fstat(fd, &sb) < 0) { file_close(fd); return; } t = buf = xcalloc(1, (size_t) sb.st_size + 1); l = FD_READ_METHOD(fd, buf, (int) sb.st_size); file_close(fd); if (l <= 0) return; while ((s = strchr(t, '\n'))) { char *q; assert(s - buf < l); *s = '\0'; memset(&N, '\0', sizeof(netdbEntry)); q = strtok(t, w_space); t = s + 1; if (NULL == q) continue; if (!safe_inet_addr(q, &addr)) continue; if (netdbLookupAddr(addr) != NULL) /* no dups! */ continue; if ((q = strtok(NULL, w_space)) == NULL) continue; N.pings_sent = atoi(q); if ((q = strtok(NULL, w_space)) == NULL) continue; N.pings_recv = atoi(q); if (N.pings_recv == 0) continue; /* give this measurement low weight */ N.pings_sent = 1; N.pings_recv = 1; if ((q = strtok(NULL, w_space)) == NULL) continue; N.hops = atof(q); if ((q = strtok(NULL, w_space)) == NULL) continue; N.rtt = atof(q); if ((q = strtok(NULL, w_space)) == NULL) continue; N.next_ping_time = (time_t) atoi(q); if ((q = strtok(NULL, w_space)) == NULL) continue; N.last_use_time = (time_t) atoi(q); n = memAllocate(MEM_NETDBENTRY); xmemcpy(n, &N, sizeof(netdbEntry)); netdbHashInsert(n, addr); while ((q = strtok(NULL, w_space)) != NULL) { if (netdbLookupHost(q) != NULL) /* no dups! */ continue; netdbHostInsert(n, q); } count++; } xfree(buf); getCurrentTime(); debug(38, 1) ("NETDB state reloaded; %d entries, %d msec\n", count, tvSubMsec(start, current_time)); }