This project is read-only.

Active mode overrides

Sep 1, 2011 at 5:58 AM
Edited Sep 1, 2011 at 5:59 AM

In my code,  added a new constructor that takes in three additional parameters:  localIPAddress, lowerPort, upperPort

These ports are necessary because when a client is running in active mode behind a firewall, they must forward a number of ports to their machine from their firewall.  These optional parameters allow the client to open a set number of ports ie (5000 - 5010) and use one of those when connecting in active mode.  The current code in source control just uses a random port, and that may not (usually isn't) opened by the client's firewall.

I also added the localIPAddress parameter, because again, when behind a firewall, the IP address that gets sent with the PORT command is a localIP address, not a public address.  Here are the code snippets I changed

using System.Net.NetworkInformation;

 

IPAddress localActiveIPAddress;
int localActivePortLower;
int localActivePortUpper;

 

public string Connect(string hostname, int port, NetworkCredential credential, ESSLSupportMode sslSupportMode, 
                            RemoteCertificateValidationCallback userValidateServerCertificate, X509Certificate x509ClientCert, 
                            int sslMinKeyExchangeAlgStrength, int sslMinCipherAlgStrength, int sslMinHashAlgStrength, 
                            int? timeout, bool useCtrlEndPointAddressForData, EDataConnectionMode dataConnectionMode,
			 IPAddress localActiveIPAddress, int lowerActivePort, int upperActivePort)

 

 

 

 

private int SetupActiveDataConnectionStep1()
{
            CloseDataConnection();

            IPEndPoint localAddr = new IPEndPoint(IPAddress.Any, 0);
			if (localActiveIPAddress != null && localActivePortLower > 0 && localActivePortUpper > 0) {

				for (int port = localActivePortLower; port <= localActivePortUpper; port++) {
					if (IsPortAvailable(port)) {
						localAddr = new IPEndPoint(IPAddress.Any, port);
						break;
					}
				}				
			}

private void PortCmd()
        {
            int port = SetupActiveDataConnectionStep1();

            byte[] addr = (ctrlClient.Client.LocalEndPoint as IPEndPoint).Address.GetAddressBytes();
			if (localActiveIPAddress != null) {
				addr = localActiveIPAddress.GetAddressBytes();
			}
            string portStr = string.Format("{0},{1},{2},{3},{4},{5}", addr[0], addr[1], addr[2], addr[3], port / 256, port % 256);

            FTPReply reply = HandleCmd("PORT " + portStr);
        }
activeDataConnListener = new TcpListener(localAddr); activeDataConnListener.Start(); return (activeDataConnListener.LocalEndpoint as IPEndPoint).Port; }


private bool IsPortAvailable(int port) {
			foreach(var connection in IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpConnections()){
				if(connection.LocalEndPoint.Port == port)
					return false;
			}
			return true;
		}

Nov 7, 2013 at 7:04 PM
Perfect for me....

I made also some internal modifications for exemple to access finall IPAdress when proxy is used, etc...

But I get still some difficulties when DNS named server , especially dyndns ones.

Any Idea ?