Blame SOURCES/squid-4.11-active-ftp.patch

5e05d2
diff --git a/src/clients/FtpClient.cc b/src/clients/FtpClient.cc
818ced
index b665bcf..d287e55 100644
5e05d2
--- a/src/clients/FtpClient.cc
5e05d2
+++ b/src/clients/FtpClient.cc
5e05d2
@@ -778,7 +778,8 @@ Ftp::Client::connectDataChannel()
5e05d2
 bool
5e05d2
 Ftp::Client::openListenSocket()
5e05d2
 {
5e05d2
-    return false;
5e05d2
+    debugs(9, 3, HERE);
5e05d2
+	  return false;
5e05d2
 }
5e05d2
 
5e05d2
 /// creates a data channel Comm close callback
5e05d2
diff --git a/src/clients/FtpClient.h b/src/clients/FtpClient.h
818ced
index a76a5a0..218d696 100644
5e05d2
--- a/src/clients/FtpClient.h
5e05d2
+++ b/src/clients/FtpClient.h
5e05d2
@@ -118,7 +118,7 @@ public:
5e05d2
     bool sendPort();
5e05d2
     bool sendPassive();
5e05d2
     void connectDataChannel();
5e05d2
-    bool openListenSocket();
5e05d2
+    virtual bool openListenSocket();
5e05d2
     void switchTimeoutToDataChannel();
5e05d2
 
5e05d2
     CtrlChannel ctrl; ///< FTP control channel state
5e05d2
diff --git a/src/clients/FtpGateway.cc b/src/clients/FtpGateway.cc
818ced
index 411bce9..31d3e36 100644
5e05d2
--- a/src/clients/FtpGateway.cc
5e05d2
+++ b/src/clients/FtpGateway.cc
5e05d2
@@ -87,6 +87,13 @@ struct GatewayFlags {
5e05d2
 class Gateway;
5e05d2
 typedef void (StateMethod)(Ftp::Gateway *);
5e05d2
 
5e05d2
+} // namespace FTP
5e05d2
+
5e05d2
+static void ftpOpenListenSocket(Ftp::Gateway * ftpState, int fallback);
5e05d2
+
5e05d2
+namespace Ftp
5e05d2
+{
5e05d2
+
5e05d2
 /// FTP Gateway: An FTP client that takes an HTTP request with an ftp:// URI,
5e05d2
 /// converts it into one or more FTP commands, and then
5e05d2
 /// converts one or more FTP responses into the final HTTP response.
5e05d2
@@ -137,7 +144,11 @@ public:
5e05d2
 
5e05d2
     /// create a data channel acceptor and start listening.
5e05d2
     void listenForDataChannel(const Comm::ConnectionPointer &conn;;
5e05d2
-
5e05d2
+    virtual bool openListenSocket() {
5e05d2
+    		debugs(9, 3, HERE);
5e05d2
+				ftpOpenListenSocket(this, 0);
5e05d2
+        return Comm::IsConnOpen(data.conn);
5e05d2
+		}
5e05d2
     int checkAuth(const HttpHeader * req_hdr);
5e05d2
     void checkUrlpath();
5e05d2
     void buildTitleUrl();
818ced
@@ -1787,6 +1798,7 @@ ftpOpenListenSocket(Ftp::Gateway * ftpState, int fallback)
5e05d2
     }
5e05d2
 
5e05d2
     ftpState->listenForDataChannel(temp);
5e05d2
+    ftpState->data.listenConn = temp;
5e05d2
 }
5e05d2
 
5e05d2
 static void
818ced
@@ -1822,13 +1834,19 @@ ftpSendPORT(Ftp::Gateway * ftpState)
5e05d2
     // pull out the internal IP address bytes to send in PORT command...
5e05d2
     // source them from the listen_conn->local
5e05d2
 
5e05d2
+    struct sockaddr_in addr;
5e05d2
+    socklen_t addrlen = sizeof(addr);
5e05d2
+    getsockname(ftpState->data.listenConn->fd, (struct sockaddr *) &addr, &addrlen);
5e05d2
+    unsigned char port_high = ntohs(addr.sin_port) >> 8;
5e05d2
+    unsigned char port_low  = ntohs(addr.sin_port) & 0xff;
5e05d2
+
5e05d2
     struct addrinfo *AI = NULL;
5e05d2
     ftpState->data.listenConn->local.getAddrInfo(AI, AF_INET);
5e05d2
     unsigned char *addrptr = (unsigned char *) &((struct sockaddr_in*)AI->ai_addr)->sin_addr;
5e05d2
-    unsigned char *portptr = (unsigned char *) &((struct sockaddr_in*)AI->ai_addr)->sin_port;
5e05d2
+    // unsigned char *portptr = (unsigned char *) &((struct sockaddr_in*)AI->ai_addr)->sin_port;
5e05d2
     snprintf(cbuf, CTRL_BUFLEN, "PORT %d,%d,%d,%d,%d,%d\r\n",
5e05d2
              addrptr[0], addrptr[1], addrptr[2], addrptr[3],
5e05d2
-             portptr[0], portptr[1]);
5e05d2
+             port_high, port_low);
5e05d2
     ftpState->writeCommand(cbuf);
5e05d2
     ftpState->state = Ftp::Client::SENT_PORT;
5e05d2
 
818ced
@@ -1881,14 +1899,27 @@ ftpSendEPRT(Ftp::Gateway * ftpState)
5e05d2
         return;
5e05d2
     }
5e05d2
 
5e05d2
+
5e05d2
+    unsigned int port;
5e05d2
+    struct sockaddr_storage addr;
5e05d2
+    socklen_t addrlen = sizeof(addr);
5e05d2
+    getsockname(ftpState->data.listenConn->fd, (struct sockaddr *) &addr, &addrlen);
5e05d2
+    if (addr.ss_family == AF_INET) {
5e05d2
+        struct sockaddr_in *addr4 = (struct sockaddr_in*) &addr;
5e05d2
+        port = ntohs( addr4->sin_port );
5e05d2
+    } else {
5e05d2
+        struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) &addr;
5e05d2
+        port = ntohs( addr6->sin6_port );
5e05d2
+    }
5e05d2
+
5e05d2
     char buf[MAX_IPSTRLEN];
5e05d2
 
5e05d2
     /* RFC 2428 defines EPRT as IPv6 equivalent to IPv4 PORT command. */
5e05d2
     /* Which can be used by EITHER protocol. */
5e05d2
-    snprintf(cbuf, CTRL_BUFLEN, "EPRT |%d|%s|%d|\r\n",
5e05d2
+    snprintf(cbuf, CTRL_BUFLEN, "EPRT |%d|%s|%u|\r\n",
5e05d2
              ( ftpState->data.listenConn->local.isIPv6() ? 2 : 1 ),
5e05d2
              ftpState->data.listenConn->local.toStr(buf,MAX_IPSTRLEN),
5e05d2
-             ftpState->data.listenConn->local.port() );
5e05d2
+             port);
5e05d2
 
5e05d2
     ftpState->writeCommand(cbuf);
5e05d2
     ftpState->state = Ftp::Client::SENT_EPRT;
818ced
@@ -1907,7 +1938,7 @@ ftpReadEPRT(Ftp::Gateway * ftpState)
5e05d2
         ftpSendPORT(ftpState);
5e05d2
         return;
5e05d2
     }
5e05d2
-
5e05d2
+    ftpState->ctrl.message = NULL;
5e05d2
     ftpRestOrList(ftpState);
5e05d2
 }
5e05d2