curl_easy_setopt(curl, CURLOPT_FTPPORT, str) on a remote computer - address is not available - ftp

I am trying to use the function 'curl_easy_setopt' with 'CURLOPT_FTPPORT' option, for changing the mode from passive to active.
On the local computer the function is working as expected.
On the remote computer when I am using curl_easy_setopt(curl, CURLOPT_FTPPORT, "-") - there is a connection (I can see that in the filezilla-server log, also files are transferring).
But, when I am using curl_easy_setopt(curl, CURLOPT_FTPPORT, "TEST_STRING" )//TEST_STRING includes ip:port, there is no connection. In the filezilla-server log the following information appears:
bind (port=21) on non local address filed: address not available
Rejected command, Requested IP address does not match control connection IP
my code:
curl_easy_setopt(m_curl, CURLOPT_FTPPORT, "192.168.19.19:21");
rc = curl_easy_perform(m_curl);
the rc returns CURL Error 28 - Timeout was reached.
In addition, I have tried several ports, and I have checked them with netstat command.

Your value of CURLOPT_FTPPORT is wrong.
First, it cannot be port 21. It must be a free local port. On most systems it also has to be above 1024.
And the IP address must be your local address, not the FTP server address. And it must be the address, from which the FTP server accepts your connection.
And in general, you should use the passive mode, not the active mode. See my article on FTP Connection Modes for details.

Related

FTP: Why use IP of PASV response at all?

When sending the FTP command "PASV", the FTP server responds with information on which host and port a data connection can be established.
This host information can be problematic if there is a NAT involved. Some clients resolve this by comparing the IP of the proposed data connection host with the one from the control connection: If the one proposed after PASV is a local one while the control connection is not using a local one, only the ports given by the PASV response are used while using the IP of the host connection.
As an example, see the Apache Commons implementation: http://svn.apache.org/viewvc/commons/proper/net/trunk/src/main/java/org/apache/commons/net/ftp/FTPClient.java?revision=1788985&view=markup#l3876
My question is now: Why use the host of the PASV answer at all? Why not just always only use the ports of the PASV answer but use the host of the control connection? As far as I know this is how it's done with IPv6 but I never see it with IPv4. Why?
At the time FTP was designed there were enough IP addresses and NAT was not a thing to be considered. But FTP was designed to support a use case where a client initiated a transfer between two different systems - see figure 2 in RFC 959 or read about File eXchange Protocol for details. And for this use case it was necessary that the IP addresses in the PORT or PASV command could be different from the (single) server resp. client IP.
As far as I know this is how it's done with IPv6 but I never see it with IPv4.
You are probably referring to the EPRT and EPSV commands which only take a port number and no IP address. While these commands were introduced since the original PORT and PASV commands did not support IPv4 these command can be used for both IPv6 and IPv4 and several clients use these for IPv4 too, thereby avoiding the problems with the wrong IP address in PORT/PASV.

Failed to FTP upload using Windows ftp.exe: "PORT IP is not same as nnn.nnn.nnn.nnn"

