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

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