git: 9front

Download patch

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