otError Udp::RemoveSocket(UdpSocket &aSocket) { if (mSockets == &aSocket) { mSockets = mSockets->GetNext(); } else { for (UdpSocket *socket = mSockets; socket; socket = socket->GetNext()) { if (socket->GetNext() == &aSocket) { socket->SetNext(aSocket.GetNext()); break; } } } aSocket.SetNext(NULL); return OT_ERROR_NONE; }
otError Udp::AddSocket(UdpSocket &aSocket) { for (UdpSocket *cur = mSockets; cur; cur = cur->GetNext()) { if (cur == &aSocket) { ExitNow(); } } aSocket.SetNext(mSockets); mSockets = &aSocket; exit: return OT_ERROR_NONE; }
otError Udp::HandleMessage(Message &aMessage, MessageInfo &aMessageInfo) { otError error = OT_ERROR_NONE; UdpHeader udpHeader; uint16_t payloadLength; uint16_t checksum; payloadLength = aMessage.GetLength() - aMessage.GetOffset(); // check length VerifyOrExit(payloadLength >= sizeof(UdpHeader), error = OT_ERROR_PARSE); // verify checksum checksum = Ip6::ComputePseudoheaderChecksum(aMessageInfo.GetPeerAddr(), aMessageInfo.GetSockAddr(), payloadLength, kProtoUdp); checksum = aMessage.UpdateChecksum(checksum, aMessage.GetOffset(), payloadLength); #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION VerifyOrExit(checksum == 0xffff, error = OT_ERROR_DROP); #endif VerifyOrExit(aMessage.Read(aMessage.GetOffset(), sizeof(udpHeader), &udpHeader) == sizeof(udpHeader), error = OT_ERROR_PARSE); aMessage.MoveOffset(sizeof(udpHeader)); aMessageInfo.mPeerPort = udpHeader.GetSourcePort(); aMessageInfo.mSockPort = udpHeader.GetDestinationPort(); // find socket for (UdpSocket *socket = mSockets; socket; socket = socket->GetNext()) { if (socket->GetSockName().mPort != udpHeader.GetDestinationPort()) { continue; } if (socket->GetSockName().mScopeId != 0 && socket->GetSockName().mScopeId != aMessageInfo.mInterfaceId) { continue; } if (!aMessageInfo.GetSockAddr().IsMulticast() && !socket->GetSockName().GetAddress().IsUnspecified() && socket->GetSockName().GetAddress() != aMessageInfo.GetSockAddr()) { continue; } // verify source if connected socket if (socket->GetPeerName().mPort != 0) { if (socket->GetPeerName().mPort != udpHeader.GetSourcePort()) { continue; } if (!socket->GetPeerName().GetAddress().IsUnspecified() && socket->GetPeerName().GetAddress() != aMessageInfo.GetPeerAddr()) { continue; } } socket->HandleUdpReceive(aMessage, aMessageInfo); } exit: return error; }