Skip to content

Conversation

@scaprile
Copy link
Collaborator

@scaprile scaprile commented Dec 22, 2025

When working with UDP multicast/broadcast, we can send to a multicast/broadcast address and get unicast or multicast/broadcast responses.
When getting a response, c->rem gets filled with the respondent IP data.
To be able to send multicast/broadcast again, we need to copy back to c->rem the original IP information.

  • mg_connect: we instruct to save c->rem contents somewhere (e.g.: c->data), and then copy back (SSDP tutorial)
  • mg_listen: we can copy back from c->loc, that's what our mDNS code does

With net_builtin, the same happens with the l2addr (MAC); if we don't restore it, we end up sending to the multicast/broadcast IP but to the requester MAC (mDNS, this just works but is wrong), or last respondent MAC (SSDP, blatantly wrong).
The fix is simple, but, in this case, it is not necessary to save the MAC, as it can be mapped (again) from the multicast/broadcast IP.

So, to keep consistency across stacks, we add mg_multicast_restore(c, from). This is the function to be called in both cases. Internally, this function copies from --> c->rem and for net_builtin also maps the MAC again.

@cpq
Copy link
Member

cpq commented Dec 23, 2025

So we have a new API function mg_multicast_restore and the only thing it does, it copies into c->rem?
I have an issue with that

@scaprile
Copy link
Collaborator Author

scaprile commented Dec 23, 2025

and for net_builtin also maps the MAC again

If we don't do something like that, then, users have to either save or re-generate the MAC themselves, but only for net_builtin. Then, multicast/broadcast user code will be different when using net_builtin.
s->mac gets copied from pkt->l2->src when receiving something.
This replicates for the link the same strategy we use for IP.

The other way I can think of is to check on every send, it is way less efficient as we're penalizing regular unicast UDP traffic, AND, the "hack" is still needed at the IP level.

@cpq
Copy link
Member

cpq commented Dec 26, 2025

What is the anticipated usage of mg_multicast_restore() ? Could you drop a little snippet that demonstrates it please?

@scaprile
Copy link
Collaborator Author

What is the anticipated usage of mg_multicast_restore() ? Could you drop a little snippet that demonstrates it please?

// Each response to the SSDP socket will change c->rem.
// We can now do mg_printf(c, "haha"); to respond back to the remote side.
// But in our case, we should restore the multicast address in order
// to have next search to go to the multicast address
mg_multicast_restore(c, (uint8_t *) c->data);

if (!req.is_unicast) mg_multicast_restore(c, (uint8_t *) &c->loc);

@cpq
Copy link
Member

cpq commented Dec 29, 2025

Ok LGTM
Can I be picky again?
I suggest to rename c->is_unicast to c->is_multicast and reverse the condition where it is used
Please merge.

@scaprile
Copy link
Collaborator Author

I suggest to rename c->is_unicast to c->is_multicast and reverse the condition where it is used

Well, it is not c-> but the mDNS request struct, which is by definition multicast (hence the 'm'). The non-usual case is when the request is explicit to perform a unicast response instead of the usual standard multicast response; so the name and usage.

Fix net_builtin inconsistency
@scaprile scaprile merged commit 1200f50 into master Dec 29, 2025
62 of 63 checks passed
@scaprile scaprile deleted the mcast branch December 29, 2025 17:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants