Deleted Added
full compact
in_pcb.c (220879) in_pcb.c (221247)
1/*-
2 * Copyright (c) 1982, 1986, 1991, 1993, 1995
3 * The Regents of the University of California.
4 * Copyright (c) 2007-2009 Robert N. M. Watson
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

--- 18 unchanged lines hidden (view full) ---

27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 *
31 * @(#)in_pcb.c 8.4 (Berkeley) 5/24/95
32 */
33
34#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 1982, 1986, 1991, 1993, 1995
3 * The Regents of the University of California.
4 * Copyright (c) 2007-2009 Robert N. M. Watson
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

--- 18 unchanged lines hidden (view full) ---

27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 *
31 * @(#)in_pcb.c 8.4 (Berkeley) 5/24/95
32 */
33
34#include <sys/cdefs.h>
35__FBSDID("$FreeBSD: head/sys/netinet/in_pcb.c 220879 2011-04-20 08:00:29Z bz $");
35__FBSDID("$FreeBSD: head/sys/netinet/in_pcb.c 221247 2011-04-30 11:04:34Z bz $");
36
37#include "opt_ddb.h"
38#include "opt_ipsec.h"
39#include "opt_inet.h"
40#include "opt_inet6.h"
41
42#include <sys/param.h>
43#include <sys/systm.h>

--- 16 unchanged lines hidden (view full) ---

60
61#include <vm/uma.h>
62
63#include <net/if.h>
64#include <net/if_types.h>
65#include <net/route.h>
66#include <net/vnet.h>
67
36
37#include "opt_ddb.h"
38#include "opt_ipsec.h"
39#include "opt_inet.h"
40#include "opt_inet6.h"
41
42#include <sys/param.h>
43#include <sys/systm.h>

--- 16 unchanged lines hidden (view full) ---

60
61#include <vm/uma.h>
62
63#include <net/if.h>
64#include <net/if_types.h>
65#include <net/route.h>
66#include <net/vnet.h>
67
68#if defined(INET) || defined(INET6)
68#include <netinet/in.h>
69#include <netinet/in_pcb.h>
69#include <netinet/in.h>
70#include <netinet/in_pcb.h>
70#include <netinet/in_var.h>
71#include <netinet/ip_var.h>
72#include <netinet/tcp_var.h>
73#include <netinet/udp.h>
74#include <netinet/udp_var.h>
71#include <netinet/ip_var.h>
72#include <netinet/tcp_var.h>
73#include <netinet/udp.h>
74#include <netinet/udp_var.h>
75#endif
76#ifdef INET
77#include <netinet/in_var.h>
78#endif
75#ifdef INET6
76#include <netinet/ip6.h>
79#ifdef INET6
80#include <netinet/ip6.h>
77#include <netinet6/ip6_var.h>
78#include <netinet6/in6_pcb.h>
81#include <netinet6/in6_pcb.h>
82#include <netinet6/in6_var.h>
83#include <netinet6/ip6_var.h>
79#endif /* INET6 */
80
81
82#ifdef IPSEC
83#include <netipsec/ipsec.h>
84#include <netipsec/key.h>
85#endif /* IPSEC */
86

--- 25 unchanged lines hidden (view full) ---

112VNET_DEFINE(int, ipport_randomcps) = 10; /* user controlled via sysctl */
113VNET_DEFINE(int, ipport_randomtime) = 45; /* user controlled via sysctl */
114VNET_DEFINE(int, ipport_stoprandom); /* toggled by ipport_tick */
115VNET_DEFINE(int, ipport_tcpallocs);
116static VNET_DEFINE(int, ipport_tcplastcount);
117
118#define V_ipport_tcplastcount VNET(ipport_tcplastcount)
119
84#endif /* INET6 */
85
86
87#ifdef IPSEC
88#include <netipsec/ipsec.h>
89#include <netipsec/key.h>
90#endif /* IPSEC */
91

--- 25 unchanged lines hidden (view full) ---

117VNET_DEFINE(int, ipport_randomcps) = 10; /* user controlled via sysctl */
118VNET_DEFINE(int, ipport_randomtime) = 45; /* user controlled via sysctl */
119VNET_DEFINE(int, ipport_stoprandom); /* toggled by ipport_tick */
120VNET_DEFINE(int, ipport_tcpallocs);
121static VNET_DEFINE(int, ipport_tcplastcount);
122
123#define V_ipport_tcplastcount VNET(ipport_tcplastcount)
124
125static void in_pcbremlists(struct inpcb *inp);
126
127#ifdef INET
120#define RANGECHK(var, min, max) \
121 if ((var) < (min)) { (var) = (min); } \
122 else if ((var) > (max)) { (var) = (max); }
123
128#define RANGECHK(var, min, max) \
129 if ((var) < (min)) { (var) = (min); } \
130 else if ((var) > (max)) { (var) = (max); }
131
124static void in_pcbremlists(struct inpcb *inp);
125
126static int
127sysctl_net_ipport_check(SYSCTL_HANDLER_ARGS)
128{
129 int error;
130
131#ifdef VIMAGE
132 error = vnet_sysctl_handle_int(oidp, arg1, arg2, req);
133#else

--- 40 unchanged lines hidden (view full) ---

174 &VNET_NAME(ipport_randomized), 0, "Enable random port allocation");
175SYSCTL_VNET_INT(_net_inet_ip_portrange, OID_AUTO, randomcps, CTLFLAG_RW,
176 &VNET_NAME(ipport_randomcps), 0, "Maximum number of random port "
177 "allocations before switching to a sequental one");
178SYSCTL_VNET_INT(_net_inet_ip_portrange, OID_AUTO, randomtime, CTLFLAG_RW,
179 &VNET_NAME(ipport_randomtime), 0,
180 "Minimum time to keep sequental port "
181 "allocation before switching to a random one");
132static int
133sysctl_net_ipport_check(SYSCTL_HANDLER_ARGS)
134{
135 int error;
136
137#ifdef VIMAGE
138 error = vnet_sysctl_handle_int(oidp, arg1, arg2, req);
139#else

--- 40 unchanged lines hidden (view full) ---

180 &VNET_NAME(ipport_randomized), 0, "Enable random port allocation");
181SYSCTL_VNET_INT(_net_inet_ip_portrange, OID_AUTO, randomcps, CTLFLAG_RW,
182 &VNET_NAME(ipport_randomcps), 0, "Maximum number of random port "
183 "allocations before switching to a sequental one");
184SYSCTL_VNET_INT(_net_inet_ip_portrange, OID_AUTO, randomtime, CTLFLAG_RW,
185 &VNET_NAME(ipport_randomtime), 0,
186 "Minimum time to keep sequental port "
187 "allocation before switching to a random one");
188#endif
182
183/*
184 * in_pcb.c: manage the Protocol Control Blocks.
185 *
186 * NOTE: It is assumed that most of these functions will be called with
187 * the pcbinfo lock held, and often, the inpcb lock held, as these utility
188 * functions often modify hash chains or addresses in pcbs.
189 */

--- 96 unchanged lines hidden (view full) ---

286 if (error != 0) {
287 crfree(inp->inp_cred);
288 uma_zfree(pcbinfo->ipi_zone, inp);
289 }
290#endif
291 return (error);
292}
293
189
190/*
191 * in_pcb.c: manage the Protocol Control Blocks.
192 *
193 * NOTE: It is assumed that most of these functions will be called with
194 * the pcbinfo lock held, and often, the inpcb lock held, as these utility
195 * functions often modify hash chains or addresses in pcbs.
196 */

