This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

NDK problem when multiple accept()



Hi.

I Think I found a bug that I want to report in sockpcb.c, SockCleanPcb().
We have a system that has multiple accept() waiting for Connection. When we change IP-address,
only one of them is signaled and aborted (ECONNABORTED).
What I found out is that the pProtNext is set to NULL in SockClose() and therefor only the first one found is signaled.
I made the following change, marked below.
We are using the latest NDK (2_25_00_09) and recomended xdctools/bios. The problem can be found in eariler NDK:s also.

-----------------------

    /* Cycle through all the entries in the socket table. */
    ps = pSockList [SockProt];
    while (ps != NULL)
    {
        // Save pProtNext because SockClose() sets it to NULL in SockPcbDetach()
        pNextTmp = ps->pProtNext;

        /* Clean the entry only if we have a match */
        if (ps->LIP == IPAddress) {
            /*
             *  Look for any sockets that are blocked on accept() call
             *  (fix for SDOCM00115513)
             */
            if (ps->OptionFlags & SO_ACCEPTCONN) {
                /* Set an error for this socket to force accept() to return */
                error = ECONNABORTED;
                SockSet((HANDLE)ps, SOL_SOCKET, SO_ERROR, &error,
                        sizeof(error));
                /*
                 *  Wake the socket blocked on accept(), allowing accept() to
                 *  handle the error and return
                 */
                FdSignalEvent(ps, FD_EVENT_READ);
            }
            
            SockClose (ps);  // pProtNext = NULL;
        }

        /* Get the next entry. */
        // ps = ps->pProtNext; Doesn't work
        ps = pNextTmp;
   }

Regards

  • Your post is invisible. Please resend.
  • Hi.

    I Think I found a bug that I want to report in sockpcb.c, SockCleanPcb().

    We have a system that has multiple accept() waiting for Connection. When we change IP-address,
    only one of them is signaled and aborted (ECONNABORTED).

    What I found out is that the pProtNext is set to NULL in SockClose() and therefor only the first one found is signaled.

    I made the following change, marked below.

    We are using the latest NDK (2_25_00_09) and recomended xdctools/bios. The problem can be found in eariler NDK:s also.


    -----------------------

    /* Cycle through all the entries in the socket table. */ ps = pSockList [SockProt]; while (ps != NULL) {         // Save pProtNext because SockClose() sets it to NULL in SockPcbDetach()
    pNextTmp = ps->pProtNext;


    /* Clean the entry only if we have a match */ if (ps->LIP == IPAddress) { /* * Look for any sockets that are blocked on accept() call * (fix for SDOCM00115513) */ if (ps->OptionFlags & SO_ACCEPTCONN) { /* Set an error for this socket to force accept() to return */ error = ECONNABORTED; SockSet((HANDLE)ps, SOL_SOCKET, SO_ERROR, &error, sizeof(error)); /* * Wake the socket blocked on accept(), allowing accept() to * handle the error and return */ FdSignalEvent(ps, FD_EVENT_READ); }

    SockClose (ps); // pProtNext = NULL; } /* Get the next entry. */
            // ps = ps->pProtNext; Doesn't work ps = pNextTmp;
    }

         Regards

         Per-Anders

  • I don't see anything again.
  • Hi.I Think I found a bug that I want to report in sockpcb.c, SockCleanPcb().

    We have a system that has multiple accept() waiting for Connection.

    When we change IP-address, only one of them is signaled and aborted (ECONNABORTED).
    What I found out is that the pProtNext is set to NULL in SockClose() and therefor only the
    first one found is signaled. I made the following change, marked below.

    We are using the latest NDK (2_25_00_09) and recomended xdctools/bios.
    The problem can be found in eariler NDK:s also.
    -----------------------

    /* Cycle through all the entries in the socket table. */

    ps = pSockList [SockProt];
    while (ps != NULL)
    {
    // Save pProtNext because SockClose() sets it to NULL in SockPcbDetach()
    pNextTmp = ps->pProtNext;

    /* Clean the entry only if we have a match */
    if (ps->LIP == IPAddress) {
    /*
    * Look for any sockets that are blocked on accept() call
    * (fix for SDOCM00115513)
    */
    if (ps->OptionFlags & SO_ACCEPTCONN) {
    /* Set an error for this socket to force accept() to return */
    error = ECONNABORTED;
    SockSet((HANDLE)ps, SOL_SOCKET, SO_ERROR, &error,
    sizeof(error));
    /*
    * Wake the socket blocked on accept(), allowing accept() to
    * handle the error and return
    */
    FdSignalEvent(ps, FD_EVENT_READ);
    }
    SockClose (ps); // pProtNext = NULL;
    }

    /* Get the next entry. */
    // ps = ps->pProtNext; Doesn't work
    ps = pNextTmp;
    }

    Regards

    Per-Anders

    PS: Hope this works
  • Hello,

    Which device and software are you using?

    best regards,

    David Zhou

  • Hi!

    i have tested this on both IDK437x and EVM57XX board with the latest NDK.

    I have an application that has 4 different accept() calls (ftp/http/telnet etc.) waiting for connections.

    When I change IP-address on the system via the CfgXXX API:s I see that only one of the accept() calls is aborted.

    I tracked this down to the netsrv.c, SPIpNet() function. In that function you call:

     SockCleanPcb (SOCKPROT_TCP, pi->IPAddr);
     SockCleanPcb (SOCKPROT_UDP, pi->IPAddr);
     SockCleanPcb (SOCKPROT_RAW, pi->IPAddr);

    In SockCleanPcb() there is a "loop" that goes through all open sockets and determind if they shall be aborted. This works fine for the first found, but because the next pointer is overwritten, only the first is aborted.

    I added some code myself in the SockCleanPcb() and now all the accept() calls are aborted as they shall. See my change below.

    void SockCleanPcb (uint SockProt, IPN IPAddress)
    {
        SOCK    *ps;
        struct _sock *Pnext;
        int error;

        /* Validate the socket protocol family. */
        if( SockProt<SOCKPROT_TCP || SockProt>SOCKPROT_RAW )
            return;

        /* Cycle through all the entries in the socket table. */
        ps = pSockList [SockProt];
        while (ps != NULL)
        {
            Pnext = ps->pProtNext;

            /* Clean the entry only if we have a match */
            if (ps->LIP == IPAddress) {
                /*
                 *  Look for any sockets that are blocked on accept() call
                 *  (fix for SDOCM00115513)
                 */
                if (ps->OptionFlags & SO_ACCEPTCONN) {
                    /* Set an error for this socket to force accept() to return */
                    error = ECONNABORTED;
                    SockSet((HANDLE)ps, SOL_SOCKET, SO_ERROR, &error,
                            sizeof(error));
                    /*
                     *  Wake the socket blocked on accept(), allowing accept() to
                     *  handle the error and return
                     */
                    FdSignalEvent(ps, FD_EVENT_READ);
                }

                SockClose (ps); // Destroys the pProtNext
            }

            /* Get the next entry. */
            ps = Pnext;
        }
        return;
    }

    Regards:

    Per-Anders

  • Hi! Any feedback on this issue?

    Regards

    Per-Anders

  • Hi!
    Any news about this issue?

    BR:
  • Hi Per-Anders,

    The code change appears to make sense. We will have NDK team reviewed for completeness.

    Regards,
    Garrett