diff -Naurp squid-3.3.8.orig/src/ipc/TypedMsgHdr.cc squid-3.3.8/src/ipc/TypedMsgHdr.cc --- squid-3.3.8.orig/src/ipc/TypedMsgHdr.cc 2013-07-13 15:25:14.000000000 +0200 +++ squid-3.3.8/src/ipc/TypedMsgHdr.cc 2015-04-20 14:28:32.971000390 +0200 @@ -167,10 +167,20 @@ Ipc::TypedMsgHdr::putRaw(const void *raw } } +bool +Ipc::TypedMsgHdr::hasFd() const +{ + struct cmsghdr *cmsg = CMSG_FIRSTHDR(this); + return cmsg && + cmsg->cmsg_level == SOL_SOCKET && + cmsg->cmsg_type == SCM_RIGHTS; +} + void Ipc::TypedMsgHdr::putFd(int fd) { Must(fd >= 0); + Must(!hasFd()); allocControl(); const int fdCount = 1; @@ -183,12 +193,15 @@ Ipc::TypedMsgHdr::putFd(int fd) int *fdStore = reinterpret_cast(CMSG_DATA(cmsg)); memcpy(fdStore, &fd, fdCount * sizeof(int)); msg_controllen = cmsg->cmsg_len; + + Must(hasFd()); } int Ipc::TypedMsgHdr::getFd() const { Must(msg_control && msg_controllen); + Must(hasFd()); struct cmsghdr *cmsg = CMSG_FIRSTHDR(this); Must(cmsg->cmsg_level == SOL_SOCKET); diff -Naurp squid-3.3.8.orig/src/ipc/TypedMsgHdr.h squid-3.3.8/src/ipc/TypedMsgHdr.h --- squid-3.3.8.orig/src/ipc/TypedMsgHdr.h 2013-07-13 15:25:14.000000000 +0200 +++ squid-3.3.8/src/ipc/TypedMsgHdr.h 2015-04-20 14:12:57.509303004 +0200 @@ -59,8 +59,8 @@ public: /* access to a "file" descriptor that can be passed between processes */ void putFd(int aFd); ///< stores descriptor - int getFd() const; ///< returns descriptor - + int getFd() const; ///< returns stored descriptor + bool hasFd() const; ///< whether the message has a descriptor stored /* raw, type-independent access for I/O */ void prepForReading(); ///< reset and provide all buffers char *raw() { return reinterpret_cast(this); } diff -Naurp squid-3.3.8.orig/src/snmp/Inquirer.cc squid-3.3.8/src/snmp/Inquirer.cc --- squid-3.3.8.orig/src/snmp/Inquirer.cc 2013-07-13 15:25:14.000000000 +0200 +++ squid-3.3.8/src/snmp/Inquirer.cc 2015-04-20 14:15:12.324970907 +0200 @@ -28,6 +28,10 @@ Snmp::Inquirer::Inquirer(const Request& closer = asyncCall(49, 5, "Snmp::Inquirer::noteCommClosed", CommCbMemFunT(this, &Inquirer::noteCommClosed)); comm_add_close_handler(conn->fd, closer); + + // forget client FD to avoid sending it to strands that may forget to close + if (Request *snmpRequest = dynamic_cast(request.getRaw())) + snmpRequest->fd = -1; } /// closes our copy of the client connection socket diff -Naurp squid-3.3.8.orig/src/snmp/Request.cc squid-3.3.8/src/snmp/Request.cc --- squid-3.3.8.orig/src/snmp/Request.cc 2013-07-13 15:25:14.000000000 +0200 +++ squid-3.3.8/src/snmp/Request.cc 2015-04-20 14:21:16.676074181 +0200 @@ -33,7 +33,8 @@ Snmp::Request::Request(const Ipc::TypedM session.unpack(msg); msg.getPod(address); - fd = msg.getFd(); + // Requests from strands have FDs. Requests from Coordinator do not. + fd = msg.hasFd() ? msg.getFd() : -1; } void @@ -46,7 +47,9 @@ Snmp::Request::pack(Ipc::TypedMsgHdr& ms session.pack(msg); msg.putPod(address); - msg.putFd(fd); + // Requests sent to Coordinator have FDs. Requests sent to strands do not. + if (fd >= 0) + msg.putFd(fd); } Ipc::Request::Pointer