Skip to content
This repository was archived by the owner on Dec 20, 2023. It is now read-only.

Commit e3daab3

Browse files
author
Jay Logue
authored
Merge pull request #384 from openweave/issue/reuseaddr-not-set
Fix for issue#383: UDPEndPoint not setting REUSEADDR on later LwIP versions
2 parents d42cdfa + 7f603cc commit e3daab3

File tree

1 file changed

+42
-66
lines changed

1 file changed

+42
-66
lines changed

src/inet/UDPEndPoint.cpp

Lines changed: 42 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -508,106 +508,82 @@ void UDPEndPoint::HandleDataReceived(PacketBuffer *msg)
508508

509509
INET_ERROR UDPEndPoint::GetPCB(IPAddressType addrType)
510510
{
511-
INET_ERROR lRetval = INET_NO_ERROR;
511+
INET_ERROR err = INET_NO_ERROR;
512512

513513
// IMPORTANT: This method MUST be called with the LwIP stack LOCKED!
514514

515-
#if LWIP_VERSION_MAJOR > 1 || LWIP_VERSION_MINOR >= 5
515+
// If a PCB hasn't been allocated yet...
516516
if (mUDP == NULL)
517517
{
518-
switch (addrType)
518+
// Allocate a PCB of the appropriate type.
519+
if (addrType == kIPAddressType_IPv6)
519520
{
520-
case kIPAddressType_IPv6:
521+
#if LWIP_VERSION_MAJOR > 1 || LWIP_VERSION_MINOR >= 5
522+
mUDP = udp_new_ip_type(IPADDR_TYPE_V6);
523+
#else // LWIP_VERSION_MAJOR <= 1 && LWIP_VERSION_MINOR < 5
524+
mUDP = udp_new_ip6();
525+
#endif // LWIP_VERSION_MAJOR <= 1 || LWIP_VERSION_MINOR >= 5
526+
}
521527
#if INET_CONFIG_ENABLE_IPV4
522-
case kIPAddressType_IPv4:
528+
else if (addrType == kIPAddressType_IPv4)
529+
{
530+
#if LWIP_VERSION_MAJOR > 1 || LWIP_VERSION_MINOR >= 5
531+
mUDP = udp_new_ip_type(IPADDR_TYPE_V4);
532+
#else // LWIP_VERSION_MAJOR <= 1 && LWIP_VERSION_MINOR < 5
533+
mUDP = udp_new();
534+
#endif // LWIP_VERSION_MAJOR <= 1 || LWIP_VERSION_MINOR >= 5
535+
}
523536
#endif // INET_CONFIG_ENABLE_IPV4
524-
mUDP = udp_new_ip_type(IPAddress::ToLwIPAddrType(addrType));
525-
break;
526-
527-
default:
528-
lRetval = INET_ERROR_WRONG_ADDRESS_TYPE;
529-
goto exit;
537+
else
538+
{
539+
ExitNow(err = INET_ERROR_WRONG_ADDRESS_TYPE);
530540
}
531541

542+
// Fail if the system has run out of PCBs.
532543
if (mUDP == NULL)
533544
{
534-
WeaveLogError(Inet, "udp_new_ip_type failed");
535-
lRetval = INET_ERROR_NO_MEMORY;
536-
goto exit;
537-
}
538-
else
539-
{
540-
mLwIPEndPointType = kLwIPEndPointType_UDP;
545+
WeaveLogError(Inet, "Unable to allocate UDP PCB");
546+
ExitNow(err = INET_ERROR_NO_MEMORY);
541547
}
548+
549+
// Allow multiple bindings to the same port.
550+
ip_set_option(mUDP, SOF_REUSEADDR);
542551
}
552+
553+
// Otherwise, verify that the existing PCB is the correct type...
543554
else
544555
{
545-
const lwip_ip_addr_type lLwIPAddrType = static_cast<lwip_ip_addr_type>(IP_GET_TYPE(&mUDP->local_ip));
556+
IPAddressType pcbAddrType;
546557

547-
switch (lLwIPAddrType)
558+
// Get the address type of the existing PCB.
559+
#if LWIP_VERSION_MAJOR > 1 || LWIP_VERSION_MINOR >= 5
560+
switch (static_cast<lwip_ip_addr_type>(IP_GET_TYPE(&mUDP->local_ip)))
548561
{
549562
case IPADDR_TYPE_V6:
550-
VerifyOrExit(addrType == kIPAddressType_IPv6, lRetval = INET_ERROR_WRONG_ADDRESS_TYPE);
563+
pcbAddrType = kIPAddressType_IPv6;
551564
break;
552-
553565
#if INET_CONFIG_ENABLE_IPV4
554566
case IPADDR_TYPE_V4:
555-
VerifyOrExit(addrType == kIPAddressType_IPv4, lRetval = INET_ERROR_WRONG_ADDRESS_TYPE);
567+
pcbAddrType = kIPAddressType_IPv4;
556568
break;
557569
#endif // INET_CONFIG_ENABLE_IPV4
558-
559570
default:
560-
break;
571+
ExitNow(err = INET_ERROR_WRONG_ADDRESS_TYPE);
561572
}
562-
}
563573
#else // LWIP_VERSION_MAJOR <= 1 && LWIP_VERSION_MINOR < 5
564-
if (mUDP == NULL)
565-
{
566-
if (addrType == kIPAddressType_IPv6)
567-
{
568-
mUDP = udp_new_ip6();
569-
if (mUDP != NULL)
570-
ip_set_option(mUDP, SOF_REUSEADDR);
571-
}
572574
#if INET_CONFIG_ENABLE_IPV4
573-
else if (addrType == kIPAddressType_IPv4) {
574-
mUDP = udp_new();
575-
}
576-
#endif // INET_CONFIG_ENABLE_IPV4
577-
else
578-
{
579-
lRetval = INET_ERROR_WRONG_ADDRESS_TYPE;
580-
goto exit;
581-
}
582-
583-
if (mUDP == NULL)
584-
{
585-
WeaveLogError(Inet, "udp_new failed");
586-
lRetval = INET_ERROR_NO_MEMORY;
587-
goto exit;
588-
}
589-
else
590-
{
591-
mLwIPEndPointType = kLwIPEndPointType_UDP;
592-
}
593-
}
594-
else
595-
{
596-
#if INET_CONFIG_ENABLE_IPV4
597-
const IPAddressType pcbType = PCB_ISIPV6(mUDP) ? kIPAddressType_IPv6 : kIPAddressType_IPv4;
575+
pcbAddrType = PCB_ISIPV6(mUDP) ? kIPAddressType_IPv6 : kIPAddressType_IPv4;
598576
#else // !INET_CONFIG_ENABLE_IPV4
599-
const IPAddressType pcbType = kIPAddressType_IPv6;
577+
pcbAddrType = kIPAddressType_IPv6;
600578
#endif // !INET_CONFIG_ENABLE_IPV4
579+
#endif // LWIP_VERSION_MAJOR <= 1 && LWIP_VERSION_MINOR < 5
601580

602-
if (addrType != pcbType) {
603-
lRetval = INET_ERROR_WRONG_ADDRESS_TYPE;
604-
goto exit;
605-
}
581+
// Fail if the existing PCB is not the correct type.
582+
VerifyOrExit(addrType == pcbAddrType, err = INET_ERROR_WRONG_ADDRESS_TYPE);
606583
}
607-
#endif // LWIP_VERSION_MAJOR <= 1 || LWIP_VERSION_MINOR >= 5
608584

609585
exit:
610-
return (lRetval);
586+
return err;
611587
}
612588

613589
#if LWIP_VERSION_MAJOR > 1 || LWIP_VERSION_MINOR >= 5

0 commit comments

Comments
 (0)