Renasis:
What you are experiencing is either a bug in the uIP stack or a bug in the WiShield fork of the uIP stack. I also experienced your confusion that varying source ports seem to 'lock' the listening port to receiving only from that source port.
After reading the uIP source provided by AsyncLabs, I found this problem:
In uip.c, around line 1150 (I've modified my version of uIP)
- Code: Select all
udp_found:
if (uip_udp_conn->rport == 0) {
uip_udp_conn->rport = UDPBUF->srcport;
}
The udp_found label is called whenever an incoming UDP datagram is found that matches the listening connection. If the rport (the source port) is 0, it sets it to the current incoming source port.
Now, let's look at an earlier check that decides whether or not to jump to udp_found. This check is performed on every listening port, and it decides if the incoming UDP datagram is destined for this listener (starting at line 1130):
- Code: Select all
/* If the local UDP port is non-zero, the connection is considered
to be used. If so, the local port number is checked against the
destination port number in the received packet. If the two port
numbers match, the remote port number is checked if the
connection is bound to a remote port. Finally, if the
connection is bound to a remote IP address, the source IP
address of the packet is checked. */
if(uip_udp_conn->lport != 0 &&
UDPBUF->destport == uip_udp_conn->lport &&
(uip_udp_conn->rport == 0 ||
UDPBUF->srcport == uip_udp_conn->rport) &&
(uip_ipaddr_cmp(uip_udp_conn->ripaddr, all_zeroes_addr) ||
uip_ipaddr_cmp(uip_udp_conn->ripaddr, all_ones_addr) ||
uip_ipaddr_cmp(BUF->srcipaddr, uip_udp_conn->ripaddr))) {
goto udp_found;
Let's focus on these two lines of that conditional:
- Code: Select all
(uip_udp_conn->rport == 0 ||
UDPBUF->srcport == uip_udp_conn->rport) &&
Basically, the packet is a valid packet for the current UDP connection if the source port is 0, or if the incoming source port matches the previously set source port.
So this confirms the behavior that you are seeing. After the first incoming UDP datagram, the listening port is 'locked' to the source port that was originally sent. Any subsequent UDP datagrams coming from your application will not likely have the same source port so they will be ignored.
I checked the latest version of uIP and in uip.c the bug is not present. In the latest version they do not set the source port to the current source port if it is zero.
If you would like for the TCP/IP stack to do what it is supposed to when binding to a UDP port, then simply remove these 3 lines from uip.c:
- Code: Select all
if (uip_udp_conn->rport == 0) {
uip_udp_conn->rport = UDPBUF->srcport;
}
Regards,
RJ Ryan