diff options
author | ume <ume@FreeBSD.org> | 2006-02-04 07:59:17 +0000 |
---|---|---|
committer | ume <ume@FreeBSD.org> | 2006-02-04 07:59:17 +0000 |
commit | 4185f9e81f4e9fbf9aeacec2fca4875433e3a9cd (patch) | |
tree | 2e8cebfbd4216c0f92aa9f6a94985512cc31c757 /sys | |
parent | 39d710a470aca516a810d0413f49d5ae95dbaee8 (diff) | |
download | FreeBSD-src-4185f9e81f4e9fbf9aeacec2fca4875433e3a9cd.zip FreeBSD-src-4185f9e81f4e9fbf9aeacec2fca4875433e3a9cd.tar.gz |
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
Diffstat (limited to 'sys')
-rw-r--r-- | sys/netinet/in_pcb.c | 24 |
1 files changed, 23 insertions, 1 deletions
diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c index cc29cf2..f96c660 100644 --- a/sys/netinet/in_pcb.c +++ b/sys/netinet/in_pcb.c @@ -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. |