Blame SOURCES/squid-3.3.8-active-ftp-2.patch

192ec7
diff --git a/src/clients/FtpGateway.cc b/src/clients/FtpGateway.cc
192ec7
index 524eebb..2f09b12 100644
192ec7
--- a/src/clients/FtpGateway.cc
192ec7
+++ b/src/clients/FtpGateway.cc
192ec7
@@ -1834,6 +1834,7 @@ ftpOpenListenSocket(Ftp::Gateway * ftpState, int fallback)
d3a8ee
     }
d3a8ee
 
192ec7
     ftpState->listenForDataChannel(temp);
d3a8ee
+    ftpState->data.listenConn = temp;
d3a8ee
 }
d3a8ee
 
192ec7
 static void
192ec7
@@ -1869,13 +1870,19 @@ ftpSendPORT(Ftp::Gateway * ftpState)
d3a8ee
     // pull out the internal IP address bytes to send in PORT command...
d3a8ee
     // source them from the listen_conn->local
192ec7
 
192ec7
-    struct addrinfo *AI = NULL;
d3a8ee
+    struct sockaddr_in addr;
d3a8ee
+    socklen_t addrlen = sizeof(addr);
d3a8ee
+    getsockname(ftpState->data.listenConn->fd, (struct sockaddr *) &addr, &addrlen);
d3a8ee
+    unsigned char port_high = ntohs(addr.sin_port) >> 8;
192ec7
+    unsigned char port_low  = ntohs(addr.sin_port) & 0xff;
192ec7
+
192ec7
+    struct addrinfo *AI = NULL;
192ec7
     ftpState->data.listenConn->local.getAddrInfo(AI, AF_INET);
d3a8ee
     unsigned char *addrptr = (unsigned char *) &((struct sockaddr_in*)AI->ai_addr)->sin_addr;
d3a8ee
-    unsigned char *portptr = (unsigned char *) &((struct sockaddr_in*)AI->ai_addr)->sin_port;
d3a8ee
+    // unsigned char *portptr = (unsigned char *) &((struct sockaddr_in*)AI->ai_addr)->sin_port;
d3a8ee
     snprintf(cbuf, CTRL_BUFLEN, "PORT %d,%d,%d,%d,%d,%d\r\n",
d3a8ee
              addrptr[0], addrptr[1], addrptr[2], addrptr[3],
d3a8ee
-             portptr[0], portptr[1]);
d3a8ee
+             port_high, port_low);
d3a8ee
     ftpState->writeCommand(cbuf);
192ec7
     ftpState->state = Ftp::Client::SENT_PORT;
d3a8ee
 
192ec7
@@ -1923,14 +1930,27 @@ ftpSendEPRT(Ftp::Gateway * ftpState)
d3a8ee
         return;
d3a8ee
     }
192ec7
 
d3a8ee
-    char buf[MAX_IPSTRLEN];
192ec7
+
d3a8ee
+    unsigned int port;
d3a8ee
+    struct sockaddr_storage addr;
d3a8ee
+    socklen_t addrlen = sizeof(addr);
d3a8ee
+    getsockname(ftpState->data.listenConn->fd, (struct sockaddr *) &addr, &addrlen);
d3a8ee
+    if (addr.ss_family == AF_INET) {
192ec7
+        struct sockaddr_in *addr4 = (struct sockaddr_in*) &addr;
192ec7
+        port = ntohs( addr4->sin_port );
d3a8ee
+    } else {
192ec7
+        struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) &addr;
192ec7
+        port = ntohs( addr6->sin6_port );
192ec7
+    }
192ec7
+
192ec7
+    char buf[MAX_IPSTRLEN];
192ec7
 
d3a8ee
     /* RFC 2428 defines EPRT as IPv6 equivalent to IPv4 PORT command. */
d3a8ee
     /* Which can be used by EITHER protocol. */
d3a8ee
-    snprintf(cbuf, CTRL_BUFLEN, "EPRT |%d|%s|%d|\r\n",
d3a8ee
+    snprintf(cbuf, CTRL_BUFLEN, "EPRT |%d|%s|%u|\r\n",
192ec7
              ( ftpState->data.listenConn->local.isIPv6() ? 2 : 1 ),
192ec7
              ftpState->data.listenConn->local.toStr(buf,MAX_IPSTRLEN),
192ec7
-             ftpState->data.listenConn->local.port() );
d3a8ee
+             port);
d3a8ee
 
d3a8ee
     ftpState->writeCommand(cbuf);
192ec7
     ftpState->state = Ftp::Client::SENT_EPRT;