if (fwd->isServerConnectionOpen()) {
comm_remove_close_handler(fwd->serverConnection()->fd, fwdServerClosedWrapper, fwd);
}
- fwd->paths.clean();
+ fwd->serverDestinations.clean();
fwd->self = NULL;
}
client_fd = fd;
request = HTTPMSGLOCK(r);
start_t = squid_curtime;
-
+ serverDestinations.reserve(Config.forward_max_tries);
e->lock();
EBIT_SET(e->flags, ENTRY_FWD_HDR_WAIT);
}
// Otherwise we are going to leak our object.
entry->registerAbort(FwdState::abort, this);
- peerSelect(&paths, request, entry, fwdStartCompleteWrapper, this);
+ peerSelect(&serverDestinations, request, entry, fwdStartCompleteWrapper, this);
}
void
if (isServerConnectionOpen()) {
comm_remove_close_handler(serverConnection()->fd, fwdServerClosedWrapper, this);
debugs(17, 3, HERE << "closing FD " << serverConnection()->fd);
- serverConnection()->close();
+ serverConn->close();
}
- paths.clean();
+ serverDestinations.clean();
debugs(17, 3, HERE << "FwdState destructor done");
}
{
debugs(17, 3, HERE << entry->url() );
- if (paths.size() > 0) {
+ if (serverDestinations.size() > 0) {
connectStart();
} else {
debugs(17, 3, HERE << entry->url() );
* Frees fwdState without closing FD or generating an abort
*/
void
-FwdState::unregister(Comm::ConnectionPointer conn)
+FwdState::unregister(Comm::ConnectionPointer &conn)
{
debugs(17, 3, HERE << entry->url() );
assert(serverConnection() == conn);
assert(conn->isOpen());
comm_remove_close_handler(conn->fd, fwdServerClosedWrapper, this);
+ serverConn = NULL;
}
// Legacy method to be removed in favor of the above as soon as possible
{
debugs(17, 3, HERE << entry->url() );
assert(fd == serverConnection()->fd);
- assert(fd > -1);
- comm_remove_close_handler(fd, fwdServerClosedWrapper, this);
- serverConnection()->fd = -1;
+ unregister(serverConn);
}
/**
debugs(17, 3, HERE << "re-forwarding " << entry->getReply()->sline.status << " " << entry->url());
if (isServerConnectionOpen())
- unregister(serverConnection());
+ unregister(serverConn);
entry->reset();
/**** CALLBACK WRAPPERS ************************************************************/
static void
-fwdStartCompleteWrapper(Comm::Paths * unused, void *data)
+fwdStartCompleteWrapper(Comm::ConnectionList * unused, void *data)
{
FwdState *fwd = (FwdState *) data;
fwd->startComplete();
if (checkRetry()) {
debugs(17, 3, HERE << "re-forwarding (" << n_tries << " tries, " << (squid_curtime - start_t) << " secs)");
- paths.shift(); // last one failed. try another.
+ serverDestinations.shift(); // last one failed. try another.
- if (paths.size() > 0) {
+ if (serverDestinations.size() > 0) {
/* Ditch error page if it was created before.
* A new one will be created if there's another problem */
if (err) {
connectStart();
return;
}
- // else bail. no more paths possible to try.
+ // else bail. no more serverDestinations possible to try.
}
if (!err && shutting_down) {
peerConnectFailed(serverConnection()->getPeer());
}
- serverConnection()->close();
+ serverConn->close();
return;
}
}
fail(anErr);
/* it might have been a timeout with a partially open link */
- if (paths.size() > 0) {
- if (serverConnection()->getPeer())
- peerConnectFailed(serverConnection()->getPeer());
+ if (conn != NULL) {
+ if (conn->getPeer())
+ peerConnectFailed(conn->getPeer());
- serverConnection()->close();
+ conn->close();
}
retryOrBail();
return;
}
+ serverConn = conn;
+
#if REDUNDANT_NOW
if (Config.onoff.log_ip_on_direct && serverConnection()->peerType == HIER_DIRECT)
updateHierarchyInfo();
fail(anErr);
/* This marks the peer DOWN ... */
- if (paths.size() > 0)
- if (serverConnection()->getPeer())
+ if (serverConnection() != NULL && serverConnection()->getPeer())
peerConnectFailed(serverConnection()->getPeer());
}
if (isServerConnectionOpen()) {
- serverConnection()->close();
+ serverConn->close();
}
}
if (serverConnection()->peerType == PINNED) {
ConnStateData *pinned_connection = request->pinnedConnection();
assert(pinned_connection);
- serverConnection()->fd = pinned_connection->validatePinnedConnection(request, serverConnection()->getPeer());
+ serverConn->fd = pinned_connection->validatePinnedConnection(request, serverConnection()->getPeer());
if (isServerConnectionOpen()) {
pinned_connection->unpinConnection();
#if 0
if (!serverConnection()->getPeer())
- serverConnection()->peerType = HIER_DIRECT;
+ serverConn->peerType = HIER_DIRECT;
#endif
n_tries++;
request->flags.pinned = 1;
if (pinned_connection->pinnedAuth())
request->flags.auth = 1;
updateHierarchyInfo();
- Comm::ConnectionPointer conn = serverConnection();
- FwdState::connectDone(conn, COMM_OK, 0);
+ FwdState::connectDone(serverConn, COMM_OK, 0);
return;
}
/* Failure. Fall back on next path */
debugs(17,2,HERE << " Pinned connection " << pinned_connection << " not valid. Releasing.");
request->releasePinnedConnection();
- paths.shift();
+ serverDestinations.shift();
connectStart();
return;
}
if (serverConnection()->getPeer()) {
host = serverConnection()->getPeer()->host;
port = serverConnection()->getPeer()->http_port;
- serverConnection()->fd = fwdPconnPool->pop(serverConnection()->getPeer()->name,
- serverConnection()->getPeer()->http_port,
- request->GetHost(), serverConnection()->local,
- checkRetriable());
+ serverConn->fd = fwdPconnPool->pop(serverConnection()->getPeer()->name,
+ serverConnection()->getPeer()->http_port,
+ request->GetHost(), serverConn->local,
+ checkRetriable());
} else {
host = request->GetHost();
port = request->port;
- serverConnection()->fd = fwdPconnPool->pop(host, port, NULL, serverConnection()->local, checkRetriable());
+ serverConn->fd = fwdPconnPool->pop(host, port, NULL, serverConn->local, checkRetriable());
}
- serverConnection()->remote.SetPort(port);
+ serverConn->remote.SetPort(port);
if (isServerConnectionOpen()) {
debugs(17, 3, HERE << "reusing pconn FD " << serverConnection()->fd);
#endif
AsyncCall::Pointer call = commCbCall(17,3, "fwdConnectDoneWrapper", CommConnectCbPtrFun(fwdConnectDoneWrapper, this));
- Comm::ConnectionPointer conn = serverConnection();
- Comm::ConnOpener *cs = new Comm::ConnOpener(conn, call, ctimeout);
+ Comm::ConnOpener *cs = new Comm::ConnOpener(serverDestinations[0], call, ctimeout);
cs->setHost(host);
AsyncJob::AsyncStart(cs);
}
*/
flags.dont_retry = 1;
if (isServerConnectionOpen()) {
- serverConnection()->close();
+ serverConn->close();
}
break;
}
if (request->bodyNibbled())
return 0;
- paths.shift();
+ serverDestinations.shift();
- if (paths.size() > 0) {
+ if (serverDestinations.size() > 0) {
debugs(17, 3, HERE << "No alternative forwarding paths left");
return 0;
}
* - address of the client for which we made the connection
*/
void
-FwdState::pconnPush(Comm::ConnectionPointer conn, const peer *_peer, const HttpRequest *req, const char *domain, Ip::Address &client_addr)
+FwdState::pconnPush(Comm::ConnectionPointer &conn, const peer *_peer, const HttpRequest *req, const char *domain, Ip::Address &client_addr)
{
if (_peer) {
fwdPconnPool->push(conn->fd, _peer->name, _peer->http_port, domain, client_addr);
{
assert(request);
- assert(paths.size() > 0);
+ assert(serverDestinations.size() > 0);
char nextHop[256];
static void fwdStart(int fd, StoreEntry *, HttpRequest *);
void startComplete();
void fail(ErrorState *err);
- void unregister(Comm::ConnectionPointer conn);
+ void unregister(Comm::ConnectionPointer &conn);
void unregister(int fd);
void complete();
void handleUnregisteredServerEnd();
bool reforwardableStatus(http_status s);
void serverClosed(int fd);
void connectStart();
- void connectDone(Comm::ConnectionPointer &conn, comm_err_t status, int xerrno);
+ void connectDone(Comm::ConnectionPointer & conn, comm_err_t status, int xerrno);
void connectTimeout(int fd);
void initiateSSL();
void negotiateSSL(int fd);
bool checkRetry();
bool checkRetriable();
void dispatch();
- void pconnPush(Comm::ConnectionPointer conn, const peer *_peer, const HttpRequest *req, const char *domain, Ip::Address &client_addr);
+ void pconnPush(Comm::ConnectionPointer & conn, const peer *_peer, const HttpRequest *req, const char *domain, Ip::Address &client_addr);
bool dontRetry() { return flags.dont_retry; }
void ftpPasvFailed(bool val) { flags.ftp_pasv_failed = val; }
/** return a ConnectionPointer to the current server connection (may or may not be open) */
- Comm::ConnectionPointer serverConnection() const { assert(paths.size() > 0); return paths[0]; };
+ Comm::ConnectionPointer const & serverConnection() const { return serverConn; };
/** test if the current server connection is open */
bool isServerConnectionOpen() const {
- if (paths.size() > 0 && serverConnection()->fd >= 0)
- assert(fd_table[serverConnection()->fd].flags.open == serverConnection()->isOpen());
- return (paths.size() > 0 && serverConnection()->isOpen());
+ if (serverConn != NULL && serverConn->isOpen())
+ assert(fd_table[serverConn->fd].flags.open == serverConn->isOpen());
+ return (serverConn != NULL && serverConn->isOpen());
};
private:
} flags;
/** connections to open, in order, until successful */
- Comm::Paths paths;
+ Comm::ConnectionList serverDestinations;
+
+ Comm::ConnectionPointer serverConn; ///< a successfully opened connection to a server.
// NP: keep this last. It plays with private/public
CBDATA_CLASS2(FwdState);
char *host; /* either request->host or proxy host */
u_short port;
HttpRequest *request;
- Comm::Paths paths;
+ Comm::ConnectionList serverDestinations;
class Connection
{
~Connection();
int const & fd() const { return fd_;}
- void fd(int const newFD);
+ void fd(int newFd);
int bytesWanted(int lower=0, int upper = INT_MAX) const;
void bytesIn(int const &);
#if DELAY_POOLS
assert(tunnelState != NULL);
assert(tunnelState->noConnections());
safe_free(tunnelState->url);
- tunnelState->paths.clean();
+ tunnelState->serverDestinations.clean();
tunnelState->host = NULL;
HTTPMSGUNLOCK(tunnelState->request);
delete tunnelState;
/* At this point only the TCP handshake has failed. no data has been passed.
* we are allowed to re-try the TCP-level connection to alternate IPs for CONNECT.
*/
- tunnelState->paths.shift();
- if (status != COMM_TIMEOUT && tunnelState->paths.size() > 0) {
+ tunnelState->serverDestinations.shift();
+ if (status != COMM_TIMEOUT && tunnelState->serverDestinations.size() > 0) {
/* Try another IP of this destination host */
AsyncCall::Pointer call = commCbCall(26,3, "tunnelConnectDone", CommConnectCbPtrFun(tunnelConnectDone, tunnelState));
- Comm::ConnOpener *cs = new Comm::ConnOpener(tunnelState->paths[0], call, Config.Timeout.connect);
+ Comm::ConnOpener *cs = new Comm::ConnOpener(tunnelState->serverDestinations[0], call, Config.Timeout.connect);
cs->setHost(tunnelState->url);
AsyncJob::AsyncStart(cs);
} else {
tunnelTimeout,
tunnelState);
- peerSelect(&(tunnelState->paths), request,
+ peerSelect(&(tunnelState->serverDestinations), request,
NULL,
tunnelPeerSelectComplete,
tunnelState);
}
static void
-tunnelPeerSelectComplete(Comm::Paths *peer_paths, void *data)
+tunnelPeerSelectComplete(Comm::ConnectionList *peer_paths, void *data)
{
TunnelStateData *tunnelState = (TunnelStateData *)data;
HttpRequest *request = tunnelState->request;
}
AsyncCall::Pointer call = commCbCall(26,3, "tunnelConnectDone", CommConnectCbPtrFun(tunnelConnectDone, tunnelState));
- Comm::ConnOpener *cs = new Comm::ConnOpener(tunnelState->paths[0], call, Config.Timeout.connect);
+ Comm::ConnOpener *cs = new Comm::ConnOpener(tunnelState->serverDestinations[0], call, Config.Timeout.connect);
cs->setHost(tunnelState->url);
AsyncJob::AsyncStart(cs);
}