ref: b345f3ef2c3927157d841a3701e554437d7acb1f
parent: f41198fb76d82200e4b006cb17d3351aa78c3d86
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Wed Jun 7 14:27:26 EDT 2023
devip: generate more reasonable laddr for UDP "headers" connection writes By default, we where just selecting a source address based on the remote unicast address. But for bcast/mcast, it makes more sense to use the interface address (which was previously generated by ipv6local()) to ensure that the reply is sent to the same interface that the request came in from, and make link-local remotes work. this is analog to the address selection used for "connection" based udp listener. This code only triggers when the user has not changed the source address to a unicast address in the multicast case.
--- a/sys/src/9/ip/rudp.c
+++ b/sys/src/9/ip/rudp.c
@@ -367,9 +367,22 @@
bp->rp += IPaddrlen;
ipmove(laddr, bp->rp);
bp->rp += IPaddrlen;
- /* pick interface closest to dest */
- if(ipforme(f, laddr) != Runi)
+ switch(ipforme(f, laddr)){
+ case Runi:
+ break;
+ case Rmulti:
+ case Rbcast:
+ /* use ifc address for bcast/mcast reply */
+ if(ipcmp(bp->rp, IPnoaddr) != 0
+ && ipforme(f, bp->rp) == Runi
+ && v6lookup(f, raddr, bp->rp, nil) != nil){
+ ipmove(laddr, bp->rp);
+ break;
+ }
+ default:
+ /* pick interface closest to dest */
findlocalip(f, laddr, raddr);
+ }
bp->rp += IPaddrlen; /* Ignore ifc address */
rport = nhgets(bp->rp);
bp->rp += 2+2; /* Ignore local port */
--- a/sys/src/9/ip/udp.c
+++ b/sys/src/9/ip/udp.c
@@ -212,9 +212,22 @@
bp->rp += IPaddrlen;
ipmove(laddr, bp->rp);
bp->rp += IPaddrlen;
- /* pick interface closest to dest */
- if(ipforme(f, laddr) != Runi)
+ switch(ipforme(f, laddr)){
+ case Runi:
+ break;
+ case Rmulti:
+ case Rbcast:
+ /* use ifc address for bcast/mcast reply */
+ if(ipcmp(bp->rp, IPnoaddr) != 0
+ && ipforme(f, bp->rp) == Runi
+ && v6lookup(f, raddr, bp->rp, nil) != nil){
+ ipmove(laddr, bp->rp);
+ break;
+ }
+ default:
+ /* pick interface closest to dest */
findlocalip(f, laddr, raddr);
+ }
bp->rp += IPaddrlen; /* Ignore ifc address */
rport = nhgets(bp->rp);
bp->rp += 2+2; /* Ignore local port */
--
⑨