From: Christos Tsantilas Date: Fri, 17 Jun 2016 17:37:22 +0000 (+0300) Subject: Assertion failed: Write.cc:38: "fd_table[conn->fd].flags.open" X-Git-Tag: SQUID_4_0_12~13 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4309d5071889f0abe9a2ff4067b7b4ac0c28b1ed;p=thirdparty%2Fsquid.git Assertion failed: Write.cc:38: "fd_table[conn->fd].flags.open" The Ftp::Server::stopWaitingForOrigin() notification may come after Ftp::Server (or an external force) has started closing the control connection but before the Ftp::Server job became unreachable for notifications. Writing a response in this state leads to assertions. Other, currently unknown paths may lead to the same write-after-close problems. This change protects all asynchronous notification methods (except the connection closure handler itself) from exposing underlying code to a closing control connection. This is very similar to checking for ERR_CLOSING in Comm handlers. This is a Measurement Factory project. --- diff --git a/src/servers/FtpServer.cc b/src/servers/FtpServer.cc index 5728ca32cf..2ac9f19987 100644 --- a/src/servers/FtpServer.cc +++ b/src/servers/FtpServer.cc @@ -220,12 +220,18 @@ Ftp::Server::shovelUploadData() void Ftp::Server::noteMoreBodySpaceAvailable(BodyPipe::Pointer) { + if (!isOpen()) // if we are closing, nothing to do + return; + shovelUploadData(); } void Ftp::Server::noteBodyConsumerAborted(BodyPipe::Pointer ptr) { + if (!isOpen()) // if we are closing, nothing to do + return; + ConnStateData::noteBodyConsumerAborted(ptr); closeDataConnection(); } @@ -1731,6 +1737,9 @@ Ftp::Server::callException(const std::exception &e) void Ftp::Server::startWaitingForOrigin() { + if (!isOpen()) // if we are closing, nothing to do + return; + debugs(33, 5, "waiting for Ftp::Client data transfer to end"); waitingForOrigin = true; } @@ -1741,6 +1750,9 @@ Ftp::Server::stopWaitingForOrigin(int originStatus) Must(waitingForOrigin); waitingForOrigin = false; + if (!isOpen()) // if we are closing, nothing to do + return; + // if we have already decided how to respond, respond now if (delayedReply) { HttpReply::Pointer reply = delayedReply;