udp.c: Simplify and cleanup input PCB matching

This commit is contained in:
Dirk Ziegelmeier 2016-02-24 19:13:30 +01:00
parent 3b5803ec9a
commit 005c196ed8

View File

@ -161,7 +161,7 @@ udp_input(struct pbuf *p, struct netif *inp)
#if LWIP_IPV4 #if LWIP_IPV4
u8_t broadcast; u8_t broadcast;
#endif /* LWIP_IPV4 */ #endif /* LWIP_IPV4 */
u8_t for_us; u8_t for_us = 0;
LWIP_UNUSED_ARG(inp); LWIP_UNUSED_ARG(inp);
@ -242,50 +242,52 @@ udp_input(struct pbuf *p, struct netif *inp)
/* compare PCB local addr+port to UDP destination addr+port */ /* compare PCB local addr+port to UDP destination addr+port */
if (pcb->local_port == dest) { if (pcb->local_port == dest) {
if (
#if LWIP_IPV6 /* TODO: Add special dualstack case here */
(IP_IS_V6_VAL(pcb->local_ip) && ip_current_is_v6() &&
(ip6_addr_isany(ip_2_ip6(&pcb->local_ip)) || /* Only need to check PCB if incoming IP version matches PCB IP version */
#if LWIP_IPV6_MLD if(ip_current_is_v6() == IP_IS_V6_VAL(pcb->local_ip)) {
ip6_addr_ismulticast(ip6_current_dest_addr()) || LWIP_ASSERT("UDP PCB: inconsistent local/remote IP versions", IP_IS_V6_VAL(pcb->local_ip) == IP_IS_V6_VAL(pcb->remote_ip));
#endif /* LWIP_IPV6_MLD */
ip6_addr_cmp(ip_2_ip6(&pcb->local_ip), ip6_current_dest_addr())))
#endif /* LWIP_IPV6 */
#if LWIP_IPV4 && LWIP_IPV6
|| (!IP_IS_V6_VAL(pcb->local_ip) &&
(ip4_current_header() != NULL) &&
#endif /* LWIP_IPV4 && LWIP_IPV6 */
#if LWIP_IPV4 #if LWIP_IPV4
#if !LWIP_IPV6 /* Special case: IPv4 broadcast: all or broadcasts in my subnet
( * Note: broadcast variable can only be 1 if it is an IPv4 broadcast */
#endif /* !LWIP_IPV6 */ if(broadcast != 0) {
((!broadcast && ip_addr_isany(&pcb->local_ip)) ||
ip_addr_cmp(&pcb->local_ip, ip_current_dest_addr()) ||
#if LWIP_IGMP
(ip_addr_isany(&pcb->local_ip) && ip_addr_ismulticast(ip_current_dest_addr())) ||
#endif /* LWIP_IGMP */
#if IP_SOF_BROADCAST_RECV #if IP_SOF_BROADCAST_RECV
(broadcast && ip_get_option(pcb, SOF_BROADCAST) && if(ip_get_option(pcb, SOF_BROADCAST))
(ip_addr_isany(&pcb->local_ip) ||
ip_addr_netcmp(&pcb->local_ip, ip_current_dest_addr(), netif_ip4_netmask(inp))))))
#else /* IP_SOF_BROADCAST_RECV */
(broadcast &&
(ip_addr_isany(&pcb->local_ip) ||
ip_addr_netcmp(&pcb->local_ip, ip_current_dest_addr(), netif_ip4_netmask(inp))))))
#endif /* IP_SOF_BROADCAST_RECV */ #endif /* IP_SOF_BROADCAST_RECV */
#endif /* LWIP_IPV4 */ {
) { if(ip4_addr_isany(ip_2_ip4(&pcb->local_ip)) ||
ip4_addr_netcmp(ip_2_ip4(&pcb->local_ip), ip4_current_dest_addr(), netif_ip4_netmask(inp))) {
local_match = 1; local_match = 1;
}
}
} else
#endif /* LWIP_IPV4 */
{
/* Handle IPv4 and IPv6: all, multicast or exact match */
if(ip_addr_isany(&pcb->local_ip) ||
#if LWIP_IPV6_MLD
(ip_current_is_v6() && ip6_addr_ismulticast(ip6_current_dest_addr())) ||
#endif /* LWIP_IPV6_MLD */
#if LWIP_IGMP
(!ip_current_is_v6() && ip4_addr_ismulticast(ip4_current_dest_addr())) ||
#endif /* LWIP_IGMP */
ip_addr_cmp(&pcb->local_ip, ip_current_dest_addr())) {
local_match = 1;
}
}
}
if(local_match != 0) {
if ((uncon_pcb == NULL) && if ((uncon_pcb == NULL) &&
((pcb->flags & UDP_FLAGS_CONNECTED) == 0)) { ((pcb->flags & UDP_FLAGS_CONNECTED) == 0)) {
/* the first unconnected matching PCB */ /* the first unconnected matching PCB */
uncon_pcb = pcb; uncon_pcb = pcb;
} }
}
}
/* compare PCB remote addr+port to UDP source addr+port */ /* compare PCB remote addr+port to UDP source addr+port */
if ((local_match != 0) && if ((pcb->remote_port == src) &&
(pcb->remote_port == src) && (ip_current_is_v6() == IP_IS_V6_VAL(pcb->remote_ip)) &&
(ip_addr_isany_val(pcb->remote_ip) || (ip_addr_isany_val(pcb->remote_ip) ||
ip_addr_cmp(&pcb->remote_ip, ip_current_src_addr()))) { ip_addr_cmp(&pcb->remote_ip, ip_current_src_addr()))) {
/* the first fully matching PCB */ /* the first fully matching PCB */
@ -300,6 +302,9 @@ udp_input(struct pbuf *p, struct netif *inp)
} }
break; break;
} }
}
}
prev = pcb; prev = pcb;
} }
/* no fully matching pcb found? then look for an unconnected pcb */ /* no fully matching pcb found? then look for an unconnected pcb */
@ -316,16 +321,14 @@ udp_input(struct pbuf *p, struct netif *inp)
if (ip_current_is_v6()) { if (ip_current_is_v6()) {
for_us = netif_get_ip6_addr_match(inp, ip6_current_dest_addr()) >= 0; for_us = netif_get_ip6_addr_match(inp, ip6_current_dest_addr()) >= 0;
} }
#if LWIP_IPV4
else
#endif /* LWIP_IPV4 */
#endif /* LWIP_IPV6 */ #endif /* LWIP_IPV6 */
#if LWIP_IPV4 #if LWIP_IPV4
{ if (!ip_current_is_v6()) {
for_us = ip4_addr_cmp(netif_ip4_addr(inp), ip4_current_dest_addr()); for_us = ip4_addr_cmp(netif_ip4_addr(inp), ip4_current_dest_addr());
} }
#endif /* LWIP_IPV4 */ #endif /* LWIP_IPV4 */
} }
if (for_us) { if (for_us) {
LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_input: calculating checksum\n")); LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_input: calculating checksum\n"));
#if CHECKSUM_CHECK_UDP #if CHECKSUM_CHECK_UDP