lwip-users
[Top][All Lists]
Advanced

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

[lwip-users] Re: [lwip] udp server problem (possible problem with pcb->


From: Lars Kanis
Subject: [lwip-users] Re: [lwip] udp server problem (possible problem with pcb->remote_ip)
Date: Wed, 08 Jan 2003 23:38:05 -0000

Hi Dave

Am Donnerstag, 22. August 2002 04:11 schrieb David Figueroa:
> I have noticed there might be a problem with udp, else maybe I'm
> overlooking something trivial.
>
> Once the server has bound to a port and is "receiving"
>
> The first and subsequent requests from the same ip source works just fine.
>
> The second and subsequent requests from a different ip source does not get
> accepted.
>
> This is because the "listening" pcb is now set to the first guy's ip
> address.  This is set by the udp_connect function:
>
> err_t
> udp_connect(struct udp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
> {
>   struct udp_pcb *ipcb;
>   ip_addr_set(&pcb->remote_ip, ipaddr);
>   pcb->remote_port = port;
>
> ...
>
> Therefore whenever a new udp packet arrives (and port matches) from a
> different ip address it will be rejected because the remote ip address in
> pcb (pcb->remote_ip) is no longer NULL i.e. "ip_addr_isany" (in udp_input -
> there are 6 different checks to accept/reject udp request).

Thats the correct behaviour. BSD sockets do nothing else. A udp_pcb is 
"listening" to all incomming packets as long as you do not connect it to a 
address/port pair.

> I have temporarily fixed this by clearing out the pcb->remote_ip after the
> "ip_output_if" call in udp_send.
>
>
>     err = ip_output_if(p, src_ip, &pcb->remote_ip, UDP_TTL, IP_PROTO_UDP,
> netif);
>   }
>
>   /**** df temporary fix  ****/
>
>   ip_addr_set(&pcb->remote_ip, NULL);
>   pcb->remote_port = 0;
>
>   /**** end df temporary fix ****/
>
> #ifdef UDP_STATS
>   ++stats.udp.xmit;
> #endif /* UDP_STATS */
>   return err;
> }
>
> but this cannot be correct.  Should there be a new pcb created to accept
> the new udp request?  If so how is this done? And also why can't the
> existing pcb be re-used (as I am doing now).  Surely new udp clients should
> not cause the pcb list to grow indefinitely...

Yes, You have to use a "listen" pcb for reception of any udp packets and a 
connected pcb to answer back to a the sender. Thats what BSD sockets 
requires, too.
You can unconnect/unbind a pcb only by udp_remove() and recall udp_new().

Nevertheless there is a bug in the sources. The selection which pcb recieves 
which packet is made in udp_input(). If you do not connect to a remote port, 
all incomming packets that do not match exactly should go to this pcb. This 
depends in the order of the pcb's without the following patch:

  if(pcb == NULL) {
    for(pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) {
      DEBUGF(UDP_DEBUG, ("udp_input: pcb local port %d (dgram %d)\n",
                         pcb->local_port, dest));
-      if(pcb->local_port == dest &&
+      if(pcb->remote_port == 0 &&
+       pcb->local_port == dest &&
         (ip_addr_isany(&pcb->remote_ip) ||
          ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src))) &&
         (ip_addr_isany(&pcb->local_ip) ||
          ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest)))) {
        break;
      }      
    }
  }

I hope I could help you.

Regards
Lars Kanis

By the way: I started a documentation of the lwIP. You should look at 
http://people.freenet.de/l.kanis/index.html for the result, so far.
The sources in doxygen-style may go in the new open repositiory if anyone who 
has write access does it.

[This message was sent through the lwip discussion list.]




reply via email to

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