I have created FTP Active mode client. On OS X operating system it works great. But when I have migrated to Ubuntu, it has started to fail. The problem is that on OS X, when I am enabling data connection, my listening socket listens on my wifi router IP. I don't know why, but on my Ubuntu it listens on 127.0.1.1. Because of this, I get response to my PORT commnd:

I won't open a connection to 127.0.1.1

How to prioritize hosts just like I had in OS X?

Data connection:

    else if (strcmp(command, "ls") == 0)
    {
        // Listening data socket initialization
        data_socket = listen_to_server(&ip_address);

        if (data_socket == SOCKET_ERROR)
        {
            goto EXIT;
        }

        // FTP commad PORT request
        if(request_port(&command_socket, ip_address) == SOCKET_ERROR)
        {
            goto EXIT;
        }

        // Server response receiving
        if(receive_packet(&command_socket, packet) == SOCKET_ERROR)
        {
            goto EXIT;
        }

        // Server response printing
        printf ("%s\n", packet);

        // FTP command LIST request
        if(request_list(&command_socket) == SOCKET_ERROR)
        {
            goto EXIT;
        }

        // Server response receiving
        if(receive_packet(&command_socket, packet) == SOCKET_ERROR)
        {
            goto EXIT;
        }

        // Server response printing
        printf ("%s\n", packet);

        // Server connection accepting (Active mode)
        int address_size = sizeof(struct sockaddr_in);
        struct sockaddr_in remote_address;

        data_socket_server = accept(data_socket, (struct sockaddr *)&remote_address, (socklen_t *)&address_size);

        // Server response receiving
        if(receive_packet(&command_socket, packet) == SOCKET_ERROR)
        {
            goto EXIT;
        }

        // Server response printing
        printf ("%s\n", packet);

        // Server data receiving
        if(receive_packet(&data_socket_server, packet) == SOCKET_ERROR)
        {
            goto EXIT;
        }

        // Server data printing
        printf ("%s\n", packet);

        // Sockets closing
        closesocket(data_socket_server);
        closesocket(data_socket);
    }

Listening socket creation:

// Listening to server function
SOCKET listen_to_server(char **ip)
{
    // SOCKET variable
    SOCKET data_socket;
    // SOCKET address structure
    struct sockaddr_in socket_address;
    // Listening host name
    char host_name [256] = {0};
    // Listening host entry
    struct hostent *host_entry;

    // Host name initialization
    if (gethostname(host_name, sizeof(host_name)) == INVALID_SOCKET)
    {
        printf("Error: failed to get host  name\n");

        return INVALID_SOCKET;
    }

    // Host entry structure initialization
    if ((host_entry = gethostbyname(host_name)) == NULL)
    {
        printf("Error: failed to get host by name \'%s\'\n", host_name);

        return INVALID_SOCKET;
    }

    // Socket address structure initialization
    socket_address.sin_family = AF_INET;
    socket_address.sin_port = htons(DATA_PORT);
    socket_address.sin_addr = *(struct in_addr *)host_entry -> h_addr;
    memset (&(socket_address.sin_zero), 0, 8);

    // Socket initialization
    if ((data_socket = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
    {
        printf("Error: failed to initialize socket\n");

        return INVALID_SOCKET; 
    }

    // Socket and address binding
    if (SOCKET_ERROR == bind(data_socket, (struct sockaddr *)&socket_address,    sizeof(socket_address)))
    {
        printf("Error: failed to bind socket\n");

        closesocket(data_socket);

        return INVALID_SOCKET;
    }

    // Socket seting as listening
    if (SOCKET_ERROR == listen(data_socket, MAX_QUEUE_LENGTH))
    {
        printf("Error: failed to set socket as listening\n");

        closesocket (data_socket);

        return INVALID_SOCKET;
    }

    *ip = inet_ntoa(*(struct in_addr *)host_entry -> h_addr);

    return data_socket;
}

Also, netstat doesn't show listening data soxket foreign address:

tcp        0      0 127.0.1.1:1024          0.0.0.0:*               LISTEN
share|improve this question
    
Please show the code you are using to create the data connection and to send the PORT command to the server. – Steffen Ullrich Dec 16 '14 at 7:51
    
Is it enough? Or shoud I show some more code? – Jacob Jones Dec 16 '14 at 8:04
    
Your code needs to use the correct 'localhost' loopback address of 127.0.0.1 I have no idea as to why some off-the-wall address worked on another system, but Linux uses the correct loopback address. Again, that is 127.0.0.1 – user3629249 Dec 16 '14 at 11:47
    
I don't want to set socket on local host, I want it to have foreign address... – Jacob Jones Dec 16 '14 at 14:14
up vote 0 down vote accepted
if ((host_entry = gethostbyname(host_name)) == NULL)
...
socket_address.sin_addr = *(struct in_addr *)host_entry -> h_addr;
...
if (SOCKET_ERROR == bind(data_socket, (struct sockaddr *)&socket_address,    sizeof(socket_address)))

It looks like that you just assume, that the locally configured hostname of the system will resolve to the external address. This assumption is wrong.

Instead you should use the local address of the FTP control connection (getsockname) as the local address of the data connection.

share|improve this answer
    
Can you tell me, what shouls I do? replace gethostbyname to getsockname? – Jacob Jones Dec 16 '14 at 13:58
    
You should throw away all the code which you use to determine the local IP (gethostname,gethostbyname) and use getsockname on the control socket instead. – Steffen Ullrich Dec 16 '14 at 15:25

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.