Subject: Re: regression: bind interface and transmit to ff02::2
To: David Young <dyoung@pobox.com>
From: JINMEI Tatuya / =?ISO-2022-JP?B?GyRCP0BMQEMjOkgbKEI=?= <jinmei@isl.rdc.toshiba.co.jp>
List: tech-net
Date: 03/23/2006 16:33:47
>>>>> On Thu, 23 Mar 2006 00:51:50 -0600, 
>>>>> David Young <dyoung@pobox.com> said:

> Correct.

Okay, then it's not the intended behavior, sorry for the mess.  Please
try the attached patch.

Having said that, I'd generally recommend to specify the specific zone
ID explicitly, rather than relying on the automatic determination
based on implicit dependency.  While I admit this particular case is
deterministic and controversy, behaving based on such indirect
assumption can sometimes cause an unexpected result.

					JINMEI, Tatuya
					Communication Platform Lab.
					Corporate R&D Center, Toshiba Corp.
					jinmei@isl.rdc.toshiba.co.jp

--- in6_src.c.orig	Thu Mar 23 16:20:31 2006
+++ in6_src.c	Thu Mar 23 16:26:22 2006
@@ -201,6 +201,7 @@
 	int dst_scope = -1, best_scope = -1, best_matchlen = -1;
 	struct in6_addrpolicy *dst_policy = NULL, *best_policy = NULL;
 	u_int32_t odstzone;
+	int error;
 #ifdef notyet /* until introducing ND extensions and address selection */
 	int prefer_tempaddr;
 #endif
@@ -260,18 +261,31 @@
 	}
 
 	/*
-	 * Otherwise, if the socket has already bound the source, just use it.
+	 * Choose the best one based on the outgoing interface and the
+	 * destination address.  We do this regardless of whether the socket
+	 * is bound, since the caller may need this information as a side
+	 * effect of the call to this function (e.g., for identifying the
+	 * appropriate scope zone ID).
+	 */
+	/* get the outgoing interface */
+	error = in6_selectif(dstsock, opts, mopts, ro, &ifp);
+
+	/*
+	 * If the socket has already bound the source, just use it.  We don't
+	 * care at the moment whether in6_selectif() succeeded, even though it
+	 * would eventually cause an error.
 	 */
 	if (laddr && !IN6_IS_ADDR_UNSPECIFIED(laddr))
 		return (laddr);
 
 	/*
-	 * If the address is not specified, choose the best one based on
-	 * the outgoing interface and the destination address.
+	 * The outgoing interface is crucial in the general selection procedure
+	 * below.  If it is not known at this point, we fail.
 	 */
-	/* get the outgoing interface */
-	if ((*errorp = in6_selectif(dstsock, opts, mopts, ro, &ifp)) != 0)
+	if (ifp != NULL) {
+		*errorp = error;
 		return (NULL);
+	}
 
 #if defined(MIP6) && NMIP > 0
 	/*