buglwIP - A Lightweight TCP/IP stack - Bugs: bug #46685, pcb->accepts_pending is not...

 
 

You are not allowed to post comments on this tracker with your current authentication level.

bug #46685: pcb->accepts_pending is not decreased

Submitter:  PIPON <harvey>
Submitted:  Tue 15 Dec 2015 10:48:11 AM UTC
   
 
Category:  None Severity:  3 - Normal
Item Group:  Faulty Behaviour Status:  Invalid
Privacy:  Public Assigned to:  jcunningham
Open/Closed:  Closed Planned Release:  None
lwIP version:  1.3.2

Jump to the original submission

Mon 11 Jan 2016 03:46:53 PM UTC, comment #9: 

Closing this, the behavior seen by OP is not a bug, but an application issue

Joel Cunningham <jcunningham>
Group Member
Fri 08 Jan 2016 03:36:24 PM UTC, comment #8: 

Right, inside your accept callback, pcb is the new connection.  You'll need to reference the listener pcb.  You could save this in a static global.  I would imagine you're already storing your listener pcb somewhere that is not a function scoped variable otherwise it would be leaking when your init function goes out of scope

Or the listening pcb can be passed as the arg in your callback if you use tcp_arg() to register the listener pcb

void ftpd_init (void)
{
    pcb = tcp_new();
    tcp_bind (pcb, IP_ADDR_ANY, 21);
    pcb = tcp_listen (pcb);
    tcp_arg(pcb, pcb);
    tcp_accept (pcb, ftpd_msgaccept);
}

Joel Cunningham <jcunningham>
Group Member
Fri 08 Jan 2016 06:36:56 AM UTC, comment #7: 

Hello,
I have the impression of being an ass because I still do not understand
Actually let me rephrase my question

When I call  pcb = tcp_listen (pcb);
It's during the initialization ; At this time there is no connection
I effectiveley got a casted pointer to a reduced listenning pcb through which accepts_pending can be changed, but at this point it is not usefull...

When I connected a ftp client the callback function ftpd_msgaccept is entered; I think as you tell me it is the place to decrease accepts_pending : The problem is that inside this function, pcb is not pointing to the reduced structure so accepts_pending is not accessible ...

Regards

PIPON <harvey>
Thu 07 Jan 2016 05:44:05 PM UTC, comment #6: 

Actually the pcb returned from tcp_listen() is of type struct tcp_pcb_listen *lpcb, but it has been casted.  Take a look at tcp_listen_with_backlog().  The original pcb is transformed into type tcp_pcb_listen, which you can pass to tcp_accepted()

Within APIs and code, listener PCBs are treated as a normal struct tcp_pcb until looking at the state (LISTEN) at which point it is casted to the correct type.  If you look at the tcp_accepted() macro, you can see it's expecting the input PCB to be struct tcb_pcb because it performs its own casts

Joel Cunningham <jcunningham>
Group Member
Thu 07 Jan 2016 04:17:09 PM UTC, comment #5: 

Hello
Thanks for this information
In my case tcp_accept (pcb, ftpd_msgaccept);

with static err_t ftpd_msgaccept (void *arg, struct tcp_pcb *pcb, err_t err)

Unfortunately pcb is not a tcp_pcb_listen pointer; So I could not call tcp_accepted (pcb) inside this function


Is the pcb generated during tcp_listen call is stored somewhere in a structure ?

Regards


PIPON <harvey>
Thu 07 Jan 2016 02:50:20 PM UTC, comment #4: 

Thanks for the example code, since you're using the Raw API in your application, your application code is responsible for calling tcp_accepted() after having accepted the connection via tcp_accept().  This performs the bookkeeping on the accepts_pending that is not happening in your case

See documentation about Raw API and TCP:

http://lwip.wikia.com/wiki/Raw/TCP

Joel Cunningham <jcunningham>
Group Member
Thu 07 Jan 2016 09:40:13 AM UTC, comment #3: 

Hello Joël

I have a look to the former bug but it’s not the same behaviour : in my case the connexion succeeded and is closed by the client.


My code is

void ftpd_init (void)
{
    pcb = tcp_new();
    tcp_bind (pcb, IP_ADDR_ANY, 21);
    pcb = tcp_listen (pcb);
    tcp_accept (pcb, ftpd_msgaccept);
}

I'm using tcp_listen_with_backlog to listen the port

I tried different modification of the tcp_pcb_purge without success
My test is making an active ftp connection with winSCP, when succeeded I close the connection and open a new one : let's do that six times

Active PCB states:
Local port 23, foreign port 53409 snd_nxt 7227 rcv_nxt 1291642576 State: ESTABLISHED
Local port 21, foreign port 53420 snd_nxt 6929 rcv_nxt 3585840680 State: ESTABLISHED
Listen PCB states:
Local port 21, foreign port 10 snd_nxt 0 rcv_nxt 3452816845 State: LISTEN ++pending:0
Local port 23, foreign port 20 snd_nxt 0 rcv_nxt 3452816845 State: LISTEN ++pending:0
TIME-WAIT PCB states:
Local port 20, foreign port 53421 snd_nxt 6726 rcv_nxt 1313920599 State: TIME_WAIT

The connexion succeeded : I close it and open a new one six times …

