diff --git a/sys/net/application_layer/gcoap/gcoap.c b/sys/net/application_layer/gcoap/gcoap.c index aa7909de1e..f42c2b411f 100644 --- a/sys/net/application_layer/gcoap/gcoap.c +++ b/sys/net/application_layer/gcoap/gcoap.c @@ -85,6 +85,7 @@ static void _cache_process(gcoap_request_memo_t *memo, static ssize_t _cache_build_response(nanocoap_cache_entry_t *ce, coap_pkt_t *pdu, uint8_t *buf, size_t len); static void _receive_from_cache_cb(void *arg); +static bool _ep_is_multicast(const sock_udp_ep_t *remote_ep); static int _request_matcher_default(gcoap_listener_t *listener, const coap_resource_t **resource, @@ -345,18 +346,27 @@ static void _on_sock_udp_evt(sock_udp_t *sock, sock_async_flags_t type, void *ar cursor += res; } - /* make sure we reply with the same address that the request was destined for */ + /* make sure we reply with the same address that the request was + * destined for -- except in the multicast case */ + sock_udp_aux_tx_t *aux_out_ptr; sock_udp_aux_tx_t aux_out = { .flags = SOCK_AUX_SET_LOCAL, .local = aux_in.local, }; + if (_ep_is_multicast(&aux_in.local)) { + /* This eventually gets passed to sock_udp_send_aux, where NULL + * simply does not set any flags */ + aux_out_ptr = NULL; + } else { + aux_out_ptr = &aux_out; + } gcoap_socket_t socket = { .type = GCOAP_SOCKET_TYPE_UDP, .socket.udp = sock, }; - _process_coap_pdu(&socket, &remote, &aux_out, _listen_buf, cursor, truncated); + _process_coap_pdu(&socket, &remote, aux_out_ptr, _listen_buf, cursor, truncated); } } @@ -835,16 +845,16 @@ static int _find_resource(gcoap_socket_type_t tl_type, return ret; } -static bool _memo_ep_is_multicast(const gcoap_request_memo_t *memo) +static bool _ep_is_multicast(const sock_udp_ep_t *remote_ep) { - switch (memo->remote_ep.family) { + switch (remote_ep->family) { #ifdef SOCK_HAS_IPV6 case AF_INET6: - return ipv6_addr_is_multicast((const ipv6_addr_t *)&memo->remote_ep.addr.ipv6); + return ipv6_addr_is_multicast((const ipv6_addr_t *)&remote_ep->addr.ipv6); #endif #ifdef SOCK_HAS_IPV4 case AF_INET: - return ipv4_addr_is_multicast((const ipv4_addr_t *)&memo->remote_ep.addr.ipv4); + return ipv4_addr_is_multicast((const ipv4_addr_t *)&remote_ep->addr.ipv4); #endif default: assert(0); @@ -890,7 +900,7 @@ static void _find_req_memo(gcoap_request_memo_t **memo_ptr, coap_pkt_t *src_pdu, if ((memcmp(coap_get_token(src_pdu), coap_get_token(memo_pdu), cmplen) == 0) && (sock_udp_ep_equal(&memo->remote_ep, remote) /* Multicast addresses are not considered in matching responses */ - || _memo_ep_is_multicast(memo) + || _ep_is_multicast(&memo->remote_ep) )) { *memo_ptr = memo; break;