diff --git a/src/inet/UDPEndPoint.cpp b/src/inet/UDPEndPoint.cpp index e0907d951a9e65..b0b6f3f861e989 100644 --- a/src/inet/UDPEndPoint.cpp +++ b/src/inet/UDPEndPoint.cpp @@ -125,8 +125,8 @@ void UDPEndPoint::Close() { if (mState != State::kClosed) { - CloseImpl(); mState = State::kClosed; + CloseImpl(); } } diff --git a/src/inet/UDPEndPointImplLwIP.cpp b/src/inet/UDPEndPointImplLwIP.cpp index d5e90568f7af84..6c13c1d92479c3 100644 --- a/src/inet/UDPEndPointImplLwIP.cpp +++ b/src/inet/UDPEndPointImplLwIP.cpp @@ -241,6 +241,13 @@ void UDPEndPointImplLwIP::CloseImpl() udp_remove(mUDP); mUDP = nullptr; mLwIPEndPointType = LwIPEndPointType::Unknown; + + // In case that there is a UDPEndPointImplLwIP::LwIPReceiveUDPMessage + // event pending in the event queue (SystemLayer::ScheduleLambda), we + // schedule a release call to the end of the queue, to ensure that the + // queued pointer to UDPEndPointImplLwIP is not dangling. + Retain(); + CHIP_ERROR err = GetSystemLayer().ScheduleLambda([this] { Release(); }); } // Unlock LwIP stack @@ -342,6 +349,10 @@ void UDPEndPointImplLwIP::LwIPReceiveUDPMessage(void * arg, struct udp_pcb * pcb UDPEndPointImplLwIP * ep = static_cast(arg); IPPacketInfo * pktInfo = nullptr; System::PacketBufferHandle buf = System::PacketBufferHandle::Adopt(p); + + if (ep->mState == State::kClosed) + return; + if (buf->HasChainedBuffer()) { // Try the simple expedient of flattening in-place. diff --git a/src/inet/UDPEndPointImplOpenThread.cpp b/src/inet/UDPEndPointImplOpenThread.cpp index 02f11ba30bdf75..bab013da302105 100644 --- a/src/inet/UDPEndPointImplOpenThread.cpp +++ b/src/inet/UDPEndPointImplOpenThread.cpp @@ -54,6 +54,9 @@ void UDPEndPointImplOT::handleUdpReceive(void * aContext, otMessage * aMessage, char destStr[Inet::IPAddress::kMaxStringLength]; #endif + if (ep->mState == State::kClosed) + return; + if (msgLen > System::PacketBuffer::kMaxSizeWithoutReserve) { ChipLogError(Inet, "UDP message too long, discarding. Size received %d", msgLen); @@ -261,6 +264,13 @@ void UDPEndPointImplOT::CloseImpl() if (otUdpIsOpen(mOTInstance, &mSocket)) { otUdpClose(mOTInstance, &mSocket); + + // In case that there is a UDPEndPointImplOT::handleUdpReceive event + // pending in the event queue (SystemLayer::ScheduleLambda), we + // schedule a release call to the end of the queue, to ensure that the + // queued pointer to UDPEndPointImplOT is not dangling. + Retain(); + CHIP_ERROR err = GetSystemLayer().ScheduleLambda([this] { Release(); }); } UnlockOpenThread(); }