--- 96 unchanged lines hidden (view full) ---

293 if (error != 0) {
294 crfree(inp->inp_cred);
295 uma_zfree(pcbinfo->ipi_zone, inp);
296 }
297#endif
298 return (error);
299}
300
301#ifdef INET
294int
295in_pcbbind(struct inpcb *inp, struct sockaddr *nam, struct ucred *cred)
296{
297 int anonport, error;
298
299 INP_INFO_WLOCK_ASSERT(inp->inp_pcbinfo);
300 INP_WLOCK_ASSERT(inp);
301

--- 9 unchanged lines hidden (view full) ---

311 inp->inp_laddr.s_addr = INADDR_ANY;
312 inp->inp_lport = 0;
313 return (EAGAIN);
314 }
315 if (anonport)
316 inp->inp_flags |= INP_ANONPORT;
317 return (0);
318}
302int
303in_pcbbind(struct inpcb *inp, struct sockaddr *nam, struct ucred *cred)
304{
305 int anonport, error;
306
307 INP_INFO_WLOCK_ASSERT(inp->inp_pcbinfo);
308 INP_WLOCK_ASSERT(inp);
309

--- 9 unchanged lines hidden (view full) ---

319 inp->inp_laddr.s_addr = INADDR_ANY;
320 inp->inp_lport = 0;
321 return (EAGAIN);
322 }
323 if (anonport)
324 inp->inp_flags |= INP_ANONPORT;
325 return (0);
326}
327#endif
319
320#if defined(INET) || defined(INET6)
321int
322in_pcb_lport(struct inpcb *inp, struct in_addr *laddrp, u_short *lportp,
323 struct ucred *cred, int wild)
324{
325 struct inpcbinfo *pcbinfo;
326 struct inpcb *tmpinp;

--- 64 unchanged lines hidden (view full) ---

391 /* Make the compiler happy. */
392 laddr.s_addr = 0;
393 if ((inp->inp_vflag & (INP_IPV4|INP_IPV6)) == INP_IPV4) {
394 KASSERT(laddrp != NULL, ("%s: laddrp NULL for v4 inp %p",
395 __func__, inp));
396 laddr = *laddrp;
397 }
398#endif
328
329#if defined(INET) || defined(INET6)
330int
331in_pcb_lport(struct inpcb *inp, struct in_addr *laddrp, u_short *lportp,
332 struct ucred *cred, int wild)
333{
334 struct inpcbinfo *pcbinfo;
335 struct inpcb *tmpinp;

--- 64 unchanged lines hidden (view full) ---

400 /* Make the compiler happy. */
401 laddr.s_addr = 0;
402 if ((inp->inp_vflag & (INP_IPV4|INP_IPV6)) == INP_IPV4) {
403 KASSERT(laddrp != NULL, ("%s: laddrp NULL for v4 inp %p",
404 __func__, inp));
405 laddr = *laddrp;
406 }
407#endif
408 tmpinp = NULL; /* Make compiler happy. */
399 lport = *lportp;
400
401 if (dorandom)
402 *lastport = first + (arc4random() % (last - first));
403
404 count = last - first;
405
406 do {

--- 23 unchanged lines hidden (view full) ---

430 laddrp->s_addr = laddr.s_addr;
431#endif
432 *lportp = lport;
433
434 return (0);
435}
436#endif /* INET || INET6 */
437
409 lport = *lportp;
410
411 if (dorandom)
412 *lastport = first + (arc4random() % (last - first));
413
414 count = last - first;
415
416 do {

--- 23 unchanged lines hidden (view full) ---

440 laddrp->s_addr = laddr.s_addr;
441#endif
442 *lportp = lport;
443
444 return (0);
445}
446#endif /* INET || INET6 */
447
448#ifdef INET
438/*
439 * Set up a bind operation on a PCB, performing port allocation
440 * as required, but do not actually modify the PCB. Callers can
441 * either complete the bind by setting inp_laddr/inp_lport and
442 * calling in_pcbinshash(), or they can just use the resulting
443 * port and address to authorise the sending of a once-off packet.
444 *
445 * On error, the values of *laddrp and *lportp are not changed.

--- 547 unchanged lines hidden (view full) ---

993
994 INP_INFO_WLOCK_ASSERT(inp->inp_pcbinfo);
995 INP_WLOCK_ASSERT(inp);
996
997 inp->inp_faddr.s_addr = INADDR_ANY;
998 inp->inp_fport = 0;
999 in_pcbrehash(inp);
1000}
449/*
450 * Set up a bind operation on a PCB, performing port allocation
451 * as required, but do not actually modify the PCB. Callers can
452 * either complete the bind by setting inp_laddr/inp_lport and
453 * calling in_pcbinshash(), or they can just use the resulting
454 * port and address to authorise the sending of a once-off packet.
455 *
456 * On error, the values of *laddrp and *lportp are not changed.

--- 547 unchanged lines hidden (view full) ---

1004
1005 INP_INFO_WLOCK_ASSERT(inp->inp_pcbinfo);
1006 INP_WLOCK_ASSERT(inp);
1007
1008 inp->inp_faddr.s_addr = INADDR_ANY;
1009 inp->inp_fport = 0;
1010 in_pcbrehash(inp);
1011}
1012#endif
1001
1002/*
1003 * in_pcbdetach() is responsibe for disassociating a socket from an inpcb.
1004 * For most protocols, this will be invoked immediately prior to calling
1005 * in_pcbfree(). However, with TCP the inpcb may significantly outlive the
1006 * socket, in which case in_pcbfree() is deferred.
1007 */
1008void

--- 32 unchanged lines hidden (view full) ---

1041 if (inp->inp_vflag & INP_IPV6PROTO) {
1042 ip6_freepcbopts(inp->in6p_outputopts);
1043 if (inp->in6p_moptions != NULL)
1044 ip6_freemoptions(inp->in6p_moptions);
1045 }
1046#endif
1047 if (inp->inp_options)
1048 (void)m_free(inp->inp_options);
1013
1014/*
1015 * in_pcbdetach() is responsibe for disassociating a socket from an inpcb.
1016 * For most protocols, this will be invoked immediately prior to calling
1017 * in_pcbfree(). However, with TCP the inpcb may significantly outlive the
1018 * socket, in which case in_pcbfree() is deferred.
1019 */
1020void

--- 32 unchanged lines hidden (view full) ---

1053 if (inp->inp_vflag & INP_IPV6PROTO) {
1054 ip6_freepcbopts(inp->in6p_outputopts);
1055 if (inp->in6p_moptions != NULL)
1056 ip6_freemoptions(inp->in6p_moptions);
1057 }
1058#endif
1059 if (inp->inp_options)
1060 (void)m_free(inp->inp_options);
1061#ifdef INET
1049 if (inp->inp_moptions != NULL)
1050 inp_freemoptions(inp->inp_moptions);
1062 if (inp->inp_moptions != NULL)
1063 inp_freemoptions(inp->inp_moptions);
1064#endif
1051 inp->inp_vflag = 0;
1052 crfree(inp->inp_cred);
1053
1054#ifdef MAC
1055 mac_inpcb_destroy(inp);
1056#endif
1057 INP_WUNLOCK(inp);
1058 uma_zfree(ipi->ipi_zone, inp);

--- 100 unchanged lines hidden (view full) ---

1159 if (LIST_FIRST(&phd->phd_pcblist) == NULL) {
1160 LIST_REMOVE(phd, phd_hash);
1161 free(phd, M_PCB);
1162 }
1163 inp->inp_flags &= ~INP_INHASHLIST;
1164 }
1165}
1166
1065 inp->inp_vflag = 0;
1066 crfree(inp->inp_cred);
1067
1068#ifdef MAC
1069 mac_inpcb_destroy(inp);
1070#endif
1071 INP_WUNLOCK(inp);
1072 uma_zfree(ipi->ipi_zone, inp);

