gcoap: Forego IP address comparison in memo finding of multicasts#17978
Merged
chrysn merged 1 commit intoRIOT-OS:masterfrom Aug 10, 2022
Merged
Conversation
Member
Author
|
I should also point out that this only detects IPv6 multicast addresses; IPv4 multicast (broadcast) is harder to detect, and out of scope here. (I prefer not to sink time into a protocol that should long have been sunset). |
benpicco
reviewed
Apr 21, 2022
| /* Multicast addresses are not considered in matching responses */ | ||
| ( | ||
| memo->remote_ep.family == AF_INET6 && | ||
| ipv6_addr_is_multicast((const ipv6_addr_t *)&memo->remote_ep.addr.ipv6) |
Contributor
There was a problem hiding this comment.
Want to move that to a helper function? sock_udp_ep_is_multicast()
(Or just a local one - _ep_is_multicast())
Member
Author
There was a problem hiding this comment.
Yes, that'd be a good idea; will update when I get back to it.
Contributor
|
This just needs a tiny helper function to avoid cluttering the code like that |
Contributor
|
How about this patch diff --git a/sys/net/application_layer/gcoap/gcoap.c b/sys/net/application_layer/gcoap/gcoap.c
index e21f22211f..6c57929ebc 100644
--- a/sys/net/application_layer/gcoap/gcoap.c
+++ b/sys/net/application_layer/gcoap/gcoap.c
@@ -764,6 +764,12 @@ static int _find_resource(gcoap_socket_type_t tl_type,
return ret;
}
+static bool _memo_ep_is_multicast(const gcoap_request_memo_t *memo)
+{
+ return memo->remote_ep.family == AF_INET6 &&
+ ipv6_addr_is_multicast((const ipv6_addr_t *)&memo->remote_ep.addr.ipv6);
+}
+
/*
* Finds the memo for an outstanding request within the _coap_state.open_reqs
* array. Matches on remote endpoint and token.
@@ -803,15 +809,10 @@ static void _find_req_memo(gcoap_request_memo_t **memo_ptr, coap_pkt_t *src_pdu,
}
} else if (coap_get_token_len(memo_pdu) == cmplen) {
memo_pdu->token = coap_hdr_data_ptr(memo_pdu->hdr);
- if ((memcmp(src_pdu->token, memo_pdu->token, cmplen) == 0)
- && (
- sock_udp_ep_equal(&memo->remote_ep, remote) ||
- /* Multicast addresses are not considered in matching responses */
- (
- memo->remote_ep.family == AF_INET6 &&
- ipv6_addr_is_multicast((const ipv6_addr_t *)&memo->remote_ep.addr.ipv6)
- )
- )) {
+ if ((memcmp(src_pdu->token, memo_pdu->token, cmplen) == 0) &&
+ (sock_udp_ep_equal(&memo->remote_ep, remote) ||
+ /* Multicast addresses are not considered in matching responses */
+ _memo_ep_is_multicast(memo))) {
*memo_ptr = memo;
break;
} |
Co-Authored-By: Benjamin Valentin <[email protected]>
6b09c84 to
ab6bec6
Compare
Member
Author
|
Thanks, I lost track of this one. Added your patch, and squashed onto current master to get rid of a merge conflict due to get_token now being an accessor. |
benpicco
approved these changes
Aug 9, 2022
bors bot
added a commit
that referenced
this pull request
Feb 13, 2023
18257: drivers/wdt: add periph_wdt_auto_start for early watchdog r=benpicco a=benpicco 19272: gcoap: Do not send responses from multicast addresses r=chrysn 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: Benjamin Valentin <[email protected]> Co-authored-by: chrysn <[email protected]>
bors bot
added a commit
that referenced
this pull request
Feb 14, 2023
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 <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Contribution description
gcoap's
_find_req_memocompares tokens and IP addresses. That's generally a good thing, but when requests are sent to a multicast address, it is not right (RFC7252 has an explicit exception there).There may be other areas of multicast support that are lacking, but this is a small enhancement step.
Testing procedure
Have a local CoAP server that responds to multicasts (
aiocoap-fileserverwill do, even though that might be a bug there, gotta check out whether it's supposed to do that by default).Previously, the request timed out.
Note that good multicast behavior would be to accept several servers' responses, and (in the command line client) to show the address of the server where the response came from, both is left for further work.
Issues/PRs references
Brought up by ad6sh in https://forum.riot-os.org/t/coap-resource-discovery/3599; the testing instructions are his.