lwip-users
[Top][All Lists]
Advanced

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

Re: [lwip-users] Handling sudden disappearance of network i/f


From: Pedro Alves
Subject: Re: [lwip-users] Handling sudden disappearance of network i/f
Date: Mon, 25 Sep 2006 10:24:03 +0100
User-agent: Mozilla Thunderbird 1.0.2 (Windows/20050317)

Clive Wilson wrote:
At 11:24 19/09/2006, you wrote:

On Mon, 2006-09-18 at 13:00 +0100, address@hidden wrote:
> Hello,
>
> I have a problem whereby if the low-level comms supporting a network
> interface I'm using for LwIP suddenly (and unexpectedly) disappears,
> the upper stack layers don't seem to be becoming aware of this. I'm
> using the PPP network interface, but I don't think that should make
> any difference to the question in principle.
>
> I am able to determine when the data channel goes down (via a
> callback), so can anyone say if there is a variable or data member in
> the upper layers that I should be modifiying on this event, to
> indicate that there is no longer a means of tx'ing/rx'ing packets?
> Perhaps the variable is actually in the network layer (PPP in this
> instance)?

Are you hoping to notify the application, or TCP/IP layers?  TCP/IP
would do very little with this information as it tries to be resilient
across temporary network outages.  E.g. if you unplug an ethernet cable,
then plug it back in again after a few seconds, the TCP connections will
all still be there.  There are timer mechanisms that try to notice if a
link has gone away for longer than you're willing to wait (in order that
the connection gets closed locally and so frees resources).

If the physical layer has really gone away for good, I think the
appropriate action would be to unconfigure the network interface, using
netif_remove() (I think - haven't checked the source).


Kieran,

Yes, in the LwIP PPP layer I'm using ipcp_down(), which calls sifdown(), which in turn calls netif_remove().

Unfortunately, this doesn't have the desired result. If the serial link that LwIP's PPP layer depends upon suddenly disappears, then on this event I call pppSigHUP to inform PPP of the low-level link's absence. This in turn calls netif_remove as you mention. However, if a socket call such as read(), write() etc is made after the serial link dies, I don't see these calls returning with an error to indicate a timeout waiting for response. Is this how they should respond? I assume that there is some kind of retransmission limit for un-ACKed outgoing packets, after which the socket API calls return with a failure. What I am actually seeing is my app hanging forever for response to some data it thinks it has sent, when in fact the data went nowhere.

I would be very grateful if someone could advise whether I have the wrong end of the stick with this.


You can use something like the attached file implements to close
all the sockets associated with an interface, or with all interfaces.
I'm not sure if it is safe to use when using the sockets api, but I
guess it should.
You could call this on your 'PPP connection is closed forever' callback.

This is based on code I found somewhere else, but unfortunately I lost
the reference.

Cheers,
Pedro Alves

#include <lwip/netif.h>
#include <lwip/sys.h>
#include <lwip/pbuf.h>
#include <lwip/tcp.h>
#include <lwip/tcpip.h>
#include <lwip/netif.h>
#include <lwip/ip.h>

/* If NULL is passed, aborts for all interfaces.  */
void lwip_abort_all (struct netif *netif)
{
  /* Handling of obsolete pcbs.  */
  struct tcp_pcb *pcb = tcp_active_pcbs;
  while(pcb != NULL)
  {
    if(!netif || ip_addr_cmp (&(pcb->local_ip), &(netif->ip_addr)))
    {
      /* The PCB is connected using the old ipaddr and must be aborted.  */
      struct tcp_pcb *next = pcb->next;
      tcp_abort(pcb);
      pcb = next;
    }
    else
      pcb = pcb->next;
  }
  
  struct tcp_pcb_listen* lpcb = tcp_listen_pcbs.listen_pcbs;
  while(pcb != NULL)
  {
    if(!netif || ip_addr_cmp (&(lpcb->local_ip), &(netif->ip_addr)))
    {
      /* The PCB is connected using the old ipaddr and must be aborted.  */
      struct tcp_pcb_listen *next = lpcb->next;
      tcp_abort (pcb);
      lpcb = next;
    }
    else
      lpcb = lpcb->next;
  }
}

reply via email to

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