Bug 479016 - ftp fails opening PASV data connection over socks with remote dns resolution enabled; r=bzbarsky sr=cbiesinger

This commit is contained in:
Koen Deforche 2009-03-19 00:59:39 +01:00
parent 696e7d1565
commit 9c614d6177
2 changed files with 45 additions and 11 deletions

View File

@ -44,7 +44,6 @@
#include "prprf.h"
#include "prlog.h"
#include "prtime.h"
#include "prnetdb.h"
#include "nsFTPChannel.h"
#include "nsFtpConnectionThread.h"
@ -1271,18 +1270,34 @@ nsFtpState::S_pasv() {
if (!mAddressChecked) {
// Find socket address
mAddressChecked = PR_TRUE;
PR_InitializeNetAddr(PR_IpAddrAny, 0, &mServerAddress);
nsITransport *controlSocket = mControlConnection->Transport();
if (!controlSocket)
return FTP_ERROR;
nsCOMPtr<nsISocketTransport> sTrans = do_QueryInterface(controlSocket);
if (sTrans) {
PRNetAddr addr;
nsresult rv = sTrans->GetPeerAddr(&addr);
nsresult rv = sTrans->GetPeerAddr(&mServerAddress);
if (NS_SUCCEEDED(rv)) {
mServerIsIPv6 = addr.raw.family == PR_AF_INET6 &&
!PR_IsNetAddrType(&addr, PR_IpAddrV4Mapped);
PR_NetAddrToString(&addr, mServerAddress, sizeof(mServerAddress));
if (!PR_IsNetAddrType(&mServerAddress, PR_IpAddrAny))
mServerIsIPv6 = mServerAddress.raw.family == PR_AF_INET6 &&
!PR_IsNetAddrType(&mServerAddress, PR_IpAddrV4Mapped);
else {
/*
* In case of SOCKS5 remote DNS resolution, we do
* not know the remote IP address. Still, if it is
* an IPV6 host, then the external address of the
* socks server should also be IPv6, and this is the
* self address of the transport.
*/
PRNetAddr selfAddress;
rv = sTrans->GetSelfAddr(&selfAddress);
if (NS_SUCCEEDED(rv))
mServerIsIPv6 = selfAddress.raw.family == PR_AF_INET6
&& !PR_IsNetAddrType(&selfAddress,
PR_IpAddrV4Mapped);
}
}
}
}
@ -1405,14 +1420,32 @@ nsFtpState::R_pasv() {
return FTP_ERROR;
nsCOMPtr<nsISocketTransport> strans;
rv = sts->CreateTransport(nsnull, 0, nsDependentCString(mServerAddress),
port, mChannel->ProxyInfo(),
getter_AddRefs(strans)); // the data socket
nsCAutoString host;
if (!PR_IsNetAddrType(&mServerAddress, PR_IpAddrAny)) {
char buf[64];
PR_NetAddrToString(&mServerAddress, buf, sizeof(buf));
host.Assign(buf);
} else {
/*
* In case of SOCKS5 remote DNS resolving, the peer address
* fetched previously will be invalid (0.0.0.0): it is unknown
* to us. But we can pass on the original hostname to the
* connect for the data connection.
*/
rv = mChannel->URI()->GetAsciiHost(host);
if (NS_FAILED(rv))
return FTP_ERROR;
}
rv = sts->CreateTransport(nsnull, 0, host,
port, mChannel->ProxyInfo(),
getter_AddRefs(strans)); // the data socket
if (NS_FAILED(rv))
return FTP_ERROR;
mDataTransport = strans;
LOG(("FTP:(%x) created DT (%s:%x)\n", this, mServerAddress, port));
LOG(("FTP:(%x) created DT (%s:%x)\n", this, host.get(), port));
// hook ourself up as a proxy for status notifications
rv = mDataTransport->SetEventSink(this, NS_GetCurrentThread());

View File

@ -52,6 +52,7 @@
#include "nsIStreamListener.h"
#include "nsICacheListener.h"
#include "nsIURI.h"
#include "prnetdb.h"
#include "prtime.h"
#include "nsString.h"
#include "nsIFTPChannel.h"
@ -286,7 +287,7 @@ private:
static PRUint32 mSessionStartTime;
char mServerAddress[64];
PRNetAddr mServerAddress;
// ***** control read gvars
nsresult mControlStatus;