lwip-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lwip-users] Microblaze and lwIP


From: Kieran Mansley
Subject: Re: [lwip-users] Microblaze and lwIP
Date: Mon, 21 May 2007 15:09:32 +0100

On Mon, 2007-05-21 at 10:40 -0300, address@hidden wrote:
> Hi Kieran,
> 
> I looked into the use of TCP_NODELAY. If this option is set, the result is to 
> add TF_NODELAY to tcp->flags.
> 
> In api_msg.c in do_write() this flag is used as shown in the code fragment 
> below.
> 
>    case NETCONN_TCP:      
>       err = tcp_write(msg->conn->pcb.tcp, msg->msg.w.dataptr,
>                       msg->msg.w.len, msg->msg.w.copy);
>       /* This is the Nagle algorithm: inhibit the sending of new TCP
>    segments when new outgoing data arrives from the user if any
>    previously transmitted data on the connection remains
>    unacknowledged. */
>       if(err == ERR_OK && (msg->conn->pcb.tcp->unacked == NULL || (msg->conn-
> >pcb.tcp->flags & TF_NODELAY)) ) {
>                 tcp_output(msg->conn->pcb.tcp);
> 
> In my case tcp->unacked is always NULL (since I am only sending the one set 
> of 
> data) so the other condition is redundant.

Yes, I agree.  It was a colleague who suggested it and I was sceptical
that it was Nagle that was causing your particular problem, but I
thought it worth passing on.

> The function tcp_output() would 
> normally only send out only the one segment (the first segment which is full) 
> since the pcb->lastack will not get updated until the client responds and 
> updates this field
> 
>       while (seg != NULL &&
>            ( (ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len <= wnd) ) 

That's not quite true.  It will send as many segments as it can without
exceeding "wnd" bytes past pcb->last_ack.  This could be many segments,
not just one.  

> In my version the second segment is sent without delay since the flags are 
> now 
> set to include TCP_PSH.
> 
>      while (seg != NULL &&
>          ( (ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len <= wnd) 
> ||           (TCPH_FLAGS(seg->tcphdr) & TCP_PSH) )) 

The problem here is that if the PSH bit is set you're sending segments
even if you exceed wnd bytes past lastack.  This violates TCP's spec:
you're only allowed to send a certain number of bytes to a receiver
(that's what the window is for) until the receiver says "OK, send me
some more".  At the start of a connection the wnd value might be small,
but it should quickly increase so you can send many packets in one go
rather than just one at a time.  By ignoring this, you're bypassing the
mechanism that TCP uses to try and avoid packet loss, and so while it
sounds like it's helpful to you in your particular circumstance, it's
not a safe change to make.

Hope that helps you understand what's what.

Kieran





reply via email to

[Prev in Thread] Current Thread [Next in Thread]