Never select the PCB that has INP_IPV6 flag and is bound to :: if

we have another PCB which is bound to 0.0.0.0.  If a PCB has the
INP_IPV6 flag, then we set its cost higher than IPv4 only PCBs.

Submitted by:	Keiichi SHIMA <keiichi__at__iijlab.net>
Obtained from:	KAME
MFC after:	1 week
This commit is contained in:
ume 2006-02-04 07:59:17 +00:00
parent 39d710a470
commit 4185f9e81f

View File

@ -863,12 +863,18 @@ in_pcbpurgeif0(struct inpcbinfo *pcbinfo, struct ifnet *ifp)
/*
* Lookup a PCB based on the local address and port.
*/
#define INP_LOOKUP_MAPPED_PCB_COST 3
struct inpcb *
in_pcblookup_local(struct inpcbinfo *pcbinfo, struct in_addr laddr,
u_int lport_arg, int wild_okay)
{
struct inpcb *inp;
int matchwild = 3, wildcard;
#ifdef INET6
int matchwild = 3 + INP_LOOKUP_MAPPED_PCB_COST;
#else
int matchwild = 3;
#endif
int wildcard;
u_short lport = lport_arg;
INP_INFO_WLOCK_ASSERT(pcbinfo);
@ -925,6 +931,21 @@ in_pcblookup_local(struct inpcbinfo *pcbinfo, struct in_addr laddr,
#ifdef INET6
if ((inp->inp_vflag & INP_IPV4) == 0)
continue;
/*
* We never select the PCB that has
* INP_IPV6 flag and is bound to :: if
* we have another PCB which is bound
* to 0.0.0.0. If a PCB has the
* INP_IPV6 flag, then we set its cost
* higher than IPv4 only PCBs.
*
* Note that the case only happens
* when a socket is bound to ::, under
* the condition that the use of the
* mapped address is allowed.
*/
if ((inp->inp_vflag & INP_IPV6) != 0)
wildcard += INP_LOOKUP_MAPPED_PCB_COST;
#endif
/*
* Clean out old time_wait sockets if they
@ -961,6 +982,7 @@ in_pcblookup_local(struct inpcbinfo *pcbinfo, struct in_addr laddr,
return (match);
}
}
#undef INP_LOOKUP_MAPPED_PCB_COST
/*
* Lookup PCB in hash list.