Blame SOURCES/squid-3.3.8-fd-leaks.patch

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