solo = NULL;
}
+bool
+ConnOpener::doneAll() const
+{
+ // is the conn to be opened still waiting?
+ if (solo != NULL)
+ return false;
+
+ // is the callback still to be called?
+ if (callback != NULL)
+ return false;
+
+ return true;
+}
+
void
ConnOpener::setHost(const char * new_host)
{
void
ConnOpener::callCallback(comm_err_t status, int xerrno)
{
- /* remove handlers we don't want to happen now */
- comm_remove_close_handler(solo->fd, ConnOpener::EarlyAbort, this);
- commSetTimeout(solo->fd, -1, NULL, NULL);
-
- typedef CommConnectCbParams Params;
- Params ¶ms = GetCommParams<Params>(callback);
- params.conn = solo;
- params.flag = status;
- params.xerrno = xerrno;
- ScheduleCallHere(callback);
-
- callback = NULL;
- delete this;
+ /* remove handlers we don't want to happen anymore */
+ if (solo != NULL && solo->fd > 0) {
+ comm_remove_close_handler(solo->fd, ConnOpener::EarlyAbort, this);
+ commSetTimeout(solo->fd, -1, NULL, NULL);
+ }
+
+ if (callback != NULL) {
+ typedef CommConnectCbParams Params;
+ Params ¶ms = GetCommParams<Params>(callback);
+ params.conn = solo;
+ params.flag = status;
+ params.xerrno = xerrno;
+ ScheduleCallHere(callback);
+ callback = NULL;
+ }
+
+ /* ensure cleared local state, we are done. */
+ solo = NULL;
}
void
}
#endif
solo->fd = comm_openex(SOCK_STREAM, IPPROTO_TCP, solo->local, solo->flags, solo->tos, host);
- if (solo->fd <= 0) {
+ if (solo->fd < 0) {
callCallback(COMM_ERR_CONNECT, 0);
return;
}
switch (comm_connect_addr(solo->fd, solo->remote) ) {
case COMM_INPROGRESS:
- debugs(5, 5, HERE << "FD " << solo->fd << ": COMM_INPROGRESS");
- commSetSelect(solo->fd, COMM_SELECT_WRITE, ConnOpener::ConnectRetry, this, 0);
+ // check for timeout FIRST.
+ if(squid_curtime - connstart > connect_timeout) {
+ debugs(5, 5, HERE << "FD " << solo->fd << ": * - ERR took too long already.");
+ callCallback(COMM_TIMEOUT, errno);
+ return;
+ } else {
+ debugs(5, 5, HERE << "FD " << solo->fd << ": COMM_INPROGRESS");
+ commSetSelect(solo->fd, COMM_SELECT_WRITE, ConnOpener::ConnectRetry, this, 0);
+ }
break;
case COMM_OK:
ConnOpener *cs = static_cast<ConnOpener *>(data);
debugs(5, 3, HERE << "FD " << fd);
cs->callCallback(COMM_ERR_CLOSING, errno); // NP: is closing or shutdown better?
-
- /* TODO split cases:
- * remote end rejecting the connection is normal and one of the other paths may be taken.
- * squid shutting down or forcing abort on the connection attempt(s) are the only real fatal cases.
- * we may need separate error codes to send back for these two.
- */
}
void
ConnOpener *cs = static_cast<ConnOpener *>(data);
cs->start();
}
-
AsyncCall::Pointer call = commCbCall(9,3, "FtpStateData::ftpPasvCallback", CommConnectCbPtrFun(FtpStateData::ftpPasvCallback, ftpState));
ConnOpener *cs = new ConnOpener(conn, call);
cs->setHost(ftpState->data.host);
- cs->start();
+ AsyncJob::AsyncStart(cs);
}
/** \ingroup ServerProtocolFTPInternal
ConnOpener *cs = new ConnOpener(conn, call);
cs->setHost(ftpState->data.host);
cs->connect_timeout = Config.Timeout.connect;
- cs->start();
+ AsyncJob::AsyncStart(cs);
}
void
ConnOpener *cs = new ConnOpener(tunnelState->paths[0], call);
cs->setHost(tunnelState->url);
cs->connect_timeout = Config.Timeout.connect;
- cs->start();
+ AsyncJob::AsyncStart(cs);
} else {
err = errorCon(ERR_CONNECT_FAIL, HTTP_SERVICE_UNAVAILABLE, request);
*tunnelState->status_ptr = HTTP_SERVICE_UNAVAILABLE;
ConnOpener *cs = new ConnOpener(tunnelState->paths[0], call);
cs->setHost(tunnelState->url);
cs->connect_timeout = Config.Timeout.connect;
- cs->start();
+ AsyncJob::AsyncStart(cs);
}
CBDATA_CLASS_INIT(TunnelStateData);