ref: 059b863fab96cf3ba65e74ad67221eec6cbcbe0c
parent: 24472b1071d197e57a1d551965f492a436ad6a15
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 */