lwip-users
[Top][All Lists]
Advanced

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

Re: [lwip-users] slip recvs corrupted packets


From: Chris Frost
Subject: Re: [lwip-users] slip recvs corrupted packets
Date: Mon, 3 Jan 2005 22:41:36 -0600
User-agent: Mutt/1.3.28i

On Wed, Dec 15, 2004 at 12:15:01PM +0100, address@hidden wrote:
> > These two example ip headers probably don't say anything obvious, but I
> was
> > curious if they might?
> 
> The IP checksum failure could be caused
> by a malfunction in the slip driver.
> 
> I'm unfamliar with this code, but if it is true what you say
> "slipf_loop() appears to be designed for  multithread programs"
> then this might be the culprit.

Thanks for this suggestion, this lead to my finding the problem and correcting
not long after your message. (That next day I had lwip pingable and tcp
mostly working, thank you!)


The problem and my solution, in case it might be helpful for others:

lwip's slipif driver is designed to use threads, but I wanted all of lwip
to run in one process as my port isn't multithreaded [yet]. The solution
is pretty straightforward, instead of using two threads and letting the
os do scheduling, I changed slipif slightly to be able to run an iteration
at a time and run an iteration inside of the loop that calls tcp_tmr().

More specifically, I added a new slipif_loop_iter() to use instead of
slipif_loop():

static void
slipif_loop(void *nf)
{
  struct pbuf *p;
  struct netif *netif = (struct netif *)nf;

  while (1) {
    p = slipif_input(netif);
    netif->input(p, netif);
  }
}

void
slipif_loop_iter(struct netif *nif)
{
        struct pbuf *p;
        p = slipif_input(nif);
        if(p != NULL)
                nif->input(p, nif);
}

I call slipif_loop_iter() very frequently from within the tight loop that
already calls tcp_[fast|slow]tmr() every TCP_[FAST|SLOW]_INTERVAL.

My other modification is to slipif_input(). Originally, this function had
a loop that would run until an entire packet came across the link (switch
case SLIP_END). As this might take a while, I modified this function and
the way my sio_recv() works. sio_recv() now also notes (via netif->state)
when there was no data to return. When this is the case, slipif_input()
saves the state of its local variables (q, p, recved, i, and c) so
that they can be restored the next time slipif_input() is entered, and
returns NULL. You'll notice that the new slipif_loop_iter() checks for NULL
and returns without calling nif->input() when NULL is seen. Note that
both points in slipif_input() that call sio_recv() should check for no
available data and save state and return.

This appears to be all that is needed to single-thread slipif.


While this allowed me to telnet to my lwip-http server and request
resources without problem, the "GET ..." packets from a real browser
were getting corrupted. I wanted to say thanks to Christiaan Simons,
whose "initialisation of lwIP" email on 12/23/2004 pointed me to
fixing this problem: I increased the size of MEM_SIZE and
PBUF_POOL_BUFSIZE. Thanks! My understanding is that PBUF_POOL_BUFSIZE
should be large enough to hold largest packet (plus mac frame) a host
may see.


Next in my port of lwip, I'd like to add multiple-process support and
bsd sockets to lwip in our os, reading how the socket interface
already implemented for lwip works and designing how to interface this
with our os's ipc mechanisms are my next steps.

-- 
Chris Frost  |  <http://www.frostnet.net/chris/>
-------------+----------------------------------
Public PGP Key:
   Email address@hidden with the subject "retrieve pgp key"
   or visit <http://www.frostnet.net/chris/about/pgp_key.phtml>




reply via email to

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