--- 100 unchanged lines hidden (view full) ---

1173 if (LIST_FIRST(&phd->phd_pcblist) == NULL) {
1174 LIST_REMOVE(phd, phd_hash);
1175 free(phd, M_PCB);
1176 }
1177 inp->inp_flags &= ~INP_INHASHLIST;
1178 }
1179}
1180
1181#ifdef INET
1167/*
1168 * Common routines to return the socket addresses associated with inpcbs.
1169 */
1170struct sockaddr *
1171in_sockaddr(in_port_t port, struct in_addr *addr_p)
1172{
1173 struct sockaddr_in *sin;
1174

--- 347 unchanged lines hidden (view full) ---

1522#ifdef INET6
1523 if (local_wild_mapped != NULL)
1524 return (local_wild_mapped);
1525#endif /* defined(INET6) */
1526 } /* if (wildcard == INPLOOKUP_WILDCARD) */
1527
1528 return (NULL);
1529}
1182/*
1183 * Common routines to return the socket addresses associated with inpcbs.
1184 */
1185struct sockaddr *
1186in_sockaddr(in_port_t port, struct in_addr *addr_p)
1187{
1188 struct sockaddr_in *sin;
1189

--- 347 unchanged lines hidden (view full) ---

1537#ifdef INET6
1538 if (local_wild_mapped != NULL)
1539 return (local_wild_mapped);
1540#endif /* defined(INET6) */
1541 } /* if (wildcard == INPLOOKUP_WILDCARD) */
1542
1543 return (NULL);
1544}
1545#endif /* INET */
1530
1531/*
1532 * Insert PCB onto various hash lists.
1533 */
1534int
1535in_pcbinshash(struct inpcb *inp)
1536{
1537 struct inpcbhead *pcbhash;

--- 541 unchanged lines hidden ---
1546
1547/*
1548 * Insert PCB onto various hash lists.
1549 */
1550int
1551in_pcbinshash(struct inpcb *inp)
1552{
1553 struct inpcbhead *pcbhash;

--- 541 unchanged lines hidden ---