1

My question is this: During TFTP, when a client connects to a server, the default port for intitial data transmission is port 69. When the server receives a WRQ (write request) packet from the client, it returns an ACK(acknowledgement) packet. However this ACK packet is sent via a different port back to the client. below is a function which I am using to connect to the server. Note that server_port is 69.

int TFTPClient::connectToServer() {

    socket_descriptor = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);

    if (socket_descriptor == -1) {

        throw new ETFTPSocketCreate;

    }

    client_address.sin_family = AF_INET;
    client_address.sin_port = htons(server_port);   
    client_address.sin_addr.s_addr = inet_addr(this->server_ip); 

    connection = connect(socket_descriptor, (const struct sockaddr *)&client_address, sizeof(client_address));

    if (connection != 0) {

    cout << "Unable to connect to an address\n";
    return -1;

    }

    DEBUGMSG("Successfully connected");

    AfxMessageBox("Successfully connected");

    return 1;

}


int TFTPClient::sendPacket(TFTP_Packet* packet) {

    return send(socket_descriptor, (char*)packet->getData(), packet->getSize(), 0);

}

int TFTPClient::waitForPacket(TFTP_Packet* packet, int timeout_ms) {

    packet->clear();

    int receive_status;
    int iResult; 
    u_long iMode = 0;

    //-----------------------------------------------
    //  Set the socket I/O mode: In this case FIONBIO
    //  enables or disables the blocking mode for the 
    //  socket based on the numerical value of iMode.
    //  If iMode = 0, blocking is enabled; 
    //  If iMode != 0, non-blocking mode is enabled.
    //-----------------------------------------------

    iResult = ioctlsocket(socket_descriptor, FIONBIO, &iMode);

    if (iResult != NO_ERROR){

        printf("ioctlsocket failed with error: %ld\n", iResult);
    }

    receive_status = recv(socket_descriptor, (char*)packet->getData(), TFTP_PACKET_MAX_SIZE, 0);

    if (receive_status == 0) {
        cout << "Connection was closed by server\n";
        return TFTP_CLIENT_ERROR_CONNECTION_CLOSED;
    }

    if (receive_status == SOCKET_ERROR) {

        DEBUGMSG("recv() error in waitForPackage()");
        return TFTP_CLIENT_ERROR_RECEIVE;
    }

    packet->setSize(receive_status);

    return TFTP_CLIENT_ERROR_NO_ERROR;

}

I am using Wire Shark to determine data transmission over the socket. I am sending a WRQ packet which is successfully reaching the server. An ACK packet(acc. to Wireshark) is sent back to the client successfully(on a different port). However, my application hangs indefinitely when I hit the 'recv()' function. I fear that this may be due to the fact that I am calling the same socket('socket_descriptor') in the recv() function that I called in the send() function. Does the port 69 specification of 'socket_descriptor' cause this application stall?? Or does recv() accept packets from the server IP over other ports?? Can anyone shed light on this please??

Apanatshka
  • 5,958
  • 27
  • 38
MDK
  • 57
  • 1
  • 8
  • You're gonna want to put a timeout on that recv() call. You also might try setting it to receive on the port that the ACK is gonna be sent back on. – Bioniclegenius Jul 30 '15 at 16:52
  • The timeout I can implement. However the server will choose a different port every time I run the application, and the only way I can see that is through WireShark. My application is running under VS 2008. Thanks for the reply. – MDK Jul 31 '15 at 08:30
  • recv() works using a socket connection that you've set up. Sockets are assigned to a specific IP and port. I kinda don't think that the server should be sending ACK on random ports back... Time to look up the documentation on TFTP! https://tools.ietf.org/html/rfc1350 <- this is the RFC for TFTP. Try reading through and see if it helps at all. From my own readthrough of it, it doesn't mention anything about ACK packets being returned on a separate port. Something weird is up. – Bioniclegenius Jul 31 '15 at 14:09

0 Answers0