[udp6] use newly added linked-list to search for a matching socket (#5180)
This commit adds `UdpSocket::Matches()` to match a UDP socket with a
given `MessageInfo`. This is then used alongw with the newly added
linked-list `FindMatching()` method to find a matching socket from the
list of UDP sockets in `Udp::HandlePayload()`.
diff --git a/src/core/net/udp6.cpp b/src/core/net/udp6.cpp
index 0e9e498..9b74765 100644
--- a/src/core/net/udp6.cpp
+++ b/src/core/net/udp6.cpp
@@ -202,6 +202,32 @@
return error;
}
+bool UdpSocket::Matches(const MessageInfo &aMessageInfo) const
+{
+ bool matches = false;
+
+ VerifyOrExit(GetSockName().mPort == aMessageInfo.GetSockPort(), OT_NOOP);
+
+ VerifyOrExit(aMessageInfo.GetSockAddr().IsMulticast() || GetSockName().GetAddress().IsUnspecified() ||
+ GetSockName().GetAddress() == aMessageInfo.GetSockAddr(),
+ OT_NOOP);
+
+ // Verify source if connected socket
+ if (GetPeerName().mPort != 0)
+ {
+ VerifyOrExit(GetPeerName().mPort == aMessageInfo.GetPeerPort(), OT_NOOP);
+
+ VerifyOrExit(GetPeerName().GetAddress().IsUnspecified() ||
+ GetPeerName().GetAddress() == aMessageInfo.GetPeerAddr(),
+ OT_NOOP);
+ }
+
+ matches = true;
+
+exit:
+ return matches;
+}
+
Udp::Udp(Instance &aInstance)
: InstanceLocator(aInstance)
, mEphemeralPort(kDynamicPortMin)
@@ -341,40 +367,18 @@
void Udp::HandlePayload(Message &aMessage, MessageInfo &aMessageInfo)
{
- // find socket
- for (UdpSocket *socket = mSockets.GetHead(); socket; socket = socket->GetNext())
- {
- if (socket->GetSockName().mPort != aMessageInfo.GetSockPort())
- {
- continue;
- }
+ UdpSocket *socket;
+ UdpSocket *prev;
- if (!aMessageInfo.GetSockAddr().IsMulticast() && !socket->GetSockName().GetAddress().IsUnspecified() &&
- socket->GetSockName().GetAddress() != aMessageInfo.GetSockAddr())
- {
- continue;
- }
+ socket = mSockets.FindMatching(aMessageInfo, prev);
+ VerifyOrExit(socket != nullptr, OT_NOOP);
- // verify source if connected socket
- if (socket->GetPeerName().mPort != 0)
- {
- if (socket->GetPeerName().mPort != aMessageInfo.GetPeerPort())
- {
- continue;
- }
+ aMessage.RemoveHeader(aMessage.GetOffset());
+ OT_ASSERT(aMessage.GetOffset() == 0);
+ socket->HandleUdpReceive(aMessage, aMessageInfo);
- if (!socket->GetPeerName().GetAddress().IsUnspecified() &&
- socket->GetPeerName().GetAddress() != aMessageInfo.GetPeerAddr())
- {
- continue;
- }
- }
-
- aMessage.RemoveHeader(aMessage.GetOffset());
- OT_ASSERT(aMessage.GetOffset() == 0);
- socket->HandleUdpReceive(aMessage, aMessageInfo);
- break;
- }
+exit:
+ return;
}
void Udp::UpdateChecksum(Message &aMessage, uint16_t aChecksum)
diff --git a/src/core/net/udp6.hpp b/src/core/net/udp6.hpp
index b56a7ea..cca7cbe 100644
--- a/src/core/net/udp6.hpp
+++ b/src/core/net/udp6.hpp
@@ -94,6 +94,7 @@
class UdpSocket : public otUdpSocket, public InstanceLocator, public LinkedListEntry<UdpSocket>
{
friend class Udp;
+ friend class LinkedList<UdpSocket>;
public:
/**
@@ -189,6 +190,14 @@
SockAddr &GetSockName(void) { return *static_cast<SockAddr *>(&mSockName); }
/**
+ * This method returns the local socket address.
+ *
+ * @returns A reference to the local socket address.
+ *
+ */
+ const SockAddr &GetSockName(void) const { return *static_cast<const SockAddr *>(&mSockName); }
+
+ /**
* This method returns the peer's socket address.
*
* @returns A reference to the peer's socket address.
@@ -196,7 +205,17 @@
*/
SockAddr &GetPeerName(void) { return *static_cast<SockAddr *>(&mPeerName); }
+ /**
+ * This method returns the peer's socket address.
+ *
+ * @returns A reference to the peer's socket address.
+ *
+ */
+ const SockAddr &GetPeerName(void) const { return *static_cast<const SockAddr *>(&mPeerName); }
+
private:
+ bool Matches(const MessageInfo &aMessageInfo) const;
+
void HandleUdpReceive(Message &aMessage, const MessageInfo &aMessageInfo)
{
mHandler(mContext, &aMessage, &aMessageInfo);