void
FwdState::establishTunnelThruProxy(const Comm::ConnectionPointer &conn)
{
- assert(!httpConnectWait);
-
AsyncCall::Pointer callback = asyncCall(17,4,
"FwdState::tunnelEstablishmentDone",
Http::Tunneler::CbDialer<FwdState>(&FwdState::tunnelEstablishmentDone, this));
void
FwdState::secureConnectionToPeer(const Comm::ConnectionPointer &conn)
{
- assert(!encryptionWait);
HttpRequest::Pointer requestPointer = request;
AsyncCall::Pointer callback = asyncCall(17,4,
"FwdState::ConnectedToPeer",
Must(!request->pinnedConnection());
assert(!destinations->empty());
- assert(!tcpConnWait);
assert(!usingDestination());
// Ditch error page if it was created before.
void
PeerPoolMgr::handleOpenedConnection(const CommConnectCbParams ¶ms)
{
- assert(connWait);
connWait.finish();
if (!validPeer()) {
void
PeerPoolMgr::handleSecuredPeer(Security::EncryptorAnswer &answer)
{
- assert(encryptionWait);
encryptionWait.finish();
if (closer != NULL) {
/// called when the connection attempt to an ICAP service completes (successfully or not)
void Adaptation::Icap::Xaction::noteCommConnected(const CommConnectCbParams &io)
{
- assert(connWait);
connWait.finish();
if (io.flag == Comm::TIMEOUT) {
void
Adaptation::Icap::Xaction::handleSecuredPeer(Security::EncryptorAnswer &answer)
{
- Must(encryptionWait);
encryptionWait.finish();
if (closer != NULL) {
/// starts waiting for the given job to call the given callback
void start(JobPointer, AsyncCall::Pointer);
- /// ends wait (if any) after receiving the call back
+ /// ends wait (after receiving the call back)
/// forgets the job which is likely to be gone by now
- /// does nothing if we are not waiting (TODO: assert that we are waiting)
- void finish() { clear(); }
+ void finish();
/// aborts wait (if any) before receiving the call back
/// does nothing if we are not waiting
assert(aCall);
assert(aJob.valid());
- // TODO: Should we also assert !callback_ and !job_?
+ // "Double" waiting state leads to conflicting/mismatching callbacks
+ // detailed in finish(). Detect that bug ASAP.
+ assert(!waiting());
+ assert(!callback_);
+ assert(!job_);
callback_ = aCall;
job_ = aJob;
}
+template<class Job>
+void
+JobWait<Job>::finish()
+{
+ // Unexpected callbacks might result in disasters like secrets exposure,
+ // data corruption, or expensive message routing mistakes when the callback
+ // info is applied to the wrong message part or acted upon prematurely.
+ assert(waiting());
+ clear();
+}
+
template<class Job>
void
JobWait<Job>::cancel(const char *reason)
Ftp::Gateway::dataChannelConnected(const CommConnectCbParams &io)
{
debugs(9, 3, HERE);
- assert(dataConnWait);
dataConnWait.finish();
if (io.flag != Comm::OK) {
Ftp::Relay::dataChannelConnected(const CommConnectCbParams &io)
{
debugs(9, 3, status());
- assert(dataConnWait);
dataConnWait.finish();
if (io.flag != Comm::OK) {
void
Log::TcpLogger::connectDone(const CommConnectCbParams ¶ms)
{
- assert(connWait);
connWait.finish();
if (params.flag != Comm::OK) {
const Downloader *csd = (request ? dynamic_cast<const Downloader*>(request->downloader.valid()) : nullptr);
Downloader *dl = new Downloader(url, certCallback, XactionInitiator::initCertFetcher, csd ? csd->nestedLevel() + 1 : 1);
- assert(!certDownloadWait);
certDownloadWait.start(dl, certCallback);
AsyncJob::Start(dl);
}
void
Security::PeerConnector::certDownloadingDone(SBuf &obj, int downloadStatus)
{
- assert(certDownloadWait);
certDownloadWait.finish();
++certsDownloads;
void
Ftp::Server::connectedForData(const CommConnectCbParams ¶ms)
{
- assert(dataConnWait);
dataConnWait.finish();
if (params.flag != Comm::OK) {
static void
tunnelStartShoveling(TunnelStateData *tunnelState)
{
+ assert(!tunnelState->tcpConnWait);
+ assert(!tunnelState->encryptionWait);
assert(!tunnelState->httpConnectWait);
+
assert(tunnelState->server.conn);
AsyncCall::Pointer timeoutCall = commCbCall(5, 4, "tunnelTimeout",
CommTimeoutCbPtrFun(tunnelTimeout, tunnelState));
void
TunnelStateData::secureConnectionToPeer(const Comm::ConnectionPointer &conn)
{
- assert(!encryptionWait);
AsyncCall::Pointer callback = asyncCall(5,4, "TunnelStateData::noteSecurityPeerConnectorAnswer",
MyAnswerDialer(&TunnelStateData::noteSecurityPeerConnectorAnswer, this));
const auto connector = new Security::BlindPeerConnector(request, conn, callback, al);
void
TunnelStateData::establishTunnelThruProxy(const Comm::ConnectionPointer &conn)
{
- assert(!httpConnectWait);
-
AsyncCall::Pointer callback = asyncCall(5,4,
"TunnelStateData::tunnelEstablishmentDone",
Http::Tunneler::CbDialer<TunnelStateData>(&TunnelStateData::tunnelEstablishmentDone, this));
request->hier.startPeerClock();
assert(!destinations->empty());
- assert(!tcpConnWait);
assert(!usingDestination());
AsyncCall::Pointer callback = asyncCall(17, 5, "TunnelStateData::noteConnection", HappyConnOpener::CbDialer<TunnelStateData>(&TunnelStateData::noteConnection, this));
const auto cs = new HappyConnOpener(destinations, callback, request, startTime, 0, al);