From: Amos Jeffries Date: Tue, 8 Jun 2010 14:16:03 +0000 (+1200) Subject: Merge from trunk X-Git-Tag: take08~55^2~124^2~135 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3a1dccf5cdcefe0def5fd9c4b29cde7114f7da40;p=thirdparty%2Fsquid.git Merge from trunk --- 3a1dccf5cdcefe0def5fd9c4b29cde7114f7da40 diff --cc src/forward.cc index a5e3afb83e,a954803d05..4fcda73b68 --- a/src/forward.cc +++ b/src/forward.cc @@@ -59,16 -54,12 +59,9 @@@ static PF fwdServerClosedWrapper #if USE_SSL static PF fwdNegotiateSSLWrapper; #endif - #if 0 --static PF fwdConnectTimeoutWrapper; --static EVH fwdConnectStartWrapper; - #endif static CNCB fwdConnectDoneWrapper; static OBJH fwdStats; - #if 0 --static void fwdServerFree(FwdServer * fs); - #endif #define MAX_FWD_STATS_IDX 9 static int FwdReplyCodes[MAX_FWD_STATS_IDX + 1][HTTP_INVALID_HEADER + 1]; @@@ -664,46 -676,63 +657,53 @@@ FwdState::initiateSSL( #endif void -FwdState::connectDone(int aServerFD, const DnsLookupDetails &dns, comm_err_t status, int xerrno) +FwdState::connectDone(Comm::ConnectionPointer conn, Comm::PathsPointer result_paths, comm_err_t status, int xerrno) { - FwdServer *fs = servers; - assert(server_fd == aServerFD); - - request->recordLookup(dns); + assert(result_paths == &paths); - if (Config.onoff.log_ip_on_direct && status != COMM_ERR_DNS && fs->code == HIER_DIRECT) - updateHierarchyInfo(); - - if (status == COMM_ERR_DNS) { - /* - * Only set the dont_retry flag if the DNS lookup fails on - * a direct connection. If DNS lookup fails when trying - * a neighbor cache, we may want to retry another option. - */ + if (status != COMM_OK) { + ErrorState *anErr = errorCon(ERR_CONNECT_FAIL, HTTP_SERVICE_UNAVAILABLE, request); + anErr->xerrno = xerrno; - if (NULL == fs->_peer) - flags.dont_retry = 1; + fail(anErr); - debugs(17, 4, "fwdConnectDone: Unknown host: " << request->GetHost()); + /* it might have been a timeout with a partially open link */ + if (paths.size() > 0) { + if (paths[0]->getPeer()) + peerConnectFailed(paths[0]->getPeer()); - ErrorState *anErr = errorCon(ERR_DNS_FAIL, HTTP_SERVICE_UNAVAILABLE, request); + comm_close(paths[0]); + } - anErr->dnsError = dns.error; + return; + } - fail(anErr); ++#if REDUNDANT_NOW + if (Config.onoff.log_ip_on_direct && paths[0]->peer_type == HIER_DIRECT) + updateHierarchyInfo(); ++#endif - comm_close(server_fd); - } else if (status != COMM_OK) { - assert(fs); - ErrorState *anErr = errorCon(ERR_CONNECT_FAIL, HTTP_SERVICE_UNAVAILABLE, request); - anErr->xerrno = xerrno; + debugs(17, 3, "FD " << paths[0]->fd << ": '" << entry->url() << "'" ); - comm_add_close_handler(conn->fd, fwdServerClosedWrapper, this); - fail(anErr); ++ comm_add_close_handler(paths[0]->fd, fwdServerClosedWrapper, this); - if (fs->_peer) - peerConnectFailed(fs->_peer); + if (paths[0]->getPeer()) + peerConnectSucceded(paths[0]->getPeer()); - comm_close(server_fd); - } else { - debugs(17, 3, "fwdConnectDone: FD " << server_fd << ": '" << entry->url() << "'" ); ++ // TODO: Avoid this if %local_port is often cached. ++ request->hier.peer_local_port = comm_local_port(paths[0]->fd); + - if (fs->_peer) - peerConnectSucceded(fs->_peer); ++ updateHierarchyInfo(); + #if USE_SSL - - if ((fs->_peer && fs->_peer->use_ssl) || - (!fs->_peer && request->protocol == PROTO_HTTPS)) { - initiateSSL(); - return; - } - -#endif - dispatch(); + if ((paths[0]->getPeer() && paths[0]->getPeer()->use_ssl) || + (!paths[0]->getPeer() && request->protocol == PROTO_HTTPS)) { + initiateSSL(); + return; } +#endif + + dispatch(); } void @@@ -815,8 -852,13 +815,12 @@@ FwdState::connectStart( updateHierarchyInfo(); - comm_add_close_handler(fd, fwdServerClosedWrapper, this); + comm_add_close_handler(conn->fd, fwdServerClosedWrapper, this); + + // TODO: Avoid this if %local_port is often cached. - request->hier.peer_local_port = comm_local_port(fd); ++ request->hier.peer_local_port = comm_local_port(conn->fd); + dispatch(); - return; } @@@ -824,13 -866,81 +828,11 @@@ entry->mem_obj->checkUrlChecksum(); #endif - outgoing = getOutgoingAddr(request, fs->_peer); - - tos = getOutgoingTOS(request); - - debugs(17, 3, "fwdConnectStart: got outgoing addr " << outgoing << ", tos " << tos); - - int commFlags = COMM_NONBLOCKING; - if (request->flags.spoof_client_ip) { - if (!fs->_peer || !fs->_peer->options.no_tproxy) - commFlags |= COMM_TRANSPARENT; - // else no tproxy today ... - } - - fd = comm_openex(SOCK_STREAM, IPPROTO_TCP, outgoing, commFlags, tos, url); - - debugs(17, 3, "fwdConnectStart: got TCP FD " << fd); - - if (fd < 0) { - debugs(50, 4, "fwdConnectStart: " << xstrerror()); - ErrorState *anErr = errorCon(ERR_SOCKET_FAILURE, HTTP_INTERNAL_SERVER_ERROR, request); - anErr->xerrno = errno; - fail(anErr); - self = NULL; // refcounted - return; - } - - server_fd = fd; - n_tries++; - - if (!fs->_peer) - origin_tries++; - - request->hier.peer_local_port = comm_local_port(fd); - - /* - * stats.conn_open is used to account for the number of - * connections that we have open to the peer, so we can limit - * based on the max-conn option. We need to increment here, - * even if the connection may fail. - */ - - if (fs->_peer) { - fs->_peer->stats.conn_open++; - comm_add_close_handler(fd, fwdPeerClosed, fs->_peer); - } - - comm_add_close_handler(fd, fwdServerClosedWrapper, this); - - commSetTimeout(fd, ctimeout, fwdConnectTimeoutWrapper, this); - -- updateHierarchyInfo(); - commConnectStart(fd, host, port, fwdConnectDoneWrapper, this); -} - -void -FwdState::startComplete(FwdServer * theServers) -{ - debugs(17, 3, "fwdStartComplete: " << entry->url() ); - - if (theServers != NULL) { - servers = theServers; - connectStart(); - } else { - startFail(); - } -} -- -void -FwdState::startFail() -{ - debugs(17, 3, "fwdStartFail: " << entry->url() ); - ErrorState *anErr = errorCon(ERR_CANNOT_FORWARD, HTTP_SERVICE_UNAVAILABLE, request); - anErr->xerrno = errno; - fail(anErr); - self = NULL; // refcounted + AsyncCall::Pointer call = commCbCall(17,3, "fwdConnectDoneWrapper", CommConnectCbPtrFun(fwdConnectDoneWrapper, this)); + ConnectStateData *cs = new ConnectStateData(&paths, call); + cs->host = xstrdup(host); + cs->connect_timeout = ctimeout; + cs->connect(); } void