Index: squid/src/cf.data.pre diff -c squid/src/cf.data.pre:1.245.2.53 squid/src/cf.data.pre:1.245.2.54 *** squid/src/cf.data.pre:1.245.2.53 Fri Nov 28 12:14:31 2003 --- squid/src/cf.data.pre Sat Nov 29 11:52:58 2003 *************** *** 3115,3129 **** NAME: maximum_single_addr_tries TYPE: int LOC: Config.retry.maxtries ! DEFAULT: 3 DOC_START This sets the maximum number of connection attempts for a host that only has one address (for multiple-address hosts, each address is tried once). ! The default value is three tries, the (not recommended) maximum is 255 tries. A warning message will be generated if it is set to a value greater than ten. DOC_END NAME: snmp_port --- 3115,3132 ---- NAME: maximum_single_addr_tries TYPE: int LOC: Config.retry.maxtries ! DEFAULT: 1 DOC_START This sets the maximum number of connection attempts for a host that only has one address (for multiple-address hosts, each address is tried once). ! The default value is one attempt, the (not recommended) maximum is 255 tries. A warning message will be generated if it is set to a value greater than ten. + + Note: This is in addition to the request reforwarding which + takes place if Squid fails to get a satisfying response. DOC_END NAME: snmp_port *************** *** 3585,3590 **** --- 3588,3597 ---- By combining nonhierarchical_direct off and prefer_direct on you can set up Squid to use a parent as a backup path if going direct fails. + + Note: If you want Squid to use parents for all requests then see + the never_direct directive. prefer_direct only modifies how Squid + acts on cachable requests. DOC_END NAME: strip_query_terms Index: squid/src/comm.c diff -c squid/src/comm.c:1.324.2.2 squid/src/comm.c:1.324.2.3 *** squid/src/comm.c:1.324.2.2 Sun Mar 31 23:03:38 2002 --- squid/src/comm.c Sat Nov 29 11:52:59 2003 *************** *** 49,55 **** CNCB *callback; void *data; struct in_addr in_addr; - int locks; int fd; int tries; int addrcount; --- 49,54 ---- *************** *** 272,278 **** cs->data = data; cbdataLock(cs->data); comm_add_close_handler(fd, commConnectFree, cs); - cs->locks++; ipcache_nbgethostbyname(host, commConnectDnsHandle, cs); } --- 271,276 ---- *************** *** 280,287 **** commConnectDnsHandle(const ipcache_addrs * ia, void *data) { ConnectStateData *cs = data; - assert(cs->locks == 1); - cs->locks--; if (ia == NULL) { debug(5, 3) ("commConnectDnsHandle: Unknown host: %s\n", cs->host); if (!dns_error_message) { --- 278,283 ---- *************** *** 398,403 **** --- 394,406 ---- return commResetFD(cs); } + static void + commReconnect(void *data) + { + ConnectStateData *cs = data; + ipcache_nbgethostbyname(cs->host, commConnectDnsHandle, cs); + } + /* Connect SOCK to specified DEST_PORT at DEST_HOST. */ static void commConnectHandle(int fd, void *data) *************** *** 425,432 **** if (Config.onoff.test_reachability) netdbDeleteAddrNetwork(cs->S.sin_addr); if (commRetryConnect(cs)) { ! cs->locks++; ! ipcache_nbgethostbyname(cs->host, commConnectDnsHandle, cs); } else { commConnectCallback(cs, COMM_ERR_CONNECT); } --- 428,434 ---- if (Config.onoff.test_reachability) netdbDeleteAddrNetwork(cs->S.sin_addr); if (commRetryConnect(cs)) { ! eventAdd("commReconnect", commReconnect, cs, cs->addrcount == 1 ? 0.05 : 0.0, 0); } else { commConnectCallback(cs, COMM_ERR_CONNECT); } Index: squid/src/forward.c diff -c squid/src/forward.c:1.82.2.4 squid/src/forward.c:1.82.2.5 *** squid/src/forward.c:1.82.2.4 Wed Aug 6 07:49:01 2003 --- squid/src/forward.c Sat Nov 29 11:53:00 2003 *************** *** 136,141 **** --- 136,143 ---- return 0; if (fwdState->n_tries > 10) return 0; + if (fwdState->origin_tries > 2) + return 0; if (squid_curtime - fwdState->start > Config.Timeout.connect) return 0; if (fwdState->flags.dont_retry) *************** *** 180,185 **** --- 182,188 ---- assert(fwdState->server_fd == fd); fwdState->server_fd = -1; if (fwdCheckRetry(fwdState)) { + int originserver = (fwdState->servers->peer == NULL); debug(17, 3) ("fwdServerClosed: re-forwarding (%d tries, %d secs)\n", fwdState->n_tries, (int) (squid_curtime - fwdState->start)); *************** *** 197,206 **** /* Use next. The last "direct" entry is retried multiple times */ fwdState->servers = fs->next; fwdServerFree(fs); } } ! /* use eventAdd to break potential call sequence loops */ ! eventAdd("fwdConnectStart", fwdConnectStart, fwdState, 0.0, 0); return; } if (!fwdState->err && shutting_down) { --- 200,210 ---- /* Use next. The last "direct" entry is retried multiple times */ fwdState->servers = fs->next; fwdServerFree(fs); + originserver = 0; } } ! /* use eventAdd to break potential call sequence loops and to slow things down a little */ ! eventAdd("fwdConnectStart", fwdConnectStart, fwdState, originserver ? 0.05 : 0.005, 0); return; } if (!fwdState->err && shutting_down) { *************** *** 387,392 **** --- 391,398 ---- debug(17, 3) ("fwdConnectStart: reusing pconn FD %d\n", fd); fwdState->server_fd = fd; fwdState->n_tries++; + if (!fs->peer) + fwdState->origin_tries++; comm_add_close_handler(fd, fwdServerClosed, fwdState); fwdConnectDone(fd, COMM_OK, fwdState); return; *************** *** 418,423 **** --- 424,431 ---- } fwdState->server_fd = fd; fwdState->n_tries++; + if (!fs->peer) + fwdState->origin_tries++; /* * stats.conn_open is used to account for the number of * connections that we have open to the peer, so we can limit *************** *** 553,558 **** --- 561,568 ---- return 0; } if (fwdState->n_tries > 9) + return 0; + if (fwdState->origin_tries > 1) return 0; if (fwdState->request->flags.body_sent) return 0; Index: squid/src/neighbors.c diff -c squid/src/neighbors.c:1.299.2.3 squid/src/neighbors.c:1.299.2.4 *** squid/src/neighbors.c:1.299.2.3 Tue Aug 12 18:28:19 2003 --- squid/src/neighbors.c Sat Nov 29 11:53:00 2003 *************** *** 48,55 **** static void neighborCountIgnored(peer *); static void peerRefreshDNS(void *); static IPH peerDNSConfigure; ! static void peerProbeConnect(peer *); ! static IPH peerProbeConnect2; static CNCB peerProbeConnectDone; static void peerCountMcastPeersDone(void *data); static void peerCountMcastPeersStart(void *data); --- 48,54 ---- static void neighborCountIgnored(peer *); static void peerRefreshDNS(void *); static IPH peerDNSConfigure; ! static int peerProbeConnect(peer *); static CNCB peerProbeConnectDone; static void peerCountMcastPeersDone(void *data); static void peerCountMcastPeersStart(void *data); *************** *** 590,609 **** if (!p->digest) { debug(15, 5) ("peerDigestLookup: gone!\n"); return LOOKUP_NONE; - } else if (!peerHTTPOkay(p, request)) { - debug(15, 5) ("peerDigestLookup: !peerHTTPOkay\n"); - return LOOKUP_NONE; - } else if (p->digest->flags.usable) { - debug(15, 5) ("peerDigestLookup: usable\n"); - /* fall through; put here to have common case on top */ ; } else if (!p->digest->flags.needed) { debug(15, 5) ("peerDigestLookup: note need\n"); peerDigestNeeded(p->digest); return LOOKUP_NONE; ! } else { debug(15, 5) ("peerDigestLookup: !ready && %srequested\n", p->digest->flags.requested ? "" : "!"); return LOOKUP_NONE; } debug(15, 5) ("peerDigestLookup: OK to lookup peer %s\n", p->host); assert(p->digest->cd); --- 589,605 ---- if (!p->digest) { debug(15, 5) ("peerDigestLookup: gone!\n"); return LOOKUP_NONE; } else if (!p->digest->flags.needed) { debug(15, 5) ("peerDigestLookup: note need\n"); peerDigestNeeded(p->digest); return LOOKUP_NONE; ! } else if (!p->digest->flags.usable) { debug(15, 5) ("peerDigestLookup: !ready && %srequested\n", p->digest->flags.requested ? "" : "!"); return LOOKUP_NONE; + } else if (!peerHTTPOkay(p, request)) { + debug(15, 5) ("peerDigestLookup: !peerHTTPOkay\n"); + return LOOKUP_NONE; } debug(15, 5) ("peerDigestLookup: OK to lookup peer %s\n", p->host); assert(p->digest->cd); *************** *** 935,942 **** neighborUp(const peer * p) { if (!p->tcp_up) { ! peerProbeConnect((peer *) p); ! return 0; } if (p->options.no_query) return 1; --- 931,938 ---- neighborUp(const peer * p) { if (!p->tcp_up) { ! if (!peerProbeConnect((peer *) p)) ! return 0; } if (p->options.no_query) return 1; *************** *** 1042,1056 **** eventAddIsh("peerRefreshDNS", peerRefreshDNS, NULL, 3600.0, 1); } ! void ! peerConnectFailed(peer * p) { p->stats.last_connect_failure = squid_curtime; if (!p->tcp_up) { debug(15, 2) ("TCP connection to %s/%d dead\n", p->host, p->http_port); return; } - debug(15, 1) ("TCP connection to %s/%d failed\n", p->host, p->http_port); p->tcp_up--; if (!p->tcp_up) { debug(15, 1) ("Detected DEAD %s: %s/%d/%d\n", --- 1038,1051 ---- eventAddIsh("peerRefreshDNS", peerRefreshDNS, NULL, 3600.0, 1); } ! static void ! peerConnectFailedSilent(peer * p) { p->stats.last_connect_failure = squid_curtime; if (!p->tcp_up) { debug(15, 2) ("TCP connection to %s/%d dead\n", p->host, p->http_port); return; } p->tcp_up--; if (!p->tcp_up) { debug(15, 1) ("Detected DEAD %s: %s/%d/%d\n", *************** *** 1061,1066 **** --- 1056,1068 ---- } void + peerConnectFailed(peer * p) + { + debug(15, 1) ("TCP connection to %s/%d failed\n", p->host, p->http_port); + peerConnectFailedSilent(p); + } + + void peerConnectSucceded(peer * p) { if (!p->tcp_up) { *************** *** 1073,1107 **** p->tcp_up = PEER_TCP_MAGIC_COUNT; } /* * peerProbeConnect will be called on dead peers by neighborUp */ ! static void peerProbeConnect(peer * p) { int fd; if (p->test_fd != -1) ! return; /* probe already running */ ! if (squid_curtime - p->stats.last_connect_probe < Config.Timeout.connect) ! return; /* don't probe to often */ fd = comm_open(SOCK_STREAM, 0, getOutgoingAddr(NULL), 0, COMM_NONBLOCKING, p->host); if (fd < 0) ! return; p->test_fd = fd; p->stats.last_connect_probe = squid_curtime; - ipcache_nbgethostbyname(p->host, peerProbeConnect2, p); - } - - static void - peerProbeConnect2(const ipcache_addrs * ianotused, void *data) - { - peer *p = data; commConnectStart(p->test_fd, p->host, p->http_port, peerProbeConnectDone, p); } static void --- 1075,1116 ---- p->tcp_up = PEER_TCP_MAGIC_COUNT; } + static void + peerProbeConnectTimeout(int fd, void *data) + { + peer *p = data; + comm_close(fd); + p->test_fd = -1; + peerConnectFailedSilent(p); + } + /* * peerProbeConnect will be called on dead peers by neighborUp */ ! static int peerProbeConnect(peer * p) { int fd; + time_t ctimeout = p->connect_timeout > 0 ? p->connect_timeout + : Config.Timeout.peer_connect; + int ret = squid_curtime - p->stats.last_connect_failure > ctimeout * 10; if (p->test_fd != -1) ! return ret; /* probe already running */ ! if (squid_curtime - p->stats.last_connect_probe == 0) ! return ret; /* don't probe to often */ fd = comm_open(SOCK_STREAM, 0, getOutgoingAddr(NULL), 0, COMM_NONBLOCKING, p->host); if (fd < 0) ! return ret; ! commSetTimeout(fd, ctimeout, peerProbeConnectTimeout, p); p->test_fd = fd; p->stats.last_connect_probe = squid_curtime; commConnectStart(p->test_fd, p->host, p->http_port, peerProbeConnectDone, p); + return ret; } static void *************** *** 1111,1117 **** if (status == COMM_OK) { peerConnectSucceded(p); } else { ! peerConnectFailed(p); } comm_close(fd); p->test_fd = -1; --- 1120,1126 ---- if (status == COMM_OK) { peerConnectSucceded(p); } else { ! peerConnectFailedSilent(p); } comm_close(fd); p->test_fd = -1; Index: squid/src/structs.h diff -c squid/src/structs.h:1.408.2.15 squid/src/structs.h:1.408.2.16 *** squid/src/structs.h:1.408.2.15 Wed Oct 29 17:01:52 2003 --- squid/src/structs.h Sat Nov 29 11:53:00 2003 *************** *** 1959,1964 **** --- 1959,1965 ---- ErrorState *err; time_t start; int n_tries; + int origin_tries; #if WIP_FWD_LOG http_status last_status; #endif