[En-Nut-Discussion] ICMP echo request response failure on ARP cache timeout

Nathan Moore nategoose at gmail.com
Fri Jun 5 16:38:38 CEST 2009

Hey Harald,

> > Every time I try to do much that involves the TCP state machine thread my
> > head
> > explodes, so I don't pretend to understand all of it's internals.
> TCP is a complex beast. In opposite to other parts of Nut/OS, the TCP
> state machine had been written in the first place with the human reader
> in mind, using a specific function for each state. Some parts could have
> been optimized to create less code. But none of the contributors ever
> had the courage to work it out. There are many things that may go
> miserably wrong. And many things did go wrong in the past. I remember
> some very nasty and long living bugs in this area.

It's like reading lisp -- very easy to get lost in, even if you understand
it in theory.
PPP is the same way.

> >> We'd still need a TCP state machine thread to handle re-transmissions.
> >> That one could be simpler than the combined timing/handler loop used
> >> right now.
> >
> > Since you now do protocol registration you could make part of that
> > registration
> > a callback to a periodically called function and a pointer to it's data
> --
> > the TCP
> > thread could turn into one of these functions, and a more generic IP
> > transmission
> > thread would call it.
> I can't comment on this right now, without having a clearer picture of
> the general structure.

This is similar to the chain of protocols I mentioned for Ethernet.  It
walk a list of transport layer structures and decide if it should call each
transport layer's periodic/timer handler function and pass that function
a pointer to something (maybe this entry in the protocol chain) that would
allow it to do something.  For TCP this would be call a function which is
essentially the TCP state machine thread function and it's argument would
allow it to access the socket list.  For UDP, ICMP, and IGMP this might be
a NULL pointer (and not called).
I hope this is clearer.
If you extend this concept when you register a transport layer protocol over
IP the structure could have pointers to the input routine and periodic/state
routine.  Then introducing new protocols would be very modularized.
struct ip_transport {
   struct ip_transport *next;
   uint32_t periodic_next_time; // next time to call the periodic()
   ... whatever else generic transport stuff ...
   ... transport protocol specific stuff (either by void* or by tacking it
onto the tail of this struct) ...
extern struct ip_transport * ip_protocols;

> I recently removed CONFNET saving from the system routines. I wasn't
> aware of the PPP problem, but recognized, that many people got confused
> by this "feature". If the application uses the wrong function call
> sequence, they may end up with the hard coded values overwriting a valid
> EEPROM contents (I think the ftpd sample has or had this problem too).
> Now the application must explicitly call NutSaveConfig to store new
> settings.
> I'll have a look at the current code.

> > For ethernet you could have a chain of protocols which each had a queue
> of
> > packets (netbufs).
> > These chain links could be made of (raw, IPv4).  The Ethernet TX thread
> > would do different
> > things based on which link a packet was under.  Raw packets would just be
> > sent, while IP packets
> > would be fed through ARP.  If an arp request needed to be made then that
> arp
> > request would be
> > appended to the RAW queue (unless there was an outstanding request
> already).
> >  If the IP packet
> > was ready to send then it's ethernet header would be completed and that
> > packet would become a
> > RAW packet, and be placed in the raw queue.  Essentially only things in
> the
> > RAW queue can be
> > sent to the device.
> Sounds interesting enough to give it a try.
> > I had thought about using a linked list or tree-like structure for
> netbufs
> > (maybe even
> > with reference counting and garbage collection).  That would be a huge
> Well, there are many things to try before thinking about garbage
> collection. Indeed, re-using packet headers on multiple packets is
> something I thought about too. It doesn't actually require garbage
> collection, but just the reference counter.

Yeah -- I was just thinking about GC using reference counting.  Something
like mark and sweep would interfere with use of the heap by everything else,
and I'm pretty sure that would never work on AVR because pointers are
multibyte.  You'd have to make sure that pointers were completely stored
in at least one location before you could do GC or you might reclaim RAM
only for some code to later move the 2 bytes of the pointer back together
and dereference it later.  Plus it takes a good bit of resources to do GC.


More information about the En-Nut-Discussion mailing list