if (requestBodySource->getMoreData(buf)) {
debugs(9,3, HERE << "will write " << buf.contentSize() << " request body bytes");
typedef CommCbMemFunT<ServerStateData, CommIoCbParams> Dialer;
- requestSender = asyncCall(93,3, "ServerStateData::sentRequestBody",
- Dialer(this, &ServerStateData::sentRequestBody));
+ requestSender = JobCallback(93,3,
+ Dialer, this, ServerStateData::sentRequestBody);
- comm_write_mbuf(fd, &buf, requestSender);
+ comm_write_mbuf(conn->fd, &buf, requestSender);
} else {
debugs(9,3, HERE << "will wait for more request body bytes or eof");
requestSender = NULL;
//CBDATA_NAMESPACED_CLASS_INIT(Adaptation::Icap, Xaction);
- Adaptation::Icap::Xaction::Xaction(const char *aTypeName, Adaptation::Initiator *anInitiator, Adaptation::Icap::ServiceRep::Pointer &aService):
-Adaptation::Icap::Xaction::Xaction(const char *aTypeName,
- Adaptation::Icap::ServiceRep::Pointer &aService):
++Adaptation::Icap::Xaction::Xaction(const char *aTypeName, Adaptation::Icap::ServiceRep::Pointer &aService):
AsyncJob(aTypeName),
- Adaptation::Initiate(aTypeName, anInitiator),
+ Adaptation::Initiate(aTypeName),
icapRequest(NULL),
icapReply(NULL),
attempts(0),
// fake the connect callback
// TODO: can we sync call Adaptation::Icap::Xaction::noteCommConnected here instead?
typedef CommCbMemFunT<Adaptation::Icap::Xaction, CommConnectCbParams> Dialer;
- Dialer dialer(this, &Adaptation::Icap::Xaction::noteCommConnected);
+ CbcPointer<Xaction> self(this);
+ Dialer dialer(self, &Adaptation::Icap::Xaction::noteCommConnected);
- dialer.params.fd = connection;
+ dialer.params.fd = connection->fd;
dialer.params.flag = COMM_OK;
// fake other parameters by copying from the existing connection
connector = asyncCall(93,3, "Adaptation::Icap::Xaction::noteCommConnected", dialer);
disableRetries(); // we only retry pconn failures
- Ip::Address outgoing;
- if (!Ip::EnableIpv6 && !outgoing.SetIPv4()) {
- debugs(31, DBG_CRITICAL, "ERROR: IPv6 is disabled. " << outgoing << " is not an IPv4 address.");
- dieOnConnectionFailure(); // throws
- }
- /* split-stack for now requires default IPv4-only socket */
- if (Ip::EnableIpv6&IPV6_SPECIAL_SPLITSTACK && outgoing.IsAnyAddr() && !s.cfg().ipv6) {
- outgoing.SetIPv4();
- }
-
- connection = comm_open(SOCK_STREAM, 0, outgoing,
- COMM_NONBLOCKING, s.cfg().uri.termedBuf());
-
- if (connection < 0)
- dieOnConnectionFailure(); // throws
-
- debugs(93,3, typeName << " opens connection to " << s.cfg().host << ":" << s.cfg().port);
-
- // TODO: service bypass status may differ from that of a transaction
- typedef CommCbMemFunT<Adaptation::Icap::Xaction, CommTimeoutCbParams> TimeoutDialer;
- AsyncCall::Pointer timeoutCall = JobCallback(93, 5,
- TimeoutDialer, this, Adaptation::Icap::Xaction::noteCommTimedout);
- commSetTimeout(connection, TheConfig.connect_timeout(
- service().cfg().bypass), timeoutCall);
-
- typedef CommCbMemFunT<Adaptation::Icap::Xaction, CommCloseCbParams> CloseDialer;
- closer = JobCallback(93, 5,
- CloseDialer, this, Adaptation::Icap::Xaction::noteCommClosed);
- comm_add_close_handler(connection, closer);
-
typedef CommCbMemFunT<Adaptation::Icap::Xaction, CommConnectCbParams> ConnectDialer;
- connector = asyncCall(93,3, "Adaptation::Icap::Xaction::noteCommConnected",
- ConnectDialer(this, &Adaptation::Icap::Xaction::noteCommConnected));
-
- connector = JobCallback(93,3,
- ConnectDialer, this, Adaptation::Icap::Xaction::noteCommConnected);
- commConnectStart(connection, s.cfg().host.termedBuf(), s.cfg().port, connector);
++ connector = JobCallback(93,3, ConnectDialer, this, Adaptation::Icap::Xaction::noteCommConnected);
+ Comm::ConnOpener *cs = new Comm::ConnOpener(connection, connector, TheConfig.connect_timeout(service().cfg().bypass));
+ cs->setHost(s.cfg().host.termedBuf());
+ AsyncJob::AsyncStart(cs);
}
/*
void Adaptation::Icap::Xaction::scheduleWrite(MemBuf &buf)
{
+ Must(haveConnection());
+
// comm module will free the buffer
typedef CommCbMemFunT<Adaptation::Icap::Xaction, CommIoCbParams> Dialer;
- writer = asyncCall(93,3, "Adaptation::Icap::Xaction::noteCommWrote",
- Dialer(this, &Adaptation::Icap::Xaction::noteCommWrote));
- writer = JobCallback(93,3,
- Dialer, this, Adaptation::Icap::Xaction::noteCommWrote);
--
- comm_write_mbuf(connection, &buf, writer);
++ writer = JobCallback(93, 3, Dialer, this, Adaptation::Icap::Xaction::noteCommWrote);
+ comm_write_mbuf(connection->fd, &buf, writer);
updateTimeout();
}
// XXX: why does Config.Timeout lacks a write timeout?
// TODO: service bypass status may differ from that of a transaction
typedef CommCbMemFunT<Adaptation::Icap::Xaction, CommTimeoutCbParams> TimeoutDialer;
- AsyncCall::Pointer call = asyncCall(93, 5, "Adaptation::Icap::Xaction::noteCommTimedout",
- TimeoutDialer(this,&Adaptation::Icap::Xaction::noteCommTimedout));
- AsyncCall::Pointer call = JobCallback(93,5,
- TimeoutDialer, this, Adaptation::Icap::Xaction::noteCommTimedout);
--
- commSetTimeout(connection->fd,
- commSetTimeout(connection,
-- TheConfig.io_timeout(service().cfg().bypass), call);
++ AsyncCall::Pointer call = JobCallback(93, 5, TimeoutDialer, this, Adaptation::Icap::Xaction::noteCommTimedout);
++ commSetTimeout(connection->fd, TheConfig.io_timeout(service().cfg().bypass), call);
} else {
// clear timeout when there is no I/O
// Do we need a lifetime timeout?
* here instead of reading directly into readBuf.buf.
*/
typedef CommCbMemFunT<Adaptation::Icap::Xaction, CommIoCbParams> Dialer;
- reader = asyncCall(93,3, "Adaptation::Icap::Xaction::noteCommRead",
- Dialer(this, &Adaptation::Icap::Xaction::noteCommRead));
- reader = JobCallback(93,3,
- Dialer, this, Adaptation::Icap::Xaction::noteCommRead);
--
- comm_read(connection, commBuf, readBuf.spaceSize(), reader);
++ reader = JobCallback(93, 3, Dialer, this, Adaptation::Icap::Xaction::noteCommRead);
+ comm_read(connection->fd, commBuf, readBuf.spaceSize(), reader);
updateTimeout();
}
AsyncJob::~AsyncJob()
{
+ debugs(93,3, "AsyncJob of type " << typeName << " destructed, this=" << this <<
+ " [async" << id << ']');
}
- void AsyncJob::noteStart()
- {
- start();
- }
-
void AsyncJob::start()
{
}
makeSpaceAvailable();
typedef CommCbMemFunT<ConnStateData, CommIoCbParams> Dialer;
- reader = asyncCall(33, 5, "ConnStateData::clientReadRequest",
- Dialer(this, &ConnStateData::clientReadRequest));
- reader = JobCallback(33, 5,
- Dialer, this, ConnStateData::clientReadRequest);
- comm_read(fd, in.addressToReadInto(), getAvailableBufferLength(), reader);
++ reader = JobCallback(33, 5, Dialer, this, ConnStateData::clientReadRequest);
+ comm_read(clientConn->fd, in.addressToReadInto(), getAvailableBufferLength(), reader);
}
* Set the timeout BEFORE calling clientReadRequest().
*/
typedef CommCbMemFunT<ConnStateData, CommTimeoutCbParams> TimeoutDialer;
- AsyncCall::Pointer timeoutCall = asyncCall(33, 5, "ConnStateData::requestTimeout",
- TimeoutDialer(this, &ConnStateData::requestTimeout));
+ AsyncCall::Pointer timeoutCall = JobCallback(33, 5,
+ TimeoutDialer, this, ConnStateData::requestTimeout);
- commSetTimeout(fd, Config.Timeout.persistent_request, timeoutCall);
+ commSetTimeout(clientConn->fd, Config.Timeout.persistent_request, timeoutCall);
readSomeData();
/** Please don't do anything with the FD past here! */
return;
}
- debugs(33, 4, "httpAccept: FD " << newfd << ": accepted");
- fd_note(newfd, "client http connect");
- connState = connStateCreate(&details->peer, &details->me, newfd, s);
+ debugs(33, 4, HERE << details << ": accepted");
+ fd_note(details->fd, "client http connect");
+ connState = connStateCreate(details, s);
typedef CommCbMemFunT<ConnStateData, CommCloseCbParams> Dialer;
- AsyncCall::Pointer call = asyncCall(33, 5, "ConnStateData::connStateClosed",
- Dialer(connState, &ConnStateData::connStateClosed));
- AsyncCall::Pointer call = JobCallback(33, 5,
- Dialer, connState, ConnStateData::connStateClosed);
- comm_add_close_handler(newfd, call);
++ AsyncCall::Pointer call = JobCallback(33, 5, Dialer, connState, ConnStateData::connStateClosed);
+ comm_add_close_handler(details->fd, call);
if (Config.onoff.log_fqdn)
- fqdncache_gethostbyaddr(details->peer, FQDN_LOOKUP_IF_MISS);
+ fqdncache_gethostbyaddr(details->remote, FQDN_LOOKUP_IF_MISS);
typedef CommCbMemFunT<ConnStateData, CommTimeoutCbParams> TimeoutDialer;
- AsyncCall::Pointer timeoutCall = asyncCall(33, 5, "ConnStateData::requestTimeout",
- TimeoutDialer(connState,&ConnStateData::requestTimeout));
+ AsyncCall::Pointer timeoutCall = JobCallback(33, 5,
+ TimeoutDialer, connState, ConnStateData::requestTimeout);
- commSetTimeout(newfd, Config.Timeout.read, timeoutCall);
+ commSetTimeout(details->fd, Config.Timeout.read, timeoutCall);
#if USE_IDENT
if (Ident::TheConfig.identLookup) {
}
SSL *ssl = NULL;
- if (!(ssl = httpsCreate(newfd, details, sslContext)))
+ if (!(ssl = httpsCreate(details, sslContext)))
return;
- debugs(33, 5, "httpsAccept: FD " << newfd << " accepted, starting SSL negotiation.");
- fd_note(newfd, "client https connect");
- ConnStateData *connState = connStateCreate(details->peer, details->me,
- newfd, &s->http);
+ debugs(33, 5, HERE << details << " accepted, starting SSL negotiation.");
+ fd_note(details->fd, "client https connect");
+ ConnStateData *connState = connStateCreate(details, &s->http);
typedef CommCbMemFunT<ConnStateData, CommCloseCbParams> Dialer;
- AsyncCall::Pointer call = asyncCall(33, 5, "ConnStateData::connStateClosed",
- Dialer(connState, &ConnStateData::connStateClosed));
- AsyncCall::Pointer call = JobCallback(33, 5,
- Dialer, connState, ConnStateData::connStateClosed);
- comm_add_close_handler(newfd, call);
++ AsyncCall::Pointer call = JobCallback(33, 5, Dialer, connState, ConnStateData::connStateClosed);
+ comm_add_close_handler(details->fd, call);
if (Config.onoff.log_fqdn)
- fqdncache_gethostbyaddr(details->peer, FQDN_LOOKUP_IF_MISS);
+ fqdncache_gethostbyaddr(details->remote, FQDN_LOOKUP_IF_MISS);
typedef CommCbMemFunT<ConnStateData, CommTimeoutCbParams> TimeoutDialer;
- AsyncCall::Pointer timeoutCall = asyncCall(33, 5, "ConnStateData::requestTimeout",
- TimeoutDialer(connState,&ConnStateData::requestTimeout));
+ AsyncCall::Pointer timeoutCall = JobCallback(33, 5,
+ TimeoutDialer, connState, ConnStateData::requestTimeout);
- commSetTimeout(newfd, Config.Timeout.request, timeoutCall);
+ commSetTimeout(details->fd, Config.Timeout.request, timeoutCall);
#if USE_IDENT
if (Ident::TheConfig.identLookup) {
flags.rest_supported = 1;
typedef CommCbMemFunT<FtpStateData, CommCloseCbParams> Dialer;
- AsyncCall::Pointer closer = asyncCall(9, 5, "FtpStateData::ctrlClosed",
- Dialer(this, &FtpStateData::ctrlClosed));
- AsyncCall::Pointer closer = JobCallback(9, 5,
- Dialer, this, FtpStateData::ctrlClosed);
- ctrl.opened(theFwdState->server_fd, closer);
++ AsyncCall::Pointer closer = JobCallback(9, 5, Dialer, this, FtpStateData::ctrlClosed);
+ ctrl.opened(conn, closer);
if (request->method == METHOD_PUT)
flags.put = 1;
debugs(9, 9, HERE << ": OUT: login='" << login << "', escaped=" << escaped << ", user=" << user << ", password=" << password);
}
- AsyncCall::Pointer timeoutCall = asyncCall(9, 5, "FtpStateData::ftpTimeout",
- TimeoutDialer(this, &FtpStateData::ftpTimeout));
+/**
+ * Cancel the timeout on the Control socket and establish one
+ * on the data socket
+ */
+void
+FtpStateData::switchTimeoutToDataChannel()
+{
+ AsyncCall::Pointer nullCall = NULL;
+ commSetTimeout(ctrl.conn->fd, -1, nullCall);
+
+ typedef CommCbMemFunT<FtpStateData, CommTimeoutCbParams> TimeoutDialer;
++ AsyncCall::Pointer timeoutCall = JobCallback(9, 5, TimeoutDialer, this, FtpStateData::ftpTimeout);
+ commSetTimeout(data.conn->fd, Config.Timeout.read, timeoutCall);
+}
+
void
FtpStateData::ftpTimeout(const CommTimeoutCbParams &io)
{
data.read_pending = true;
typedef CommCbMemFunT<FtpStateData, CommTimeoutCbParams> TimeoutDialer;
- AsyncCall::Pointer timeoutCall = asyncCall(9, 5, "FtpStateData::ftpTimeout",
- TimeoutDialer(this,&FtpStateData::ftpTimeout));
+ AsyncCall::Pointer timeoutCall = JobCallback(9, 5,
+ TimeoutDialer, this, FtpStateData::ftpTimeout);
- commSetTimeout(data.fd, Config.Timeout.read, timeoutCall);
+ commSetTimeout(data.conn->fd, Config.Timeout.read, timeoutCall);
- debugs(9,5,HERE << "queueing read on FD " << data.fd);
+ debugs(9,5,HERE << "queueing read on FD " << data.conn->fd);
typedef CommCbMemFunT<FtpStateData, CommIoCbParams> Dialer;
- entry->delayAwareRead(data.fd, data.readBuf->space(), read_sz,
+ entry->delayAwareRead(data.conn->fd, data.readBuf->space(), read_sz,
- asyncCall(9, 5, "FtpStateData::dataRead",
- Dialer(this, &FtpStateData::dataRead)));
+ JobCallback(9, 5, Dialer, this, FtpStateData::dataRead));
}
void
}
typedef CommCbMemFunT<FtpStateData, CommIoCbParams> Dialer;
- AsyncCall::Pointer call = asyncCall(9, 5, "FtpStateData::ftpWriteCommandCallback",
- Dialer(this, &FtpStateData::ftpWriteCommandCallback));
- AsyncCall::Pointer call = JobCallback(9, 5,
- Dialer, this, FtpStateData::ftpWriteCommandCallback);
- comm_write(ctrl.fd,
++ AsyncCall::Pointer call = JobCallback(9, 5, Dialer, this, FtpStateData::ftpWriteCommandCallback);
+ comm_write(ctrl.conn->fd,
ctrl.last_command,
strlen(ctrl.last_command),
call);
}
typedef CommCbMemFunT<FtpStateData, CommTimeoutCbParams> TimeoutDialer;
- AsyncCall::Pointer timeoutCall = asyncCall(9, 5, "FtpStateData::ftpTimeout",
- TimeoutDialer(this,&FtpStateData::ftpTimeout));
-
- AsyncCall::Pointer timeoutCall = JobCallback(9, 5,
- TimeoutDialer, this, FtpStateData::ftpTimeout);
++ AsyncCall::Pointer timeoutCall = JobCallback(9, 5, TimeoutDialer, this, FtpStateData::ftpTimeout);
+ commSetTimeout(ctrl.conn->fd, Config.Timeout.read, timeoutCall);
- commSetTimeout(ctrl.fd, Config.Timeout.read, timeoutCall);
+ typedef CommCbMemFunT<FtpStateData, CommIoCbParams> Dialer;
- AsyncCall::Pointer reader=asyncCall(9, 5, "FtpStateData::ftpReadControlReply",
- Dialer(this, &FtpStateData::ftpReadControlReply));
++ AsyncCall::Pointer reader = JobCallback(9, 5, Dialer, this, FtpStateData::ftpReadControlReply);
+ comm_read(ctrl.conn->fd, ctrl.buf + ctrl.offset, ctrl.size - ctrl.offset, reader);
}
}
/*
* ugly hack for ftp servers like ftp.netscape.com that sometimes
- * dont acknowledge PASV commands.
+ * dont acknowledge PASV commands. Use connect timeout to be faster then read timeout (minutes).
*/
typedef CommCbMemFunT<FtpStateData, CommTimeoutCbParams> TimeoutDialer;
- AsyncCall::Pointer timeoutCall = asyncCall(9, 5, "FtpStateData::ftpTimeout",
- TimeoutDialer(ftpState,&FtpStateData::ftpTimeout));
+ AsyncCall::Pointer timeoutCall = JobCallback(9, 5,
+ TimeoutDialer, ftpState, FtpStateData::ftpTimeout);
- commSetTimeout(ftpState->data.fd, 15, timeoutCall);
+ commSetTimeout(ftpState->ctrl.conn->fd, Config.Timeout.connect, timeoutCall);
}
void
}
typedef CommCbMemFunT<FtpStateData, CommAcceptCbParams> acceptDialer;
- AsyncCall::Pointer acceptCall = asyncCall(11, 5, "FtpStateData::ftpAcceptDataConnection",
- acceptDialer(ftpState, &FtpStateData::ftpAcceptDataConnection));
- AsyncCall::Pointer acceptCall = JobCallback(11, 5,
- acceptDialer, ftpState, FtpStateData::ftpAcceptDataConnection);
- ftpState->data.listener = new Comm::ListenStateData(fd, acceptCall, false);
++ AsyncCall::Pointer acceptCall = JobCallback(11, 5, acceptDialer, ftpState, FtpStateData::ftpAcceptDataConnection);
+ ftpState->data.listener = new Comm::ConnAcceptor(conn, false, ftpState->entry->url());
+ ftpState->data.listener->subscribe(acceptCall);
- if (!ftpState->data.listener || ftpState->data.listener->errcode != 0) {
- comm_close(fd);
- return -1;
+ if (ftpState->data.listener->errcode != 0) {
+ conn->close();
+ } else {
+
+ if (!fallback)
+ conn->local.SetPort(comm_local_port(conn->fd));
+ ftpState->data.host = NULL;
+ AsyncJob::AsyncStart(ftpState->data.listener);
}
- ftpState->data.opened(fd, ftpState->dataCloser());
- ftpState->data.port = comm_local_port(fd);
- ftpState->data.host = NULL;
- return fd;
+ ftpState->data.listen_conn = conn;
}
/// \ingroup ServerProtocolFTPInternal
* This prevents third-party hacks, but also third-party load balancing handshakes.
*/
if (Config.Ftp.sanitycheck) {
- io.details.peer.NtoA(ntoapeer,MAX_IPSTRLEN);
+ io.details->remote.NtoA(ntoapeer,MAX_IPSTRLEN);
- if (strcmp(fd_table[ctrl.fd].ipaddr, ntoapeer) != 0) {
+ // accept if either our data or ctrl connection is talking to this remote peer.
+ if (data.listen_conn->remote != io.details->remote && ctrl.conn->remote != io.details->remote) {
debugs(9, DBG_IMPORTANT,
"FTP data connection from unexpected server (" <<
- io.details.peer << "), expecting " <<
- fd_table[ctrl.fd].ipaddr);
+ io.details->remote << "), expecting " <<
+ data.listen_conn->remote << " or " << ctrl.conn->remote);
- /* close the bad soures connection down ASAP. */
- comm_close(io.nfd);
+ /* drop the bad connection (io) by ignoring. */
- /* we are ony accepting once, so need to re-open the listener socket. */
+ /* we are ony accepting once, so need to reset the listener socket. */
typedef CommCbMemFunT<FtpStateData, CommAcceptCbParams> acceptDialer;
- AsyncCall::Pointer acceptCall = asyncCall(11, 5, "FtpStateData::ftpAcceptDataConnection",
- acceptDialer(this, &FtpStateData::ftpAcceptDataConnection));
- AsyncCall::Pointer acceptCall = JobCallback(11, 5,
- acceptDialer, this, FtpStateData::ftpAcceptDataConnection);
- data.listener = new Comm::ListenStateData(data.fd, acceptCall, false);
++ AsyncCall::Pointer acceptCall = JobCallback(11, 5, acceptDialer, this, FtpStateData::ftpAcceptDataConnection);
+ data.listener = new Comm::ConnAcceptor(data.listen_conn, false, data.host);
+ data.listener->subscribe(acceptCall);
+ AsyncJob::AsyncStart(data.listener);
return;
}
}
state = WRITING_DATA;
debugs(9, 3, HERE << "writing data channel");
} else if (code == 150) {
- /*\par
- * When client code is 150 with a hostname, Accept data channel. */
+ /* When client code is 150 with no data channel, Accept data channel. */
debugs(9, 3, "ftpReadStor: accepting data channel");
typedef CommCbMemFunT<FtpStateData, CommAcceptCbParams> acceptDialer;
- AsyncCall::Pointer acceptCall = asyncCall(11, 5, "FtpStateData::ftpAcceptDataConnection",
- acceptDialer(this, &FtpStateData::ftpAcceptDataConnection));
+ AsyncCall::Pointer acceptCall = JobCallback(11, 5,
+ acceptDialer, this, FtpStateData::ftpAcceptDataConnection);
- data.listener = new Comm::ListenStateData(data.fd, acceptCall, false);
+ data.listener = new Comm::ConnAcceptor(data.conn, false, data.host);
+ data.listener->subscribe(acceptCall);
+ AsyncJob::AsyncStart(data.listener);
} else {
debugs(9, DBG_IMPORTANT, HERE << "Unexpected reply code "<< std::setfill('0') << std::setw(3) << code);
ftpFail(this);
int code = ftpState->ctrl.replycode;
debugs(9, 3, HERE);
- if (code == 125 || (code == 150 && ftpState->data.host)) {
+ if (code == 125 || (code == 150 && Comm::IsConnOpen(ftpState->data.conn))) {
+ debugs(9, 3, HERE << "begin data transfer from " << ftpState->data.conn->remote);
/* Begin data transfer */
- /* XXX what about Config.Timeout.read? */
+ ftpState->switchTimeoutToDataChannel();
ftpState->maybeReadVirginBody();
ftpState->state = READING_DATA;
- /*
- * Cancel the timeout on the Control socket and establish one
- * on the data socket
- */
- AsyncCall::Pointer nullCall = NULL;
- commSetTimeout(ftpState->ctrl.fd, -1, nullCall);
return;
} else if (code == 150) {
+ debugs(9, 3, HERE << "accept data channel from " << ftpState->ctrl.conn->remote);
+ ftpState->switchTimeoutToDataChannel();
+
/* Accept data channel */
typedef CommCbMemFunT<FtpStateData, CommAcceptCbParams> acceptDialer;
- AsyncCall::Pointer acceptCall = asyncCall(11, 5, "FtpStateData::ftpAcceptDataConnection",
- acceptDialer(ftpState, &FtpStateData::ftpAcceptDataConnection));
+ AsyncCall::Pointer acceptCall = JobCallback(11, 5,
+ acceptDialer, ftpState, FtpStateData::ftpAcceptDataConnection);
- ftpState->data.listener = new Comm::ListenStateData(ftpState->data.fd, acceptCall, false);
- /*
- * Cancel the timeout on the Control socket and establish one
- * on the data socket
- */
- AsyncCall::Pointer nullCall = NULL;
- commSetTimeout(ftpState->ctrl.fd, -1, nullCall);
-
- typedef CommCbMemFunT<FtpStateData, CommTimeoutCbParams> TimeoutDialer;
- AsyncCall::Pointer timeoutCall = JobCallback(9, 5,
- TimeoutDialer, ftpState,FtpStateData::ftpTimeout);
- commSetTimeout(ftpState->data.fd, Config.Timeout.read, timeoutCall);
+ ftpState->data.listener = new Comm::ConnAcceptor(ftpState->data.conn, false, ftpState->data.host);
+ ftpState->data.listener->subscribe(acceptCall);
+ AsyncJob::AsyncStart(ftpState->data.listener);
return;
} else if (!ftpState->flags.tried_nlst && code > 300) {
ftpSendNlst(ftpState);
int code = ftpState->ctrl.replycode;
debugs(9, 3, HERE);
- if (code == 125 || (code == 150 && ftpState->data.host)) {
+ if (code == 125 || (code == 150 && Comm::IsConnOpen(ftpState->data.conn))) {
/* Begin data transfer */
debugs(9, 3, HERE << "reading data channel");
- /* XXX what about Config.Timeout.read? */
+ ftpState->switchTimeoutToDataChannel();
ftpState->maybeReadVirginBody();
ftpState->state = READING_DATA;
- /*
- * Cancel the timeout on the Control socket and establish one
- * on the data socket
- */
- AsyncCall::Pointer nullCall = NULL;
- commSetTimeout(ftpState->ctrl.fd, -1, nullCall);
} else if (code == 150) {
/* Accept data channel */
+ ftpState->switchTimeoutToDataChannel();
typedef CommCbMemFunT<FtpStateData, CommAcceptCbParams> acceptDialer;
- AsyncCall::Pointer acceptCall = asyncCall(11, 5, "FtpStateData::ftpAcceptDataConnection",
- acceptDialer(ftpState, &FtpStateData::ftpAcceptDataConnection));
+ AsyncCall::Pointer acceptCall = JobCallback(11, 5,
+ acceptDialer, ftpState, FtpStateData::ftpAcceptDataConnection);
- ftpState->data.listener = new Comm::ListenStateData(ftpState->data.fd, acceptCall, false);
- /*
- * Cancel the timeout on the Control socket and establish one
- * on the data socket
- */
- AsyncCall::Pointer nullCall = NULL;
- commSetTimeout(ftpState->ctrl.fd, -1, nullCall);
-
- typedef CommCbMemFunT<FtpStateData, CommTimeoutCbParams> TimeoutDialer;
- AsyncCall::Pointer timeoutCall = JobCallback(9, 5,
- TimeoutDialer, ftpState,FtpStateData::ftpTimeout);
- commSetTimeout(ftpState->data.fd, Config.Timeout.read, timeoutCall);
+ ftpState->data.listener = new Comm::ConnAcceptor(ftpState->data.conn, false, ftpState->data.host);
+ ftpState->data.listener->subscribe(acceptCall);
+ AsyncJob::AsyncStart(ftpState->data.listener);
} else if (code >= 300) {
if (!ftpState->flags.try_slash_hack) {
/* Try this as a directory missing trailing slash... */
* register the handler to free HTTP state data when the FD closes
*/
typedef CommCbMemFunT<HttpStateData, CommCloseCbParams> Dialer;
- closeHandler = asyncCall(9, 5, "httpStateData::httpStateConnClosed",
- Dialer(this,&HttpStateData::httpStateConnClosed));
- closeHandler = JobCallback(9, 5,
- Dialer, this, HttpStateData::httpStateConnClosed);
- comm_add_close_handler(fd, closeHandler);
++ closeHandler = JobCallback(9, 5, Dialer, this, HttpStateData::httpStateConnClosed);
+ comm_add_close_handler(serverConnection->fd, closeHandler);
}
HttpStateData::~HttpStateData()
if (flags.do_next_read) {
flags.do_next_read = 0;
typedef CommCbMemFunT<HttpStateData, CommIoCbParams> Dialer;
- entry->delayAwareRead(fd, readBuf->space(read_size), read_size,
+ entry->delayAwareRead(serverConnection->fd, readBuf->space(read_size), read_size,
- asyncCall(11, 5, "HttpStateData::readReply",
- Dialer(this, &HttpStateData::readReply)));
+ JobCallback(11, 5, Dialer, this, HttpStateData::readReply));
}
}
* request bodies.
*/
typedef CommCbMemFunT<HttpStateData, CommTimeoutCbParams> TimeoutDialer;
- AsyncCall::Pointer timeoutCall = asyncCall(11, 5, "HttpStateData::httpTimeout",
- TimeoutDialer(this,&HttpStateData::httpTimeout));
+ AsyncCall::Pointer timeoutCall = JobCallback(11, 5,
+ TimeoutDialer, this, HttpStateData::httpTimeout);
- commSetTimeout(fd, Config.Timeout.read, timeoutCall);
+ commSetTimeout(serverConnection->fd, Config.Timeout.read, timeoutCall);
flags.request_sent = 1;
}
typedef CommCbMemFunT<HttpStateData, CommTimeoutCbParams> TimeoutDialer;
- AsyncCall::Pointer timeoutCall = asyncCall(11, 5, "HttpStateData::httpTimeout",
- TimeoutDialer(this,&HttpStateData::httpTimeout));
- commSetTimeout(serverConnection->fd, Config.Timeout.lifetime, timeoutCall);
+ AsyncCall::Pointer timeoutCall = JobCallback(11, 5,
+ TimeoutDialer, this, HttpStateData::httpTimeout);
- commSetTimeout(fd, Config.Timeout.lifetime, timeoutCall);
++ commSetTimeout(srverConnection->fd, Config.Timeout.lifetime, timeoutCall);
flags.do_next_read = 1;
maybeReadVirginBody();
}
typedef CommCbMemFunT<HttpStateData, CommIoCbParams> Dialer;
- Dialer dialer(this, &HttpStateData::sendComplete);
- AsyncCall::Pointer call= asyncCall(11,5, "HttpStateData::SendComplete", dialer);
- AsyncCall::Pointer call = JobCallback(11,5,
- Dialer, this, HttpStateData::sendComplete);
- comm_write(fd, "\r\n", 2, call);
++ AsyncCall::Pointer call = JobCallback(11, 5, Dialer, this, HttpStateData::sendComplete);
+ comm_write(serverConnection->fd, "\r\n", 2, call);
}
return;
}
debugs(26, 3, "tunnelStart: '" << RequestMethodStr(request->method) << " " << url << "'");
statCounter.server.all.requests++;
statCounter.server.other.requests++;
- /* Create socket. */
- Ip::Address temp = getOutgoingAddr(request,NULL);
-
- // if IPv6 is disabled try to force IPv4-only outgoing.
- if (!Ip::EnableIpv6 && !temp.SetIPv4()) {
- debugs(50, 4, "tunnelStart: IPv6 is Disabled. Tunnel failed from " << temp);
- ErrorState *anErr = errorCon(ERR_CONNECT_FAIL, HTTP_SERVICE_UNAVAILABLE, request);
- anErr->xerrno = EAFNOSUPPORT;
- errorSend(fd, anErr);
- return;
- }
-
- // if IPv6 is split-stack, prefer IPv4
- if (Ip::EnableIpv6&IPV6_SPECIAL_SPLITSTACK) {
- // NP: This is not a great choice of default,
- // but with the current Internet being IPv4-majority has a higher success rate.
- // if setting to IPv4 fails we dont care, that just means to use IPv6 outgoing.
- temp.SetIPv4();
- }
-
- int flags = COMM_NONBLOCKING;
- if (request->flags.spoof_client_ip) {
- flags |= COMM_TRANSPARENT;
- }
- sock = comm_openex(SOCK_STREAM,
- IPPROTO_TCP,
- temp,
- flags,
- getOutgoingTOS(request),
- url);
-
- if (sock == COMM_ERROR) {
- debugs(26, 4, "tunnelStart: Failed because we're out of sockets.");
- err = errorCon(ERR_SOCKET_FAILURE, HTTP_INTERNAL_SERVER_ERROR, request);
- *status_ptr = HTTP_INTERNAL_SERVER_ERROR;
- err->xerrno = errno;
- errorSend(fd, err);
- return;
- }
+ request->hier.peer_local_port = comm_local_port(sock); // for %<lp logging
+
tunnelState = new TunnelStateData;
#if DELAY_POOLS
-
tunnelState->server.setDelayId(DelayId::DelayClient(http));
#endif
-
tunnelState->url = xstrdup(url);
tunnelState->request = HTTPMSGLOCK(request);
tunnelState->server.size_ptr = size_ptr;