Skip to content

Commit

Permalink
Merge #19272
Browse files Browse the repository at this point in the history
19272: gcoap: Do not send responses from multicast addresses r=benpicco a=chrysn

### Contribution description

Since #18026, CoAP requests to multicast addresses (eg. `ff02::1`) came back from that exact address, which Linux rightfully just drops.

The fix uses the existing multicast check from #17978 (thanks `@benpicco` for making me write this as dedicated function, I just had to generalize it removing one struct layer), and foregoes setting the source address when responding to multicasts.

### Testing procedure

* Run the gcoap example
* Send a CoAP request to a multicast address RIOT listens to, eg. `./aiocoap-client coap://'[ff02::1%tapbr0]'/.well-known/core --non`

Before, this got no response (while you see it arrive on wireshark). After, you get a correct response with two lines of note:

```
WARNING:coap:Sending request to multicast via unicast request method
Response arrived from different address; base URI is coap://[fe80::3c63:beff:fe85:ca96%tapbr0]/.well-known/core
```

(The former is aiocoap telling us that we're not using the nonexistent multicast API so it's really more of an anycast, the latter is useful factual information).

Co-authored-by: chrysn <chrysn@fsfe.org>
  • Loading branch information
bors[bot] and chrysn authored Feb 14, 2023
2 parents 1c55118 + ac3a9cd commit f78c375
Showing 1 changed file with 17 additions and 7 deletions.
24 changes: 17 additions & 7 deletions sys/net/application_layer/gcoap/gcoap.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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);
}
}

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit f78c375

Please sign in to comment.