udp_bind: Omit checking for the same port if no port specified

No port specified means to use a random port.
udp_new_port() returns a new (free) local UDP port number on success.
So in this case we don't need iterating all lists to test if the port
number is used, udp_new_port() alreay ensures the port is not used.

Move the code checking for double bind and rebind of the same pcb earlier,
as this checking is necessary in all cases.

Signed-off-by: Axel Lin <axel.lin@ingics.com>
This commit is contained in:
Axel Lin 2016-01-13 08:32:40 +08:00 committed by Dirk Ziegelmeier
parent 123c8dbd6a
commit c2a74b767b

View File

@ -937,6 +937,16 @@ udp_bind(struct udp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port)
ip_addr_debug_print(UDP_DEBUG | LWIP_DBG_TRACE, ipaddr); ip_addr_debug_print(UDP_DEBUG | LWIP_DBG_TRACE, ipaddr);
LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, (", port = %"U16_F")\n", port)); LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, (", port = %"U16_F")\n", port));
rebind = 0;
/* Check for double bind and rebind of the same pcb */
for (ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) {
/* is this UDP PCB already on active list? */
if (pcb == ipcb) {
rebind = 1;
break;
}
}
/* no port specified? */ /* no port specified? */
if (port == 0) { if (port == 0) {
port = udp_new_port(); port = udp_new_port();
@ -945,38 +955,29 @@ udp_bind(struct udp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port)
LWIP_DEBUGF(UDP_DEBUG, ("udp_bind: out of free UDP ports\n")); LWIP_DEBUGF(UDP_DEBUG, ("udp_bind: out of free UDP ports\n"));
return ERR_USE; return ERR_USE;
} }
} } else {
for (ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) {
rebind = 0; if (pcb != ipcb) {
/* Check for double bind and rebind of the same pcb */ /* By default, we don't allow to bind to a port that any other udp
for (ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) { PCB is already bound to, unless *all* PCBs with that port have tha
/* is this UDP PCB already on active list? */ REUSEADDR flag set. */
if (pcb == ipcb) {
/* pcb may occur at most once in active list */
LWIP_ASSERT("rebind == 0", rebind == 0);
/* pcb already in list, just rebind */
rebind = 1;
}
/* By default, we don't allow to bind to a port that any other udp
PCB is already bound to, unless *all* PCBs with that port have tha
REUSEADDR flag set. */
#if SO_REUSE #if SO_REUSE
else if (!ip_get_option(pcb, SOF_REUSEADDR) || if (!ip_get_option(pcb, SOF_REUSEADDR) ||
!ip_get_option(ipcb, SOF_REUSEADDR)) { !ip_get_option(ipcb, SOF_REUSEADDR))
#else /* SO_REUSE */
/* port matches that of PCB in list and REUSEADDR not set -> reject */
else {
#endif /* SO_REUSE */ #endif /* SO_REUSE */
if ((ipcb->local_port == port) && IP_PCB_IPVER_EQ(pcb, ipcb) && {
/* IP address matches, or one is IP_ADDR_ANY? */ /* port matches that of PCB in list and REUSEADDR not set -> reject */
(ip_addr_isany(&ipcb->local_ip) || if ((ipcb->local_port == port) && IP_PCB_IPVER_EQ(pcb, ipcb) &&
ip_addr_isany(ipaddr) || /* IP address matches, or one is IP_ADDR_ANY? */
ip_addr_cmp(&ipcb->local_ip, ipaddr))) { (ip_addr_isany(&ipcb->local_ip) ||
/* other PCB already binds to this local IP and port */ ip_addr_isany(ipaddr) ||
LWIP_DEBUGF(UDP_DEBUG, ip_addr_cmp(&ipcb->local_ip, ipaddr))) {
("udp_bind: local port %"U16_F" already bound by another pcb\n", port)); /* other PCB already binds to this local IP and port */
return ERR_USE; LWIP_DEBUGF(UDP_DEBUG,
("udp_bind: local port %"U16_F" already bound by another pcb\n", port));
return ERR_USE;
}
}
} }
} }
} }