From 6a2c3ba10cc66c2939c1b86a78e56ebec882bc4b Mon Sep 17 00:00:00 2001 From: Ciaran Woodward Date: Wed, 10 Jul 2019 14:06:21 +0100 Subject: [PATCH] [coap] Improve behaviour of CoAP multicast requests & responses (#3967) This commit prevents the CoAP stack from sending automatic 'Not Found' responses to multicast CoAP requests, as suggested in RFC7252 8.2: When a server is aware that a request arrived via multicast, the server MAY always ignore the request, in particular if it doesn't have anything useful to respond (e.g., if it only has an empty payload or an error response). This commit also allows CoAP requests that are sent to multicast addresses to receive multiple responses, which will all be processed by the same handler callback (For instance, a multicast GET to discover network resources). --- src/core/coap/coap.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/core/coap/coap.cpp b/src/core/coap/coap.cpp index 8835665c7..50c08c457 100644 --- a/src/core/coap/coap.cpp +++ b/src/core/coap/coap.cpp @@ -555,12 +555,21 @@ void CoapBase::ProcessReceivedResponse(Message &aMessage, const Ip6::MessageInfo case OT_COAP_TYPE_CONFIRMABLE: // Send empty ACK if it is a CON message. SendAck(aMessage, aMessageInfo); - - // fall through + FinalizeCoapTransaction(*request, coapMetadata, &aMessage, &aMessageInfo, OT_ERROR_NONE); + break; case OT_COAP_TYPE_NON_CONFIRMABLE: // Separate response. - FinalizeCoapTransaction(*request, coapMetadata, &aMessage, &aMessageInfo, OT_ERROR_NONE); + + if (coapMetadata.mDestinationAddress.IsMulticast() && coapMetadata.mResponseHandler != NULL) + { + // If multicast non-confirmable request, allow multiple responses + coapMetadata.mResponseHandler(coapMetadata.mResponseContext, &aMessage, &aMessageInfo, OT_ERROR_NONE); + } + else + { + FinalizeCoapTransaction(*request, coapMetadata, &aMessage, &aMessageInfo, OT_ERROR_NONE); + } break; } @@ -649,7 +658,7 @@ exit: { otLogInfoCoapErr(error, "Failed to process request"); - if (error == OT_ERROR_NOT_FOUND) + if (error == OT_ERROR_NOT_FOUND && !aMessageInfo.GetSockAddr().IsMulticast()) { SendNotFound(aMessage, aMessageInfo); }