Active PCB states:
Local port 23, foreign port 53409 snd_nxt 7725 rcv_nxt 1291642582 State: ESTABLISHED
Local port 21, foreign port 53494 snd_nxt 8775 rcv_nxt 955443436 State: CLOSE_WAIT
Local port 21, foreign port 53488 snd_nxt 8396 rcv_nxt 3055508506 State: CLOSE_WAIT
Local port 21, foreign port 53481 snd_nxt 8037 rcv_nxt 1950718764 State: CLOSE_WAIT
Local port 21, foreign port 53477 snd_nxt 7697 rcv_nxt 3149222811 State: CLOSE_WAIT
Local port 21, foreign port 53469 snd_nxt 7379 rcv_nxt 684387631 State: CLOSE_WAIT
Local port 21, foreign port 53466 snd_nxt 7086 rcv_nxt 4403644 State: CLOSE_WAIT
Local port 21, foreign port 53420 snd_nxt 6948 rcv_nxt 3585840689 State: CLOSE_WAIT
Listen PCB states:
Local port 21, foreign port 10 snd_nxt 0 rcv_nxt 3452816845 State: LISTEN ++pending:0
Local port 23, foreign port 20 snd_nxt 0 rcv_nxt 3452816845 State: LISTEN ++pending:0
TIME-WAIT PCB states:

The sockets are in CLOSE_WAIT states and  the accept_pending was increased but not decreased …..

During the transition from ESTABLISHED to CLOSE_WAIT I don’t know what was the listening pcb which increased the accept_pending variable so I could not decreased it here….



Best Regards

PIPON <harvey>
Wed 06 Jan 2016 03:31:14 PM UTC, comment #2: 

I took a look at your original post and what socket/netconn calls are you performing to accept the connection?  Or are you using the raw API?

I've found a leak of accepts_pending that happens during resource exhaustion when we fail to establish the connection (see https://savannah.nongnu.org/bugs/?46696) but I'm not sure if that's what you are seeing

Your proposed fix changes the behavior of accepts_pending.  The variable is used to implement a backlog which limits the number of connections outstanding within the network stack that the application has not yet "accepted".  Your change is immediately decreasing the backlog value after receiving a segment destined for a listener, the 3-way handshake may not even be complete at this point, but further there is no limiting of outstanding connections happening anymore

Joel Cunningham <jcunningham>
Group Member
Wed 06 Jan 2016 09:01:20 AM UTC, comment #1: 

{{note|Waiting for a better solution I added a bold*tcp_accepted*bold call when a connection is established....}}


tcp_input () {
.....
        if (lpcb != NULL) {
            /* Move this PCB to the front of the list so that subsequent
               lookups will be faster (we exploit locality in TCP segment
               arrivals). */
            if (prev != NULL) {
                ( (struct tcp_pcb_listen *) prev)->next = lpcb->next;
                /* our successor is the remainder of the listening list */
                lpcb->next = tcp_listen_pcbs.listen_pcbs;
                /* put this listening pcb at the head of the listening list */
                tcp_listen_pcbs.listen_pcbs = lpcb;
            }
            LWIP_DEBUGF (TCP_INPUT_DEBUG, ("tcp_input: packed for LISTENing connection.\r\n"));
            tcp_listen_input (lpcb);
            tcp_accepted (lpcb); //ADD//
            pbuf_free (p);
            return;
        }
.....
}


PIPON <harvey>
Tue 15 Dec 2015 10:48:11 AM UTC, original submission:  

Hello,

I'm new to this group.

Here is my problem .

I use a ftp server: to avoid multiple connection that causes a memory overflow I activated TCP_LISTEN_BACKLOG with  TCP_DEFAULT_LISTEN_BACKLOG  6

I connect with winSCP to my ftp server on port 21 ( I'm not in passive mode )
The connection failed and retries are performed
For each retry pcb->accepts_pending is increased up to pcb->backlog
The problem is that it's never decreased : so when I want to make a correct ftp connexion in passive mode , the connection fails.

At start

Active PCB states:
                Local port 23, foreign port 52064 snd_nxt 6934 rcv_nxt 1755408404 State: ESTABLISHED
Listen PCB states:
                Local port 21, foreign port 10 snd_nxt 0 rcv_nxt 3452816845 State: LISTEN
                Local port 23, foreign port 20 snd_nxt 0 rcv_nxt 3452816845 State: LISTEN


After retries:

Active PCB states:
                Local port 23, foreign port 52064 snd_nxt 7238 rcv_nxt 1755408410 State: ESTABLISHED
                Local port 21, foreign port 52115 snd_nxt 7824 rcv_nxt 3257071051 State: ESTABLISHED
                Local port 21, foreign port 52104 snd_nxt 7433 rcv_nxt 1725182136 State: CLOSE_WAIT
                Local port 21, foreign port 52088 snd_nxt 7149 rcv_nxt 4173042710 State: CLOSE_WAIT
                Local port 21, foreign port 52077 snd_nxt 6959 rcv_nxt 1606482214 State: CLOSE_WAIT
                Local port 21, foreign port 52069 snd_nxt 6881 rcv_nxt 2499358084 State: CLOSE_WAIT
Listen PCB states:
                Local port 21, foreign port 1290 snd_nxt 0 rcv_nxt 3452816845 State: LISTEN
                Local port 23, foreign port 20 snd_nxt 0 rcv_nxt 3452816845 State: LISTEN


After a while:

Active PCB states:
Local port 23, foreign port 52064 snd_nxt 7970 rcv_nxt 1755408416 State: ESTABLISHED
Listen PCB states:
Local port 21, foreign port 1290 snd_nxt 0 rcv_nxt 3452816845 State: LISTEN
Local port 23, foreign port 20 snd_nxt 0 rcv_nxt 3452816845 State: LISTEN


pcb->accepts_pending  = 5 !!!!

I think it's not a correct behaviour...

Is there a solution ?

Regards

PIPON <harvey>

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

No files currently attached

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by jcunningham (Posted a comment)
  • -email is unavailable- added by harvey (Submitted the item)
  •  

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

     

    Follow 3 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2016-01-11 jcunningham StatusNone Invalid
        Assigned toNone jcunningham
        Open/ClosedOpen Closed

    Back to the top

    Powered by Savane 3.13-02a9.
    Corresponding source code