I am using a call to ftp.exe to upload file to a FTP Server.
This program is running since many years and uploads to number of servers, so far without problems.
After one of the receiver servers has been updated, uploads are no longer possible.
This is the command sequence:
open ftp.xxx.de
<user>
<pw>
>230 User logged in, proceed
cd upload
bin
put <filename>
and in response to this the server replies:
501 PORT IP is not the same as 10.100.244.5
150 File Status okay, about to open Connection
That is it, after this the connection is stuck and gets closed after a certain timeout period.
Funny enough, a google search for "PORT IP is not the same as" return exactly one result, which explains that the IP seen by the server is different from the one expected.
Also, when using WinSCP, FileZilla or other FTP utility programs, the connection has no problem and does transfer files just fine.
So, why does this appear and how to solve it?
The ftp.exe uses an old-fashioned active mode command PORT, which requires the client to specify its IP address to which the FTP servers needs to connect back to open a data transfer connection.
If your are behind a firewall or a NAT, the client may not know its external IP address and uses its local network address. This causes troubles. Either the server fails to connect back as it obviously cannot connect to the client's local network. Or the server rejects the PORT command straight away, if the specified IP address does not match the IP address, from which the FTP client connects to the server. This is a security measure as the difference may indicate a man-in-the-middle attack. Your server does the validation. Some servers might be configured to ignore the IP address specified in the PORT command and connect to a known IP address of the client.
Another way to solve this is, if the firewall/NAT can inspect the FTP traffic and seamlessly modify the IP address in the PORT command. This is obviously not happening.
You do not get the problem with WinSCP or FileZilla, as these clients default to the passive FTP mode, which does not have the problem. Also in the active mode these clients can be configured to use the external IP address. FileZilla also supports the modern EPRT command, that does not need to specify the IP address at all (the server uses the known IP address of the client).
See my article about active/passive FTP mode for details.
I do not think there's any way to make it working with the Windows ftp.exe. It neither supports the passive mode, nor can be configured to use the external IP address, nor supports the EPRT command.
So unless you can configure the FTP server not to do the check and connect to the known IP address of the client or configure your firewall/NAT to modify the IP address in the PORT command, you have to use another FTP client.
As you know that WinSCP works, see the guide for converting the Windows ftp.exe script to WinSCP script.
(I'm the author of WinSCP)

Access localhost ( running on Mac OS X ) from another machine in the network

I have a REST service running on Mac OS X, which im currently accessing using "localhost:8888" and "10.0.2.2:8888"
I want to access the same service from another computer which is in the same network.
I disabled the firewall also and I typed
nc -v 192.168.1.3 8888
and got the result as
nc: connectx to 192.168.1.3 port 8888 (tcp) failed: Connection refused
currently i use localhost (to access using java application) and 10.0.2.2 (to access using android application runs in the simulator) which both runs on the same machine which the server runs too.
I want to put the android application to my phone and give the machine ip addess ( because if i connect to internet via wifi, it'll be in the same local area network) i should be able to access my service runs on my machine.
can some one please tell me what im doing wrong here? Thank you
You can't access localhost from your front end code. It needs to refer to the server's name or address.
The localhost address should be 127.0.0.1, which is in the loopback range of addresses. Any address in the 127.0.0.0/8 block can never appear anywhere on any network, nor can any address in that block be used as a source or destination address outside a host. It is not possible for one host to access anything in that address range on another host.
The goes back at least as far as RFC 990, ASSIGNED NUMBERS:
The class A network number 127 is assigned the "loopback" function,
that is, a datagram sent by a higher level protocol to a network 127
address should loop back inside the host. No datagram "sent" to a
network 127 address should ever appear on any network anywhere.
RFC 1122, Requirements for Internet Hosts -- Communication Layers:
(g) { 127, }
Internal host loopback address. Addresses of this form MUST NOT
appear outside a host.
Also RFC 3330, Special-Use IPv4 Addresses:
127.0.0.0/8 - This block is assigned for use as the Internet host loopback address. A datagram sent by a higher level protocol to an
address anywhere within this block should loop back inside the host.
This is ordinarily implemented using only 127.0.0.1/32 for loopback,
but no addresses within this block should ever appear on any network
anywhere [RFC1700, page 5].

Connecting to MySQL (on Google Cloud SQL) via JDBC and IPv6?

I would like to connect to Google Cloud SQL from an external application using JDBC and the instance's IPv6 address as shown on my Google Developers Console (here obfuscated):
String url = "jdbc:mysql://abcd:abcd:abcd:abcd:abcd:abcd:abcd:abcd";
String user = "root";
String password = "<also_obfuscated>";
connection = DriverManager.getConnection(url, user, password);
This leads to the following exception:
com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException:
Cannot load connection class because of underlying exception:
'java.lang.NumberFormatException:
For input string: "abcd:abcd:abcd:abcd:abcd:abcd:abcd:abcd"'.
I am using the latest JDBC driver for MySQL. Connection via JDBC and IPv4 works but requires an extra configuration step and incurs (small) extra cost.
So is it even possible to connect to MySQL via JDBC and IPv6 and if so how?
UPDATE According to the documentation, this URL should work for IPv6:
jdbc:mysql://address=(protocol=tcp)(host=abcd:abcd:abcd:abcd:abcd:abcd:abcd:abcd)(port=3306)
However, now I'm getting the following exception:
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException:
Communications link failure
The last packet sent successfully to the server was 0 milliseconds ago.
The driver has not received any packets from the server.
Besides the JDBC driver supporting IPv6 (which it does, according to the documentation), and the client OS supporting IPv6 (which mine should as it is OS X Yosemite), and the server OS supporting IPv6 (which the Google Cloud does because it reports an IPv6 server address) what other pieces need to be in place in order for IPv6 client-server connections to work?
E.g. does my ISP have to provide any particular support?
You need to register the IPV6 address from which you'll be coming into Google Cloud SQL, among the authorized addresses on the Cloud SQL console.
You can check that IPv6 address e.g by visiting sites such as whatismyv6.com .
Then, all your ISP has to do is to provide a stable IPV6 address (alas, even to these days, not all do -- alas, AT&T Uverse, my ISP at home, does not, for example).
Even from locations where I could reliably get a stable IPv6 address, I had exactly the same problem, originally -- until it dawned on me that, if I'm coming in with an IPv6 address and what I've authorized is an IPv4 one, Google Cloud SQL cannot "translate" one into the other to find out I'm in fact authorized!-)
Note that if you don't have and can't get an IPv6 address from which to connect (e.g. connecting from a home machine through an ISP that does not yet support IPv6) then you can hit the "Request IPv4 address" button under Google Developers Console / Storage / Cloud SQL / [Your Intance] / Access Control / IP Address and you will get one assigned (within a few seconds) which will cost $0.01 per hour, paid from your free $300 of credit if you still have that credit available. Once you move your app to, for example, one of Google's app servers, you will no doubt be able to get an IPv6 address. Release the IPv4 address when unused to save credit.
Try
String url = "jdbc:mysql://[abcd:abcd:abcd:abcd:abcd:abcd:abcd:abcd]";
In URLs literal IPv6 addresses have to be surrounded by [] so that the parser can see the difference between parts of the address and the optional port number which is also separated by a :.
It is often easier to use hostnames instead of literal IP addresses. It stays independent of the used IP protocol and changing addresses is easier as well.

Connection is forcefully rejected

Using winsock as shown below we sent information to TCP port 8000. But sometimes we get error like Connection is forcefully rejected(error number 10061) and Connection is aborted due to timeout or other failure(error number 10053) . But in both pc firewall is disabled. so i think port will not be closed due to firewall. So how to troubleshoot these errors.
Dim TempWinClient As New AxMSWinsockLib.AxWinsock
TempWinClient.RemoteHost = PCName
TempWinClient.RemotePort = Port
TempWinClient.Tag = Message
TempWinClient.Connect()
For one, always call the .Close method on the WinSock control before any .Connect. I don't know what AxMSWinsockLib is, wrapper for the Winsock APIs?
Anyway, as to your question:
Firewalls aren't the only thing in the way. Ports need to be forwarded on the listening server's router; in this case, port 8000.
So on the server that you're attempting to connect to:
See if it is hooked up to a router. You need its "Default Gateway".
Open up a command prompt and type "ipconfig" without the quotes. Find the correct adapter, look at the IP address (usually 192.168.1.x) and then find the Default Gateway. Keep note of the IP address though!
The Default Gateway is the IP address of the router which you will connect to through a web browser like Internet Explorer (yuck), Google Chrome, Firefox, etc.
Open up your web browser of choice and type in: htp://192.168.0.1 (http, not htp) where the 192.168.0.1 is the Default Gateway.
You will be prompted for a username and password. Do a search on your router's model for the default password, but usually admin/admin, administrator/admin, or something will work.
Go through the menus and find something called Port Forwarding. It's different for each router, you may have to Google search for "[router model here] port forwarding" to get instructions.
Once on the port forwarding page, enter the IP address you should have taken note of earlier. This will tell the router to forward packets on port 8000 to the correct computer.
Enter the port number (8000) and apply the settings.
Then try to reconnect.

Resources