summaryrefslogtreecommitdiffstats
path: root/sys/netinet/in_pcb.c
diff options
context:
space:
mode:
authorume <ume@FreeBSD.org>2006-02-04 07:59:17 +0000
committerume <ume@FreeBSD.org>2006-02-04 07:59:17 +0000
commit4185f9e81f4e9fbf9aeacec2fca4875433e3a9cd (patch)
tree2e8cebfbd4216c0f92aa9f6a94985512cc31c757 /sys/netinet/in_pcb.c
parent39d710a470aca516a810d0413f49d5ae95dbaee8 (diff)
downloadFreeBSD-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/netinet/in_pcb.c')
-rw-r--r--sys/netinet/in_pcb.c24
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.
OpenPOWER on IntegriCloud