shithub: riscv

Download patch

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 */