Projet

Général

Profil

Télécharger (3,34 ko) Statistiques
| Branche: | Révision:

univnautes-tools / patches / stable / 10 / udp_SO_REUSEADDR+PORT.diff @ 4ab3b90b

1
diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c
2
index 0c6f98e..6c77e2d 100644
3
--- a/sys/netinet/udp_usrreq.c
4
+++ b/sys/netinet/udp_usrreq.c
5
@@ -610,6 +610,49 @@ udp_input(struct mbuf *m, int off)
6
 		return;
7
 	}
8
 
9
+	if (inp->inp_phd != NULL) {
10
+		struct inpcb *local_inp;
11
+		struct mbuf *n;
12
+
13
+		LIST_FOREACH(local_inp, &inp->inp_phd->phd_pcblist, inp_portlist) {
14
+			if (local_inp == inp)
15
+				continue;
16
+
17
+			if ((local_inp->inp_vflag & INP_IPV4) == 0)
18
+                                continue;
19
+			if (local_inp->inp_lport != uh->uh_dport)
20
+				continue;
21
+			if (local_inp->inp_laddr.s_addr != INADDR_ANY &&
22
+			    local_inp->inp_laddr.s_addr != ip->ip_dst.s_addr)
23
+				continue;
24
+
25
+			/*
26
+			 * Check the minimum TTL for socket.
27
+			 */
28
+			if (local_inp->inp_ip_minttl && local_inp->inp_ip_minttl > ip->ip_ttl)
29
+				continue;
30
+
31
+			if ((n = m_copy(m, 0, M_COPYALL)) == NULL)
32
+				continue; /* XXX: Log about this? */
33
+			INP_RLOCK(local_inp);
34
+			UDP_PROBE(receive, NULL, local_inp, ip, local_inp, uh);
35
+			udp_append(local_inp, ip, n, iphlen, &udp_in);
36
+			INP_RUNLOCK(local_inp);
37
+			/*
38
+			 * Don't look for additional matches if this one does
39
+			 * not have either the SO_REUSEPORT or SO_REUSEADDR
40
+			 * socket options set.  This heuristic avoids
41
+			 * searching through all pcbs in the common case of a
42
+			 * non-shared port.  It assumes that an application
43
+			 * will never clear these options after setting them.
44
+			 */
45
+			if ((local_inp->inp_socket->so_options &
46
+			    (SO_REUSEPORT|SO_REUSEADDR)) == 0)
47
+				break;
48
+		}
49
+
50
+	}
51
+
52
 	/*
53
 	 * Check the minimum TTL for socket.
54
 	 */
55
diff --git a/sys/netinet6/udp6_usrreq.c b/sys/netinet6/udp6_usrreq.c
56
index e4963e2..cd1c9c1 100644
57
--- a/sys/netinet6/udp6_usrreq.c
58
+++ b/sys/netinet6/udp6_usrreq.c
59
@@ -457,6 +457,52 @@ udp6_input(struct mbuf **mp, int *offp, int proto)
60
 		icmp6_error(m, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOPORT, 0);
61
 		return (IPPROTO_DONE);
62
 	}
63
+	if (inp->inp_phd != NULL) {
64
+		struct inpcb *local_inp;
65
+		struct mbuf *n;
66
+
67
+		LIST_FOREACH(local_inp, &inp->inp_phd->phd_pcblist, inp_portlist) {
68
+			if (local_inp == inp)
69
+				continue;
70
+
71
+			if ((local_inp->inp_vflag & INP_IPV6) == 0)
72
+				continue;
73
+			if (local_inp->inp_lport != uh->uh_dport)
74
+				continue;
75
+			if (!IN6_IS_ADDR_UNSPECIFIED(&local_inp->in6p_laddr)) {
76
+				if (!IN6_ARE_ADDR_EQUAL(&local_inp->in6p_laddr,
77
+							&ip6->ip6_dst))
78
+					continue;
79
+			}
80
+
81
+			if ((n = m_copy(m, 0, M_COPYALL)) == NULL)
82
+				continue; /* XXX: Log about this? */
83
+			INP_RLOCK(local_inp);
84
+			up = intoudpcb(local_inp);
85
+			UDP_PROBE(receive, NULL, local_inp, ip6, local_inp, uh);
86
+			if (up->u_tun_func == NULL) {
87
+				udp6_append(local_inp, n, off, &fromsa);
88
+			} else {
89
+				/*
90
+				 * Engage the tunneling protocol.
91
+				 */
92
+
93
+				(*up->u_tun_func)(n, off, local_inp);
94
+			}
95
+			INP_RUNLOCK(local_inp);
96
+			/*
97
+			 * Don't look for additional matches if this one does
98
+			 * not have either the SO_REUSEPORT or SO_REUSEADDR
99
+			 * socket options set.  This heuristic avoids
100
+			 * searching through all pcbs in the common case of a
101
+			 * non-shared port.  It assumes that an application
102
+			 * will never clear these options after setting them.
103
+			 */
104
+			if ((local_inp->inp_socket->so_options &
105
+			     (SO_REUSEPORT|SO_REUSEADDR)) == 0)
106
+				break;
107
+		}
108
+	}
109
 	INP_RLOCK_ASSERT(inp);
110
 	up = intoudpcb(inp);
111
 	UDP_PROBE(receive, NULL, inp, ip6, inp, uh);
(66-66/67)