PageRenderTime 49ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/bsd/sys/netinet/in_pcb.cc

https://gitlab.com/jforge/osv
C++ | 2099 lines | 1466 code | 227 blank | 406 comment | 349 complexity | 6af5d93f521c8ba41f238b1a515b78d8 MD5 | raw file
Possible License(s): BSD-3-Clause, 0BSD, MPL-2.0-no-copyleft-exception

Large files files are truncated, but you can click here to view the full file

  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. * Copyright (c) 2010-2011 Juniper Networks, Inc.
  6. * All rights reserved.
  7. *
  8. * Portions of this software were developed by Robert N. M. Watson under
  9. * contract to Juniper Networks, Inc.
  10. *
  11. * Redistribution and use in source and binary forms, with or without
  12. * modification, are permitted provided that the following conditions
  13. * are met:
  14. * 1. Redistributions of source code must retain the above copyright
  15. * notice, this list of conditions and the following disclaimer.
  16. * 2. Redistributions in binary form must reproduce the above copyright
  17. * notice, this list of conditions and the following disclaimer in the
  18. * documentation and/or other materials provided with the distribution.
  19. * 4. Neither the name of the University nor the names of its contributors
  20. * may be used to endorse or promote products derived from this software
  21. * without specific prior written permission.
  22. *
  23. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  24. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  25. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  26. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  27. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  28. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  29. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  30. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  31. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  32. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  33. * SUCH DAMAGE.
  34. *
  35. * @(#)in_pcb.c 8.4 (Berkeley) 5/24/95
  36. */
  37. #include <sys/cdefs.h>
  38. #include <bsd/porting/netport.h>
  39. #include <bsd/porting/uma_stub.h>
  40. #include <bsd/porting/callout.h>
  41. #include <bsd/sys/sys/eventhandler.h>
  42. #include <bsd/sys/sys/libkern.h>
  43. #include <bsd/sys/sys/param.h>
  44. #include <bsd/sys/sys/mbuf.h>
  45. #include <bsd/sys/sys/domain.h>
  46. #include <bsd/sys/sys/protosw.h>
  47. #include <bsd/sys/sys/socket.h>
  48. #include <bsd/sys/sys/socketvar.h>
  49. #include <bsd/sys/sys/priv.h>
  50. #include <bsd/sys/sys/refcount.h>
  51. #include <bsd/sys/net/if.h>
  52. #include <bsd/sys/net/if_types.h>
  53. #include <bsd/sys/net/route.h>
  54. #include <bsd/sys/net/vnet.h>
  55. #if defined(INET) || defined(INET6)
  56. #include <bsd/sys/netinet/in.h>
  57. #include <bsd/sys/netinet/in_pcb.h>
  58. #include <bsd/sys/netinet/ip_var.h>
  59. #include <bsd/sys/netinet/tcp_var.h>
  60. #include <bsd/sys/netinet/udp.h>
  61. #include <bsd/sys/netinet/udp_var.h>
  62. #endif
  63. #ifdef INET
  64. #include <bsd/sys/netinet/in_var.h>
  65. #endif
  66. #ifdef INET6
  67. #include <bsd/sys/netinet/ip6.h>
  68. #include <bsd/sys/netinet6/in6_pcb.h>
  69. #include <bsd/sys/netinet6/in6_var.h>
  70. #include <bsd/sys/netinet6/ip6_var.h>
  71. #endif /* INET6 */
  72. #include <bsd/sys/net/routecache.hh>
  73. #ifdef IPSEC
  74. #include <bsd/sys/netipsec/ipsec.h>
  75. #include <bsd/sys/netipsec/key.h>
  76. #endif /* IPSEC */
  77. #include <osv/trace.hh>
  78. TRACEPOINT(trace_inpcb_ref, "inp=%x", struct inpcb *);
  79. TRACEPOINT(trace_inpcb_rele, "inp=%x", struct inpcb *);
  80. TRACEPOINT(trace_inpcb_free, "inp=%x", struct inpcb *);
  81. static struct callout ipport_tick_callout;
  82. /*
  83. * These configure the range of local port addresses assigned to
  84. * "unspecified" outgoing connections/packets/whatever.
  85. */
  86. VNET_DEFINE(int, ipport_lowfirstauto) = IPPORT_RESERVED - 1; /* 1023 */
  87. VNET_DEFINE(int, ipport_lowlastauto) = IPPORT_RESERVEDSTART; /* 600 */
  88. VNET_DEFINE(int, ipport_firstauto) = IPPORT_EPHEMERALFIRST; /* 10000 */
  89. VNET_DEFINE(int, ipport_lastauto) = IPPORT_EPHEMERALLAST; /* 65535 */
  90. VNET_DEFINE(int, ipport_hifirstauto) = IPPORT_HIFIRSTAUTO; /* 49152 */
  91. VNET_DEFINE(int, ipport_hilastauto) = IPPORT_HILASTAUTO; /* 65535 */
  92. /*
  93. * Reserved ports accessible only to root. There are significant
  94. * security considerations that must be accounted for when changing these,
  95. * but the security benefits can be great. Please be careful.
  96. */
  97. VNET_DEFINE(int, ipport_reservedhigh) = IPPORT_RESERVED - 1; /* 1023 */
  98. VNET_DEFINE(int, ipport_reservedlow);
  99. /* Variables dealing with random ephemeral port allocation. */
  100. VNET_DEFINE(int, ipport_randomized) = 1; /* user controlled via sysctl */
  101. VNET_DEFINE(int, ipport_randomcps) = 10; /* user controlled via sysctl */
  102. VNET_DEFINE(int, ipport_randomtime) = 45; /* user controlled via sysctl */
  103. VNET_DEFINE(int, ipport_stoprandom); /* toggled by ipport_tick */
  104. VNET_DEFINE(int, ipport_tcpallocs);
  105. static VNET_DEFINE(int, ipport_tcplastcount);
  106. #define V_ipport_tcplastcount VNET(ipport_tcplastcount)
  107. static void in_pcbremlists(struct inpcb *inp);
  108. #ifdef INET
  109. static struct inpcb *in_pcblookup_hash_locked(struct inpcbinfo *pcbinfo,
  110. struct in_addr faddr, u_int fport_arg,
  111. struct in_addr laddr, u_int lport_arg,
  112. int lookupflags, struct ifnet *ifp);
  113. #if 0
  114. #define RANGECHK(var, min, max) \
  115. if ((var) < (min)) { (var) = (min); } \
  116. else if ((var) > (max)) { (var) = (max); }
  117. static int
  118. sysctl_net_ipport_check(SYSCTL_HANDLER_ARGS)
  119. {
  120. int error;
  121. #ifdef VIMAGE
  122. error = vnet_sysctl_handle_int(oidp, arg1, arg2, req);
  123. #else
  124. error = sysctl_handle_int(oidp, arg1, arg2, req);
  125. #endif
  126. if (error == 0) {
  127. RANGECHK(V_ipport_lowfirstauto, 1, IPPORT_RESERVED - 1);
  128. RANGECHK(V_ipport_lowlastauto, 1, IPPORT_RESERVED - 1);
  129. RANGECHK(V_ipport_firstauto, IPPORT_RESERVED, IPPORT_MAX);
  130. RANGECHK(V_ipport_lastauto, IPPORT_RESERVED, IPPORT_MAX);
  131. RANGECHK(V_ipport_hifirstauto, IPPORT_RESERVED, IPPORT_MAX);
  132. RANGECHK(V_ipport_hilastauto, IPPORT_RESERVED, IPPORT_MAX);
  133. }
  134. return (error);
  135. }
  136. #undef RANGECHK
  137. #endif
  138. SYSCTL_NODE(_net_inet_ip, IPPROTO_IP, portrange, CTLFLAG_RW, 0, "IP Ports");
  139. SYSCTL_VNET_PROC(_net_inet_ip_portrange, OID_AUTO, lowfirst,
  140. CTLTYPE_INT|CTLFLAG_RW, &VNET_NAME(ipport_lowfirstauto), 0,
  141. &sysctl_net_ipport_check, "I", "");
  142. SYSCTL_VNET_PROC(_net_inet_ip_portrange, OID_AUTO, lowlast,
  143. CTLTYPE_INT|CTLFLAG_RW, &VNET_NAME(ipport_lowlastauto), 0,
  144. &sysctl_net_ipport_check, "I", "");
  145. SYSCTL_VNET_PROC(_net_inet_ip_portrange, OID_AUTO, first,
  146. CTLTYPE_INT|CTLFLAG_RW, &VNET_NAME(ipport_firstauto), 0,
  147. &sysctl_net_ipport_check, "I", "");
  148. SYSCTL_VNET_PROC(_net_inet_ip_portrange, OID_AUTO, last,
  149. CTLTYPE_INT|CTLFLAG_RW, &VNET_NAME(ipport_lastauto), 0,
  150. &sysctl_net_ipport_check, "I", "");
  151. SYSCTL_VNET_PROC(_net_inet_ip_portrange, OID_AUTO, hifirst,
  152. CTLTYPE_INT|CTLFLAG_RW, &VNET_NAME(ipport_hifirstauto), 0,
  153. &sysctl_net_ipport_check, "I", "");
  154. SYSCTL_VNET_PROC(_net_inet_ip_portrange, OID_AUTO, hilast,
  155. CTLTYPE_INT|CTLFLAG_RW, &VNET_NAME(ipport_hilastauto), 0,
  156. &sysctl_net_ipport_check, "I", "");
  157. SYSCTL_VNET_INT(_net_inet_ip_portrange, OID_AUTO, reservedhigh,
  158. CTLFLAG_RW|CTLFLAG_SECURE, &VNET_NAME(ipport_reservedhigh), 0, "");
  159. SYSCTL_VNET_INT(_net_inet_ip_portrange, OID_AUTO, reservedlow,
  160. CTLFLAG_RW|CTLFLAG_SECURE, &VNET_NAME(ipport_reservedlow), 0, "");
  161. SYSCTL_VNET_INT(_net_inet_ip_portrange, OID_AUTO, randomized, CTLFLAG_RW,
  162. &VNET_NAME(ipport_randomized), 0, "Enable random port allocation");
  163. SYSCTL_VNET_INT(_net_inet_ip_portrange, OID_AUTO, randomcps, CTLFLAG_RW,
  164. &VNET_NAME(ipport_randomcps), 0, "Maximum number of random port "
  165. "allocations before switching to a sequental one");
  166. SYSCTL_VNET_INT(_net_inet_ip_portrange, OID_AUTO, randomtime, CTLFLAG_RW,
  167. &VNET_NAME(ipport_randomtime), 0,
  168. "Minimum time to keep sequental port "
  169. "allocation before switching to a random one");
  170. #endif
  171. /*
  172. * in_pcb.c: manage the Protocol Control Blocks.
  173. *
  174. * NOTE: It is assumed that most of these functions will be called with
  175. * the pcbinfo lock held, and often, the inpcb lock held, as these utility
  176. * functions often modify hash chains or addresses in pcbs.
  177. */
  178. /*
  179. * Initialize an inpcbinfo -- we should be able to reduce the number of
  180. * arguments in time.
  181. */
  182. void
  183. in_pcbinfo_init(struct inpcbinfo *pcbinfo, const char *name,
  184. struct inpcbhead *listhead, int hash_nelements, int porthash_nelements,
  185. u_int hashfields)
  186. {
  187. INP_INFO_LOCK_INIT(pcbinfo, name);
  188. INP_HASH_LOCK_INIT(pcbinfo, "pcbinfohash"); /* XXXRW: argument? */
  189. #ifdef VIMAGE
  190. pcbinfo->ipi_vnet = curvnet;
  191. #endif
  192. pcbinfo->ipi_listhead = listhead;
  193. LIST_INIT(pcbinfo->ipi_listhead);
  194. pcbinfo->ipi_count = 0;
  195. pcbinfo->ipi_hashbase = (inpcbhead *)hashinit(hash_nelements, 0,
  196. &pcbinfo->ipi_hashmask);
  197. pcbinfo->ipi_porthashbase = (inpcbporthead *)hashinit(porthash_nelements, 0,
  198. &pcbinfo->ipi_porthashmask);
  199. // FIXME: uma_zone_set_max(pcbinfo->ipi_zone, maxsockets);
  200. }
  201. /*
  202. * Destroy an inpcbinfo.
  203. */
  204. void
  205. in_pcbinfo_destroy(struct inpcbinfo *pcbinfo)
  206. {
  207. KASSERT(pcbinfo->ipi_count == 0,
  208. ("%s: ipi_count = %u", __func__, pcbinfo->ipi_count));
  209. hashdestroy(pcbinfo->ipi_hashbase, 0, pcbinfo->ipi_hashmask);
  210. hashdestroy(pcbinfo->ipi_porthashbase, 0,
  211. pcbinfo->ipi_porthashmask);
  212. INP_HASH_LOCK_DESTROY(pcbinfo);
  213. INP_INFO_LOCK_DESTROY(pcbinfo);
  214. }
  215. /*
  216. * Allocate a PCB and associate it with the socket.
  217. * On success return with the PCB locked.
  218. */
  219. inpcb::inpcb(struct socket *so, struct inpcbinfo *pcbinfo)
  220. {
  221. struct inpcb *inp = this;
  222. INP_INFO_WLOCK_ASSERT(pcbinfo);
  223. inp->inp_pcbinfo = pcbinfo;
  224. inp->inp_socket = so;
  225. inp->inp_inc.inc_fibnum = so->so_fibnum;
  226. #ifdef IPSEC
  227. error = ipsec_init_policy(so, &inp->inp_sp);
  228. if (error != 0) {
  229. #ifdef MAC
  230. mac_inpcb_destroy(inp);
  231. #endif
  232. goto out;
  233. }
  234. #endif /*IPSEC*/
  235. #ifdef INET6
  236. if (INP_SOCKAF(so) == AF_INET6) {
  237. inp->inp_vflag |= INP_IPV6PROTO;
  238. if (V_ip6_v6only)
  239. inp->inp_flags |= IN6P_IPV6_V6ONLY;
  240. }
  241. #endif
  242. LIST_INSERT_HEAD(pcbinfo->ipi_listhead, inp, inp_list);
  243. pcbinfo->ipi_count++;
  244. so->so_pcb = (caddr_t)inp;
  245. so->set_mutex(&inp->inp_lock);
  246. #ifdef INET6
  247. if (V_ip6_auto_flowlabel)
  248. inp->inp_flags |= IN6P_AUTOFLOWLABEL;
  249. #endif
  250. INP_LOCK(inp);
  251. inp->inp_gencnt = ++pcbinfo->ipi_gencnt;
  252. refcount_init(&inp->inp_refcount, 1); /* Reference from inpcbinfo */
  253. }
  254. #ifdef INET
  255. int
  256. in_pcbbind(struct inpcb *inp, struct bsd_sockaddr *nam, struct ucred *cred)
  257. {
  258. int anonport, error;
  259. INP_LOCK_ASSERT(inp);
  260. INP_HASH_WLOCK_ASSERT(inp->inp_pcbinfo);
  261. if (inp->inp_lport != 0 || inp->inp_laddr.s_addr != INADDR_ANY)
  262. return (EINVAL);
  263. anonport = inp->inp_lport == 0 && (nam == NULL ||
  264. ((struct bsd_sockaddr_in *)nam)->sin_port == 0);
  265. error = in_pcbbind_setup(inp, nam, &inp->inp_laddr.s_addr,
  266. &inp->inp_lport, cred);
  267. if (error)
  268. return (error);
  269. if (in_pcbinshash(inp) != 0) {
  270. inp->inp_laddr.s_addr = INADDR_ANY;
  271. inp->inp_lport = 0;
  272. return (EAGAIN);
  273. }
  274. if (anonport)
  275. inp->inp_flags |= INP_ANONPORT;
  276. return (0);
  277. }
  278. #endif
  279. #if defined(INET) || defined(INET6)
  280. int
  281. in_pcb_lport(struct inpcb *inp, struct in_addr *laddrp, u_short *lportp,
  282. struct ucred *cred, int lookupflags)
  283. {
  284. struct inpcbinfo *pcbinfo;
  285. struct inpcb *tmpinp;
  286. unsigned short *lastport;
  287. int count, dorandom, error;
  288. u_short aux, first, last, lport;
  289. #ifdef INET
  290. struct in_addr laddr;
  291. #endif
  292. pcbinfo = inp->inp_pcbinfo;
  293. /*
  294. * Because no actual state changes occur here, a global write lock on
  295. * the pcbinfo isn't required.
  296. */
  297. INP_LOCK_ASSERT(inp);
  298. INP_HASH_LOCK_ASSERT(pcbinfo);
  299. if (inp->inp_flags & INP_HIGHPORT) {
  300. first = V_ipport_hifirstauto; /* sysctl */
  301. last = V_ipport_hilastauto;
  302. lastport = &pcbinfo->ipi_lasthi;
  303. } else if (inp->inp_flags & INP_LOWPORT) {
  304. error = priv_check_cred(cred, PRIV_NETINET_RESERVEDPORT, 0);
  305. if (error)
  306. return (error);
  307. first = V_ipport_lowfirstauto; /* 1023 */
  308. last = V_ipport_lowlastauto; /* 600 */
  309. lastport = &pcbinfo->ipi_lastlow;
  310. } else {
  311. first = V_ipport_firstauto; /* sysctl */
  312. last = V_ipport_lastauto;
  313. lastport = &pcbinfo->ipi_lastport;
  314. }
  315. /*
  316. * For UDP, use random port allocation as long as the user
  317. * allows it. For TCP (and as of yet unknown) connections,
  318. * use random port allocation only if the user allows it AND
  319. * ipport_tick() allows it.
  320. */
  321. if (V_ipport_randomized &&
  322. (!V_ipport_stoprandom || pcbinfo == &V_udbinfo))
  323. dorandom = 1;
  324. else
  325. dorandom = 0;
  326. /*
  327. * It makes no sense to do random port allocation if
  328. * we have the only port available.
  329. */
  330. if (first == last)
  331. dorandom = 0;
  332. /* Make sure to not include UDP packets in the count. */
  333. if (pcbinfo != &V_udbinfo)
  334. V_ipport_tcpallocs++;
  335. /*
  336. * Instead of having two loops further down counting up or down
  337. * make sure that first is always <= last and go with only one
  338. * code path implementing all logic.
  339. */
  340. if (first > last) {
  341. aux = first;
  342. first = last;
  343. last = aux;
  344. }
  345. #ifdef INET
  346. /* Make the compiler happy. */
  347. laddr.s_addr = 0;
  348. if ((inp->inp_vflag & (INP_IPV4|INP_IPV6)) == INP_IPV4) {
  349. KASSERT(laddrp != NULL, ("%s: laddrp NULL for v4 inp %p",
  350. __func__, inp));
  351. laddr = *laddrp;
  352. }
  353. #endif
  354. tmpinp = NULL; /* Make compiler happy. */
  355. lport = *lportp;
  356. if (dorandom)
  357. *lastport = first + (arc4random() % (last - first));
  358. count = last - first;
  359. do {
  360. if (count-- < 0) /* completely used? */
  361. return (EADDRNOTAVAIL);
  362. ++*lastport;
  363. if (*lastport < first || *lastport > last)
  364. *lastport = first;
  365. lport = htons(*lastport);
  366. #ifdef INET6
  367. if ((inp->inp_vflag & INP_IPV6) != 0)
  368. tmpinp = in6_pcblookup_local(pcbinfo,
  369. &inp->in6p_laddr, lport, lookupflags, cred);
  370. #endif
  371. #if defined(INET) && defined(INET6)
  372. else
  373. #endif
  374. #ifdef INET
  375. tmpinp = in_pcblookup_local(pcbinfo, laddr,
  376. lport, lookupflags, cred);
  377. #endif
  378. } while (tmpinp != NULL);
  379. #ifdef INET
  380. if ((inp->inp_vflag & (INP_IPV4|INP_IPV6)) == INP_IPV4)
  381. laddrp->s_addr = laddr.s_addr;
  382. #endif
  383. *lportp = lport;
  384. return (0);
  385. }
  386. #endif /* INET || INET6 */
  387. #ifdef INET
  388. /*
  389. * Set up a bind operation on a PCB, performing port allocation
  390. * as required, but do not actually modify the PCB. Callers can
  391. * either complete the bind by setting inp_laddr/inp_lport and
  392. * calling in_pcbinshash(), or they can just use the resulting
  393. * port and address to authorise the sending of a once-off packet.
  394. *
  395. * On error, the values of *laddrp and *lportp are not changed.
  396. */
  397. int
  398. in_pcbbind_setup(struct inpcb *inp, struct bsd_sockaddr *nam, in_addr_t *laddrp,
  399. u_short *lportp, struct ucred *cred)
  400. {
  401. struct socket *so = inp->inp_socket;
  402. struct bsd_sockaddr_in *sin;
  403. struct inpcbinfo *pcbinfo = inp->inp_pcbinfo;
  404. struct in_addr laddr;
  405. u_short lport = 0;
  406. int lookupflags = 0, reuseport = (so->so_options & SO_REUSEPORT);
  407. int error;
  408. /*
  409. * No state changes, so read locks are sufficient here.
  410. */
  411. INP_LOCK_ASSERT(inp);
  412. INP_HASH_LOCK_ASSERT(pcbinfo);
  413. if (TAILQ_EMPTY(&V_in_ifaddrhead)) /* XXX broken! */
  414. return (EADDRNOTAVAIL);
  415. laddr.s_addr = *laddrp;
  416. if (nam != NULL && laddr.s_addr != INADDR_ANY)
  417. return (EINVAL);
  418. if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) == 0)
  419. lookupflags = INPLOOKUP_WILDCARD;
  420. if (nam != NULL) {
  421. sin = (struct bsd_sockaddr_in *)nam;
  422. if (nam->sa_len != sizeof (*sin))
  423. return (EINVAL);
  424. #ifdef notdef
  425. /*
  426. * We should check the family, but old programs
  427. * incorrectly fail to initialize it.
  428. */
  429. if (sin->sin_family != AF_INET)
  430. return (EAFNOSUPPORT);
  431. #endif
  432. if (sin->sin_port != *lportp) {
  433. /* Don't allow the port to change. */
  434. if (*lportp != 0)
  435. return (EINVAL);
  436. lport = sin->sin_port;
  437. }
  438. /* NB: lport is left as 0 if the port isn't being changed. */
  439. if (IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) {
  440. /*
  441. * Treat SO_REUSEADDR as SO_REUSEPORT for multicast;
  442. * allow complete duplication of binding if
  443. * SO_REUSEPORT is set, or if SO_REUSEADDR is set
  444. * and a multicast address is bound on both
  445. * new and duplicated sockets.
  446. */
  447. if (so->so_options & SO_REUSEADDR)
  448. reuseport = SO_REUSEADDR|SO_REUSEPORT;
  449. } else if (sin->sin_addr.s_addr != INADDR_ANY) {
  450. sin->sin_port = 0; /* yech... */
  451. bzero(&sin->sin_zero, sizeof(sin->sin_zero));
  452. /*
  453. * Is the address a local IP address?
  454. * If INP_BINDANY is set, then the socket may be bound
  455. * to any endpoint address, local or not.
  456. */
  457. if ((inp->inp_flags & INP_BINDANY) == 0 &&
  458. ifa_ifwithaddr_check((struct bsd_sockaddr *)sin) == 0)
  459. return (EADDRNOTAVAIL);
  460. }
  461. laddr = sin->sin_addr;
  462. if (lport) {
  463. struct inpcb *t;
  464. struct tcptw *tw;
  465. /* GROSS */
  466. if (ntohs(lport) <= V_ipport_reservedhigh &&
  467. ntohs(lport) >= V_ipport_reservedlow &&
  468. priv_check_cred(cred, PRIV_NETINET_RESERVEDPORT,
  469. 0))
  470. return (EACCES);
  471. if (!IN_MULTICAST(ntohl(sin->sin_addr.s_addr)) &&
  472. priv_check_cred(inp->inp_cred,
  473. PRIV_NETINET_REUSEPORT, 0) != 0) {
  474. t = in_pcblookup_local(pcbinfo, sin->sin_addr,
  475. lport, INPLOOKUP_WILDCARD, cred);
  476. /*
  477. * XXX
  478. * This entire block sorely needs a rewrite.
  479. */
  480. #if 0
  481. if (t &&
  482. ((t->inp_flags & INP_TIMEWAIT) == 0) &&
  483. (so->so_type != SOCK_STREAM ||
  484. ntohl(t->inp_faddr.s_addr) == INADDR_ANY) &&
  485. (ntohl(sin->sin_addr.s_addr) != INADDR_ANY ||
  486. ntohl(t->inp_laddr.s_addr) != INADDR_ANY ||
  487. (t->inp_flags2 & INP_REUSEPORT) == 0) &&
  488. (inp->inp_cred->cr_uid !=
  489. t->inp_cred->cr_uid))
  490. return (EADDRINUSE);
  491. #endif
  492. }
  493. t = in_pcblookup_local(pcbinfo, sin->sin_addr,
  494. lport, lookupflags, cred);
  495. if (t && (t->inp_flags & INP_TIMEWAIT)) {
  496. /*
  497. * XXXRW: If an incpb has had its timewait
  498. * state recycled, we treat the address as
  499. * being in use (for now). This is better
  500. * than a panic, but not desirable.
  501. */
  502. /*
  503. * Linux allows a SO_REUSEADDR socket to be
  504. * bound to an existing TIME_WAIT socket
  505. * if SO_REUSEADDR is set on the new socket.
  506. *
  507. * Allow for that in addition to the BSD
  508. * SO_REUSEPORT semantics.
  509. */
  510. tw = intotw(t);
  511. if (tw == NULL ||
  512. ((reuseport & tw->tw_so_options) == 0)
  513. && (so->so_options & SO_REUSEADDR) == 0)
  514. return (EADDRINUSE);
  515. } else if (t && (reuseport == 0 ||
  516. (t->inp_flags2 & INP_REUSEPORT) == 0)) {
  517. #ifdef INET6
  518. if (ntohl(sin->sin_addr.s_addr) !=
  519. INADDR_ANY ||
  520. ntohl(t->inp_laddr.s_addr) !=
  521. INADDR_ANY ||
  522. (inp->inp_vflag & INP_IPV6PROTO) == 0 ||
  523. (t->inp_vflag & INP_IPV6PROTO) == 0)
  524. #endif
  525. return (EADDRINUSE);
  526. }
  527. }
  528. }
  529. if (*lportp != 0)
  530. lport = *lportp;
  531. if (lport == 0) {
  532. error = in_pcb_lport(inp, &laddr, &lport, cred, lookupflags);
  533. if (error != 0)
  534. return (error);
  535. }
  536. *laddrp = laddr.s_addr;
  537. *lportp = lport;
  538. return (0);
  539. }
  540. /*
  541. * Connect from a socket to a specified address.
  542. * Both address and port must be specified in argument sin.
  543. * If don't have a local address for this socket yet,
  544. * then pick one.
  545. */
  546. int
  547. in_pcbconnect_mbuf(struct inpcb *inp, struct bsd_sockaddr *nam,
  548. struct ucred *cred, struct mbuf *m)
  549. {
  550. u_short lport, fport;
  551. in_addr_t laddr, faddr;
  552. int anonport, error;
  553. INP_LOCK_ASSERT(inp);
  554. INP_HASH_WLOCK_ASSERT(inp->inp_pcbinfo);
  555. lport = inp->inp_lport;
  556. laddr = inp->inp_laddr.s_addr;
  557. anonport = (lport == 0);
  558. error = in_pcbconnect_setup(inp, nam, &laddr, &lport, &faddr, &fport,
  559. NULL, cred);
  560. if (error)
  561. return (error);
  562. /* Do the initial binding of the local address if required. */
  563. if (inp->inp_laddr.s_addr == INADDR_ANY && inp->inp_lport == 0) {
  564. inp->inp_lport = lport;
  565. inp->inp_laddr.s_addr = laddr;
  566. if (in_pcbinshash(inp) != 0) {
  567. inp->inp_laddr.s_addr = INADDR_ANY;
  568. inp->inp_lport = 0;
  569. return (EAGAIN);
  570. }
  571. }
  572. /* Commit the remaining changes. */
  573. inp->inp_lport = lport;
  574. inp->inp_laddr.s_addr = laddr;
  575. inp->inp_faddr.s_addr = faddr;
  576. inp->inp_fport = fport;
  577. in_pcbrehash_mbuf(inp, m);
  578. if (anonport)
  579. inp->inp_flags |= INP_ANONPORT;
  580. return (0);
  581. }
  582. int
  583. in_pcbconnect(struct inpcb *inp, struct bsd_sockaddr *nam, struct ucred *cred)
  584. {
  585. return (in_pcbconnect_mbuf(inp, nam, cred, NULL));
  586. }
  587. /*
  588. * Do proper source address selection on an unbound socket in case
  589. * of connect. Take jails into account as well.
  590. */
  591. static int
  592. in_pcbladdr(struct inpcb *inp, struct in_addr *faddr, struct in_addr *laddr,
  593. struct ucred *cred)
  594. {
  595. struct bsd_ifaddr *ifa;
  596. struct bsd_sockaddr *sa;
  597. struct bsd_sockaddr_in *sin;
  598. struct route sro;
  599. struct rtentry rte_one;
  600. int error;
  601. KASSERT(laddr != NULL, ("%s: laddr NULL", __func__));
  602. error = 0;
  603. bzero(&sro, sizeof(sro));
  604. sin = (struct bsd_sockaddr_in *)&sro.ro_dst;
  605. sin->sin_family = AF_INET;
  606. sin->sin_len = sizeof(struct bsd_sockaddr_in);
  607. sin->sin_addr.s_addr = faddr->s_addr;
  608. /*
  609. * If route is known our src addr is taken from the i/f,
  610. * else punt.
  611. *
  612. * Find out route to destination.
  613. */
  614. if ((inp->inp_socket->so_options & SO_DONTROUTE) == 0)
  615. {
  616. if (route_cache::lookup(sin, inp->inp_inc.inc_fibnum, &rte_one)) {
  617. sro.ro_rt = &rte_one;
  618. } else {
  619. sro.ro_rt = NULL;
  620. }
  621. }
  622. /*
  623. * If we found a route, use the address corresponding to
  624. * the outgoing interface.
  625. *
  626. * Otherwise assume faddr is reachable on a directly connected
  627. * network and try to find a corresponding interface to take
  628. * the source address from.
  629. */
  630. if (sro.ro_rt == NULL || sro.ro_rt->rt_ifp == NULL) {
  631. struct in_ifaddr *ia;
  632. struct ifnet *ifp;
  633. ia = ifatoia(ifa_ifwithdstaddr((struct bsd_sockaddr *)sin));
  634. if (ia == NULL)
  635. ia = ifatoia(ifa_ifwithnet((struct bsd_sockaddr *)sin, 0));
  636. if (ia == NULL) {
  637. error = ENETUNREACH;
  638. goto done;
  639. }
  640. ifp = ia->ia_ifp;
  641. ifa_free(&ia->ia_ifa);
  642. ia = NULL;
  643. IF_ADDR_RLOCK(ifp);
  644. TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
  645. sa = ifa->ifa_addr;
  646. if (sa->sa_family != AF_INET)
  647. continue;
  648. sin = (struct bsd_sockaddr_in *)sa;
  649. ia = (struct in_ifaddr *)ifa;
  650. break;
  651. }
  652. if (ia != NULL) {
  653. laddr->s_addr = ia->ia_addr.sin_addr.s_addr;
  654. IF_ADDR_RUNLOCK(ifp);
  655. goto done;
  656. }
  657. IF_ADDR_RUNLOCK(ifp);
  658. error = 0;
  659. goto done;
  660. }
  661. /*
  662. * If the outgoing interface on the route found is not
  663. * a loopback interface, use the address from that interface.
  664. * In case of jails do those three steps:
  665. * 1. check if the interface address belongs to the jail. If so use it.
  666. * 2. check if we have any address on the outgoing interface
  667. * belonging to this jail. If so use it.
  668. * 3. as a last resort return the 'default' jail address.
  669. */
  670. if ((sro.ro_rt->rt_ifp->if_flags & IFF_LOOPBACK) == 0) {
  671. struct in_ifaddr *ia;
  672. ia = (struct in_ifaddr *)sro.ro_rt->rt_ifa;
  673. laddr->s_addr = ia->ia_addr.sin_addr.s_addr;
  674. goto done;
  675. }
  676. /*
  677. * The outgoing interface is marked with 'loopback net', so a route
  678. * to ourselves is here.
  679. * Try to find the interface of the destination address and then
  680. * take the address from there. That interface is not necessarily
  681. * a loopback interface.
  682. * In case of jails, check that it is an address of the jail
  683. * and if we cannot find, fall back to the 'default' jail address.
  684. */
  685. if ((sro.ro_rt->rt_ifp->if_flags & IFF_LOOPBACK) != 0) {
  686. struct bsd_sockaddr_in sain;
  687. struct in_ifaddr *ia;
  688. bzero(&sain, sizeof(struct bsd_sockaddr_in));
  689. sain.sin_family = AF_INET;
  690. sain.sin_len = sizeof(struct bsd_sockaddr_in);
  691. sain.sin_addr.s_addr = faddr->s_addr;
  692. ia = ifatoia(ifa_ifwithdstaddr(sintosa(&sain)));
  693. if (ia == NULL)
  694. ia = ifatoia(ifa_ifwithnet(sintosa(&sain), 0));
  695. if (ia == NULL)
  696. ia = ifatoia(ifa_ifwithaddr(sintosa(&sain)));
  697. if (ia == NULL) {
  698. error = ENETUNREACH;
  699. goto done;
  700. }
  701. laddr->s_addr = ia->ia_addr.sin_addr.s_addr;
  702. ifa_free(&ia->ia_ifa);
  703. goto done;
  704. }
  705. done:
  706. return (error);
  707. }
  708. /*
  709. * Set up for a connect from a socket to the specified address.
  710. * On entry, *laddrp and *lportp should contain the current local
  711. * address and port for the PCB; these are updated to the values
  712. * that should be placed in inp_laddr and inp_lport to complete
  713. * the connect.
  714. *
  715. * On success, *faddrp and *fportp will be set to the remote address
  716. * and port. These are not updated in the error case.
  717. *
  718. * If the operation fails because the connection already exists,
  719. * *oinpp will be set to the PCB of that connection so that the
  720. * caller can decide to override it. In all other cases, *oinpp
  721. * is set to NULL.
  722. */
  723. int
  724. in_pcbconnect_setup(struct inpcb *inp, struct bsd_sockaddr *nam,
  725. in_addr_t *laddrp, u_short *lportp, in_addr_t *faddrp, u_short *fportp,
  726. struct inpcb **oinpp, struct ucred *cred)
  727. {
  728. struct bsd_sockaddr_in *sin = (struct bsd_sockaddr_in *)nam;
  729. struct in_ifaddr *ia;
  730. struct inpcb *oinp;
  731. struct in_addr laddr, faddr;
  732. u_short lport, fport;
  733. int error;
  734. /*
  735. * Because a global state change doesn't actually occur here, a read
  736. * lock is sufficient.
  737. */
  738. INP_LOCK_ASSERT(inp);
  739. INP_HASH_LOCK_ASSERT(inp->inp_pcbinfo);
  740. if (oinpp != NULL)
  741. *oinpp = NULL;
  742. if (nam->sa_len != sizeof (*sin))
  743. return (EINVAL);
  744. if (sin->sin_family != AF_INET)
  745. return (EAFNOSUPPORT);
  746. if (sin->sin_port == 0)
  747. return (EADDRNOTAVAIL);
  748. laddr.s_addr = *laddrp;
  749. lport = *lportp;
  750. faddr = sin->sin_addr;
  751. fport = sin->sin_port;
  752. if (!TAILQ_EMPTY(&V_in_ifaddrhead)) {
  753. /*
  754. * If the destination address is INADDR_ANY,
  755. * use the primary local address.
  756. * If the supplied address is INADDR_BROADCAST,
  757. * and the primary interface supports broadcast,
  758. * choose the broadcast address for that interface.
  759. */
  760. if (faddr.s_addr == INADDR_ANY) {
  761. IN_IFADDR_RLOCK();
  762. faddr =
  763. IA_SIN(TAILQ_FIRST(&V_in_ifaddrhead))->sin_addr;
  764. IN_IFADDR_RUNLOCK();
  765. } else if (faddr.s_addr == (u_long)INADDR_BROADCAST) {
  766. IN_IFADDR_RLOCK();
  767. if (TAILQ_FIRST(&V_in_ifaddrhead)->ia_ifp->if_flags &
  768. IFF_BROADCAST)
  769. faddr = satosin(&TAILQ_FIRST(
  770. &V_in_ifaddrhead)->ia_broadaddr)->sin_addr;
  771. IN_IFADDR_RUNLOCK();
  772. }
  773. }
  774. if (laddr.s_addr == INADDR_ANY) {
  775. error = in_pcbladdr(inp, &faddr, &laddr, cred);
  776. /*
  777. * If the destination address is multicast and an outgoing
  778. * interface has been set as a multicast option, prefer the
  779. * address of that interface as our source address.
  780. */
  781. if (IN_MULTICAST(ntohl(faddr.s_addr)) &&
  782. inp->inp_moptions != NULL) {
  783. struct ip_moptions *imo;
  784. struct ifnet *ifp;
  785. imo = inp->inp_moptions;
  786. if (imo->imo_multicast_ifp != NULL) {
  787. ifp = imo->imo_multicast_ifp;
  788. IN_IFADDR_RLOCK();
  789. TAILQ_FOREACH(ia, &V_in_ifaddrhead, ia_link) {
  790. if (ia->ia_ifp == ifp)
  791. break;
  792. }
  793. if (ia == NULL)
  794. error = EADDRNOTAVAIL;
  795. else {
  796. laddr = ia->ia_addr.sin_addr;
  797. error = 0;
  798. }
  799. IN_IFADDR_RUNLOCK();
  800. }
  801. }
  802. if (error)
  803. return (error);
  804. }
  805. oinp = in_pcblookup_hash_locked(inp->inp_pcbinfo, faddr, fport,
  806. laddr, lport, 0, NULL);
  807. if (oinp != NULL) {
  808. if (oinpp != NULL)
  809. *oinpp = oinp;
  810. return (EADDRINUSE);
  811. }
  812. if (lport == 0) {
  813. error = in_pcbbind_setup(inp, NULL, &laddr.s_addr, &lport,
  814. cred);
  815. if (error)
  816. return (error);
  817. }
  818. *laddrp = laddr.s_addr;
  819. *lportp = lport;
  820. *faddrp = faddr.s_addr;
  821. *fportp = fport;
  822. return (0);
  823. }
  824. void
  825. in_pcbdisconnect(struct inpcb *inp)
  826. {
  827. INP_LOCK_ASSERT(inp);
  828. INP_HASH_WLOCK_ASSERT(inp->inp_pcbinfo);
  829. inp->inp_faddr.s_addr = INADDR_ANY;
  830. inp->inp_fport = 0;
  831. in_pcbrehash(inp);
  832. }
  833. #endif
  834. /*
  835. * in_pcbdetach() is responsibe for disassociating a socket from an inpcb.
  836. * For most protocols, this will be invoked immediately prior to calling
  837. * in_pcbfree(). However, with TCP the inpcb may significantly outlive the
  838. * socket, in which case in_pcbfree() is deferred.
  839. */
  840. void
  841. in_pcbdetach(struct inpcb *inp)
  842. {
  843. KASSERT(inp->inp_socket != NULL, ("%s: inp_socket == NULL", __func__));
  844. inp->inp_socket->so_pcb = NULL;
  845. inp->inp_socket = NULL;
  846. }
  847. /*
  848. * in_pcbref() bumps the reference count on an inpcb in order to maintain
  849. * stability of an inpcb pointer despite the inpcb lock being released. This
  850. * is used in TCP when the inpcbinfo lock needs to be acquired or upgraded,
  851. * but where the inpcb lock may already held.
  852. *
  853. * in_pcbref() should be used only to provide brief memory stability, and
  854. * must always be followed by a call to INP_WLOCK() and in_pcbrele() to
  855. * garbage collect the inpcb if it has been in_pcbfree()'d from another
  856. * context. Until in_pcbrele() has returned that the inpcb is still valid,
  857. * lock and rele are the *only* safe operations that may be performed on the
  858. * inpcb.
  859. *
  860. * While the inpcb will not be freed, releasing the inpcb lock means that the
  861. * connection's state may change, so the caller should be careful to
  862. * revalidate any cached state on reacquiring the lock. Drop the reference
  863. * using in_pcbrele().
  864. */
  865. void
  866. in_pcbref(struct inpcb *inp)
  867. {
  868. KASSERT(inp->inp_refcount > 0, ("%s: refcount 0", __func__));
  869. trace_inpcb_ref(inp);
  870. refcount_acquire(&inp->inp_refcount);
  871. }
  872. /*
  873. * Drop a refcount on an inpcb elevated using in_pcbref(); because a call to
  874. * in_pcbfree() may have been made between in_pcbref() and in_pcbrele(), we
  875. * return a flag indicating whether or not the inpcb remains valid. If it is
  876. * valid, we return with the inpcb lock held.
  877. *
  878. * Notice that, unlike in_pcbref(), the inpcb lock must be held to drop a
  879. * reference on an inpcb. Historically more work was done here (actually, in
  880. * in_pcbfree_internal()) but has been moved to in_pcbfree() to avoid the
  881. * need for the pcbinfo lock in in_pcbrele(). Deferring the free is entirely
  882. * about memory stability (and continued use of the write lock).
  883. */
  884. int
  885. in_pcbrele_locked(struct inpcb *inp)
  886. {
  887. struct inpcbinfo *pcbinfo;
  888. KASSERT(inp->inp_refcount > 0, ("%s: refcount 0", __func__));
  889. trace_inpcb_rele(inp);
  890. INP_LOCK_ASSERT(inp);
  891. if (refcount_release(&inp->inp_refcount) == 0) {
  892. /*
  893. * If the inpcb has been freed, let the caller know, even if
  894. * this isn't the last reference.
  895. */
  896. if (inp->inp_flags2 & INP_FREED) {
  897. INP_UNLOCK(inp);
  898. return (1);
  899. }
  900. return (0);
  901. }
  902. KASSERT(inp->inp_socket == NULL, ("%s: inp_socket != NULL", __func__));
  903. trace_inpcb_free(inp);
  904. INP_UNLOCK(inp);
  905. pcbinfo = inp->inp_pcbinfo;
  906. delete inp;
  907. return (1);
  908. }
  909. /*
  910. * Temporary wrapper.
  911. */
  912. int
  913. in_pcbrele(struct inpcb *inp)
  914. {
  915. return (in_pcbrele_locked(inp));
  916. }
  917. /*
  918. * Unconditionally schedule an inpcb to be freed by decrementing its
  919. * reference count, which should occur only after the inpcb has been detached
  920. * from its socket. If another thread holds a temporary reference (acquired
  921. * using in_pcbref()) then the free is deferred until that reference is
  922. * released using in_pcbrele(), but the inpcb is still unlocked. Almost all
  923. * work, including removal from global lists, is done in this context, where
  924. * the pcbinfo lock is held.
  925. */
  926. void
  927. in_pcbfree(struct inpcb *inp)
  928. {
  929. struct inpcbinfo *pcbinfo = inp->inp_pcbinfo;
  930. KASSERT(inp->inp_socket == NULL, ("%s: inp_socket != NULL", __func__));
  931. INP_INFO_WLOCK_ASSERT(pcbinfo);
  932. INP_LOCK_ASSERT(inp);
  933. /* XXXRW: Do as much as possible here. */
  934. #ifdef IPSEC
  935. if (inp->inp_sp != NULL)
  936. ipsec_delete_pcbpolicy(inp);
  937. #endif /* IPSEC */
  938. inp->inp_gencnt = ++pcbinfo->ipi_gencnt;
  939. in_pcbremlists(inp);
  940. #ifdef INET6
  941. if (inp->inp_vflag & INP_IPV6PROTO) {
  942. ip6_freepcbopts(inp->in6p_outputopts);
  943. if (inp->in6p_moptions != NULL)
  944. ip6_freemoptions(inp->in6p_moptions);
  945. }
  946. #endif
  947. if (inp->inp_options)
  948. (void)m_free(inp->inp_options);
  949. #ifdef INET
  950. if (inp->inp_moptions != NULL)
  951. inp_freemoptions(inp->inp_moptions);
  952. #endif
  953. inp->inp_vflag = 0;
  954. inp->inp_flags2 |= INP_FREED;
  955. #ifdef MAC
  956. mac_inpcb_destroy(inp);
  957. #endif
  958. if (!in_pcbrele_locked(inp))
  959. INP_UNLOCK(inp);
  960. }
  961. /*
  962. * in_pcbdrop() removes an inpcb from hashed lists, releasing its address and
  963. * port reservation, and preventing it from being returned by inpcb lookups.
  964. *
  965. * It is used by TCP to mark an inpcb as unused and avoid future packet
  966. * delivery or event notification when a socket remains open but TCP has
  967. * closed. This might occur as a result of a shutdown()-initiated TCP close
  968. * or a RST on the wire, and allows the port binding to be reused while still
  969. * maintaining the invariant that so_pcb always points to a valid inpcb until
  970. * in_pcbdetach().
  971. *
  972. * XXXRW: Possibly in_pcbdrop() should also prevent future notifications by
  973. * in_pcbnotifyall() and in_pcbpurgeif0()?
  974. */
  975. void
  976. in_pcbdrop(struct inpcb *inp)
  977. {
  978. INP_LOCK_ASSERT(inp);
  979. /*
  980. * XXXRW: Possibly we should protect the setting of INP_DROPPED with
  981. * the hash lock...?
  982. */
  983. inp->inp_flags |= INP_DROPPED;
  984. if (inp->inp_flags & INP_INHASHLIST) {
  985. struct inpcbport *phd = inp->inp_phd;
  986. INP_HASH_WLOCK(inp->inp_pcbinfo);
  987. LIST_REMOVE(inp, inp_hash);
  988. LIST_REMOVE(inp, inp_portlist);
  989. if (LIST_FIRST(&phd->phd_pcblist) == NULL) {
  990. LIST_REMOVE(phd, phd_hash);
  991. free(phd);
  992. }
  993. INP_HASH_WUNLOCK(inp->inp_pcbinfo);
  994. inp->inp_flags &= ~INP_INHASHLIST;
  995. }
  996. }
  997. #ifdef INET
  998. /*
  999. * Common routines to return the socket addresses associated with inpcbs.
  1000. */
  1001. struct bsd_sockaddr *
  1002. in_sockaddr(in_port_t port, struct in_addr *addr_p)
  1003. {
  1004. struct bsd_sockaddr_in *sin;
  1005. sin = (bsd_sockaddr_in *)malloc(sizeof *sin);
  1006. bzero(sin, sizeof *sin);
  1007. sin->sin_family = AF_INET;
  1008. sin->sin_len = sizeof(*sin);
  1009. sin->sin_addr = *addr_p;
  1010. sin->sin_port = port;
  1011. return (struct bsd_sockaddr *)sin;
  1012. }
  1013. int
  1014. in_getsockaddr(struct socket *so, struct bsd_sockaddr **nam)
  1015. {
  1016. struct inpcb *inp;
  1017. struct in_addr addr;
  1018. in_port_t port;
  1019. inp = sotoinpcb(so);
  1020. KASSERT(inp != NULL, ("in_getsockaddr: inp == NULL"));
  1021. INP_LOCK(inp);
  1022. port = inp->inp_lport;
  1023. addr = inp->inp_laddr;
  1024. INP_UNLOCK(inp);
  1025. *nam = in_sockaddr(port, &addr);
  1026. return 0;
  1027. }
  1028. int
  1029. in_getpeeraddr(struct socket *so, struct bsd_sockaddr **nam)
  1030. {
  1031. struct inpcb *inp;
  1032. struct in_addr addr;
  1033. in_port_t port;
  1034. inp = sotoinpcb(so);
  1035. KASSERT(inp != NULL, ("in_getpeeraddr: inp == NULL"));
  1036. INP_LOCK(inp);
  1037. port = inp->inp_fport;
  1038. addr = inp->inp_faddr;
  1039. INP_UNLOCK(inp);
  1040. *nam = in_sockaddr(port, &addr);
  1041. return 0;
  1042. }
  1043. void
  1044. in_pcbnotifyall(struct inpcbinfo *pcbinfo, struct in_addr faddr, int errval,
  1045. struct inpcb *(*notify)(struct inpcb *, int))
  1046. {
  1047. struct inpcb *inp, *inp_temp;
  1048. INP_INFO_WLOCK(pcbinfo);
  1049. LIST_FOREACH_SAFE(inp, pcbinfo->ipi_listhead, inp_list, inp_temp) {
  1050. INP_LOCK(inp);
  1051. #ifdef INET6
  1052. if ((inp->inp_vflag & INP_IPV4) == 0) {
  1053. INP_UNLOCK(inp);
  1054. continue;
  1055. }
  1056. #endif
  1057. if (inp->inp_faddr.s_addr != faddr.s_addr ||
  1058. inp->inp_socket == NULL) {
  1059. INP_UNLOCK(inp);
  1060. continue;
  1061. }
  1062. if ((*notify)(inp, errval))
  1063. INP_UNLOCK(inp);
  1064. }
  1065. INP_INFO_WUNLOCK(pcbinfo);
  1066. }
  1067. void
  1068. in_pcbpurgeif0(struct inpcbinfo *pcbinfo, struct ifnet *ifp)
  1069. {
  1070. struct inpcb *inp;
  1071. struct ip_moptions *imo;
  1072. int i, gap;
  1073. INP_INFO_WLOCK(pcbinfo);
  1074. LIST_FOREACH(inp, pcbinfo->ipi_listhead, inp_list) {
  1075. INP_LOCK(inp);
  1076. imo = inp->inp_moptions;
  1077. if ((inp->inp_vflag & INP_IPV4) &&
  1078. imo != NULL) {
  1079. /*
  1080. * Unselect the outgoing interface if it is being
  1081. * detached.
  1082. */
  1083. if (imo->imo_multicast_ifp == ifp)
  1084. imo->imo_multicast_ifp = NULL;
  1085. /*
  1086. * Drop multicast group membership if we joined
  1087. * through the interface being detached.
  1088. */
  1089. for (i = 0, gap = 0; i < imo->imo_num_memberships;
  1090. i++) {
  1091. if (imo->imo_membership[i]->inm_ifp == ifp) {
  1092. in_delmulti(imo->imo_membership[i]);
  1093. gap++;
  1094. } else if (gap != 0)
  1095. imo->imo_membership[i - gap] =
  1096. imo->imo_membership[i];
  1097. }
  1098. imo->imo_num_memberships -= gap;
  1099. }
  1100. INP_UNLOCK(inp);
  1101. }
  1102. INP_INFO_WUNLOCK(pcbinfo);
  1103. }
  1104. /*
  1105. * Lookup a PCB based on the local address and port. Caller must hold the
  1106. * hash lock. No inpcb locks or references are acquired.
  1107. */
  1108. #define INP_LOOKUP_MAPPED_PCB_COST 3
  1109. struct inpcb *
  1110. in_pcblookup_local(struct inpcbinfo *pcbinfo, struct in_addr laddr,
  1111. u_short lport, int lookupflags, struct ucred *cred)
  1112. {
  1113. struct inpcb *inp;
  1114. #ifdef INET6
  1115. int matchwild = 3 + INP_LOOKUP_MAPPED_PCB_COST;
  1116. #else
  1117. int matchwild = 3;
  1118. #endif
  1119. int wildcard;
  1120. KASSERT((lookupflags & ~(INPLOOKUP_WILDCARD)) == 0,
  1121. ("%s: invalid lookup flags %d", __func__, lookupflags));
  1122. INP_HASH_LOCK_ASSERT(pcbinfo);
  1123. if ((lookupflags & INPLOOKUP_WILDCARD) == 0) {
  1124. struct inpcbhead *head;
  1125. /*
  1126. * Look for an unconnected (wildcard foreign addr) PCB that
  1127. * matches the local address and port we're looking for.
  1128. */
  1129. head = &pcbinfo->ipi_hashbase[INP_PCBHASH(INADDR_ANY, lport,
  1130. 0, pcbinfo->ipi_hashmask)];
  1131. LIST_FOREACH(inp, head, inp_hash) {
  1132. #ifdef INET6
  1133. /* XXX inp locking */
  1134. if ((inp->inp_vflag & INP_IPV4) == 0)
  1135. continue;
  1136. #endif
  1137. if (inp->inp_faddr.s_addr == INADDR_ANY &&
  1138. inp->inp_laddr.s_addr == laddr.s_addr &&
  1139. inp->inp_lport == lport) {
  1140. /*
  1141. * Found?
  1142. */
  1143. return (inp);
  1144. }
  1145. }
  1146. /*
  1147. * Not found.
  1148. */
  1149. return (NULL);
  1150. } else {
  1151. struct inpcbporthead *porthash;
  1152. struct inpcbport *phd;
  1153. struct inpcb *match = NULL;
  1154. /*
  1155. * Best fit PCB lookup.
  1156. *
  1157. * First see if this local port is in use by looking on the
  1158. * port hash list.
  1159. */
  1160. porthash = &pcbinfo->ipi_porthashbase[INP_PCBPORTHASH(lport,
  1161. pcbinfo->ipi_porthashmask)];
  1162. LIST_FOREACH(phd, porthash, phd_hash) {
  1163. if (phd->phd_port == lport)
  1164. break;
  1165. }
  1166. if (phd != NULL) {
  1167. /*
  1168. * Port is in use by one or more PCBs. Look for best
  1169. * fit.
  1170. */
  1171. LIST_FOREACH(inp, &phd->phd_pcblist, inp_portlist) {
  1172. wildcard = 0;
  1173. #ifdef INET6
  1174. /* XXX inp locking */
  1175. if ((inp->inp_vflag & INP_IPV4) == 0)
  1176. continue;
  1177. /*
  1178. * We never select the PCB that has
  1179. * INP_IPV6 flag and is bound to :: if
  1180. * we have another PCB which is bound
  1181. * to 0.0.0.0. If a PCB has the
  1182. * INP_IPV6 flag, then we set its cost
  1183. * higher than IPv4 only PCBs.
  1184. *
  1185. * Note that the case only happens
  1186. * when a socket is bound to ::, under
  1187. * the condition that the use of the
  1188. * mapped address is allowed.
  1189. */
  1190. if ((inp->inp_vflag & INP_IPV6) != 0)
  1191. wildcard += INP_LOOKUP_MAPPED_PCB_COST;
  1192. #endif
  1193. if (inp->inp_faddr.s_addr != INADDR_ANY)
  1194. wildcard++;
  1195. if (inp->inp_laddr.s_addr != INADDR_ANY) {
  1196. if (laddr.s_addr == INADDR_ANY)
  1197. wildcard++;
  1198. else if (inp->inp_laddr.s_addr != laddr.s_addr)
  1199. continue;
  1200. } else {
  1201. if (laddr.s_addr != INADDR_ANY)
  1202. wildcard++;
  1203. }
  1204. if (wildcard < matchwild) {
  1205. match = inp;
  1206. matchwild = wildcard;
  1207. if (matchwild == 0)
  1208. break;
  1209. }
  1210. }
  1211. }
  1212. return (match);
  1213. }
  1214. }
  1215. #undef INP_LOOKUP_MAPPED_PCB_COST
  1216. /*
  1217. * Lookup PCB in hash list, using pcbinfo tables. This variation assumes
  1218. * that the caller has locked the hash list, and will not perform any further
  1219. * locking or reference operations on either the hash list or the connection.
  1220. */
  1221. static struct inpcb *
  1222. in_pcblookup_hash_locked(struct inpcbinfo *pcbinfo, struct in_addr faddr,
  1223. u_int fport_arg, struct in_addr laddr, u_int lport_arg, int lookupflags,
  1224. struct ifnet *ifp)
  1225. {
  1226. struct inpcbhead *head;
  1227. struct inpcb *inp, *tmpinp;
  1228. u_short fport = fport_arg, lport = lport_arg;
  1229. KASSERT((lookupflags & ~(INPLOOKUP_WILDCARD)) == 0,
  1230. ("%s: invalid lookup flags %d", __func__, lookupflags));
  1231. INP_HASH_LOCK_ASSERT(pcbinfo);
  1232. /*
  1233. * First look for an exact match.
  1234. */
  1235. tmpinp = NULL;
  1236. head = &pcbinfo->ipi_hashbase[INP_PCBHASH(faddr.s_addr, lport, fport,
  1237. pcbinfo->ipi_hashmask)];
  1238. LIST_FOREACH(inp, head, inp_hash) {
  1239. #ifdef INET6
  1240. /* XXX inp locking */
  1241. if ((inp->inp_vflag & INP_IPV4) == 0)
  1242. continue;
  1243. #endif
  1244. if (inp->inp_faddr.s_addr == faddr.s_addr &&
  1245. inp->inp_laddr.s_addr == laddr.s_addr &&
  1246. inp->inp_fport == fport &&
  1247. inp->inp_lport == lport) {
  1248. /*
  1249. * XXX We should be able to directly return
  1250. * the inp here, without any checks.
  1251. * Well unless both bound with SO_REUSEPORT?
  1252. */
  1253. if (tmpinp == NULL)
  1254. tmpinp = inp;
  1255. }
  1256. }
  1257. if (tmpinp != NULL)
  1258. return (tmpinp);
  1259. /*
  1260. * Then look for a wildcard match, if requested.
  1261. */
  1262. if ((lookupflags & INPLOOKUP_WILDCARD) != 0) {
  1263. struct inpcb *local_wild = NULL, *local_exact = NULL;
  1264. #ifdef INET6
  1265. struct inpcb *local_wild_mapped = NULL;
  1266. #endif
  1267. struct inpcb *jail_wild = NULL;
  1268. int injail;
  1269. /*
  1270. * Order of socket selection - we always prefer jails.
  1271. * 1. jailed, non-wild.
  1272. * 2. jailed, wild.
  1273. * 3. non-jailed, non-wild.
  1274. * 4. non-jailed, wild.
  1275. */
  1276. head = &pcbinfo->ipi_hashbase[INP_PCBHASH(INADDR_ANY, lport,
  1277. 0, pcbinfo->ipi_hashmask)];
  1278. LIST_FOREACH(inp, head, inp_hash) {
  1279. #ifdef INET6
  1280. /* XXX inp locking */
  1281. if ((inp->inp_vflag & INP_IPV4) == 0)
  1282. continue;
  1283. #endif
  1284. if (inp->inp_faddr.s_addr != INADDR_ANY ||
  1285. inp->inp_lport != lport)
  1286. continue;
  1287. /* XXX inp locking */
  1288. if (ifp && ifp->if_type == IFT_FAITH &&
  1289. (inp->inp_flags & INP_FAITH) == 0)
  1290. continue;
  1291. injail = 0;
  1292. if (local_exact != NULL)
  1293. continue;
  1294. if (inp->inp_laddr.s_addr == laddr.s_addr) {
  1295. if (injail)
  1296. return (inp);
  1297. else
  1298. local_exact = inp;
  1299. } else if (inp->inp_laddr.s_addr == INADDR_ANY) {
  1300. #ifdef INET6
  1301. /* XXX inp locking, NULL check */
  1302. if (inp->inp_vflag & INP_IPV6PROTO)
  1303. local_wild_mapped = inp;
  1304. else
  1305. #endif /* INET6 */
  1306. if (injail)
  1307. jail_wild = inp;
  1308. else
  1309. local_wild = inp;
  1310. }
  1311. } /* LIST_FOREACH */
  1312. if (jail_wild != NULL)
  1313. return (jail_wild);
  1314. if (local_exact != NULL)
  1315. return (local_exact);
  1316. if (local_wild != NULL)
  1317. return (local_wild);
  1318. #ifdef INET6
  1319. if (local_wild_mapped != NULL)
  1320. return (local_wild_mapped);
  1321. #endif /* defined(INET6) */
  1322. } /* if ((lookupflags & INPLOOKUP_WILDCARD) != 0) */
  1323. return (NULL);
  1324. }
  1325. /*
  1326. * Lookup PCB in hash list, using pcbinfo tables. This variation locks the
  1327. * hash list lock, and will return the inpcb locked (i.e., requires
  1328. * INPLOOKUP_LOCKPCB).
  1329. */
  1330. static struct inpcb *
  1331. in_pcblookup_hash(struct inpcbinfo *pcbinfo, struct in_addr faddr,
  1332. u_int fport, struct in_addr laddr, u_int lport, int lookupflags,
  1333. struct ifnet *ifp)
  1334. {
  1335. struct inpcb *inp;
  1336. INP_HASH_RLOCK(pcbinfo);
  1337. inp = in_pcblookup_hash_locked(pcbinfo, faddr, fport, laddr, lport,
  1338. (lookupflags & ~(INPLOOKUP_LOCKPCB)), ifp);
  1339. if (inp != NULL) {
  1340. in_pcbref(inp);
  1341. INP_HASH_RUNLOCK(pcbinfo);
  1342. if (lookupflags & INPLOOKUP_LOCKPCB) {
  1343. INP_LOCK(inp);
  1344. if (in_pcbrele_locked(inp))
  1345. return (NULL);
  1346. } else
  1347. panic("%s: locking bug", __func__);
  1348. } else
  1349. INP_HASH_RUNLOCK(pcbinfo);
  1350. return (inp);
  1351. }
  1352. /*
  1353. * Public inpcb lookup routines, accepting a 4-tuple, and optionally, an mbuf
  1354. * from which a pre-calculated hash value may be extracted.
  1355. */
  1356. struct inpcb *
  1357. in_pcblookup(struct inpcbinfo *pcbinfo, struct in_addr faddr, u_int fport,
  1358. struct in_addr laddr, u_int lport, int lookupflags, struct ifnet *ifp)
  1359. {
  1360. KASSERT((lookupflags & ~INPLOOKUP_MASK) == 0,
  1361. ("%s: invalid lookup flags %d", __func__, lookupflags));
  1362. KASSERT((lookupflags & INPLOOKUP_LOCKPCB) != 0,
  1363. ("%s: LOCKPCB not set", __func__));
  1364. return (in_pcblookup_hash(pcbinfo, faddr, fport, laddr, lport,
  1365. lookupflags, ifp));
  1366. }
  1367. struct inpcb *
  1368. in_pcblookup_mbuf(struct inpcbinfo *pcbinfo, struct in_addr faddr,
  1369. u_int fport, struct in_addr laddr, u_int lport, int lookupflags,
  1370. struct ifnet *ifp, struct mbuf *m)
  1371. {
  1372. KASSERT((lookupflags & ~INPLOOKUP_MASK) == 0,
  1373. ("%s: invalid lookup flags %d", __func__, lookupflags));
  1374. KASSERT((lookupflags & (INPLOOKUP_LOCKPCB)) != 0,
  1375. ("%s: LOCKPCB not set", __func__));
  1376. return (in_pcblookup_hash(pcbinfo, faddr, fport, laddr, lport,
  1377. lookupflags, ifp));
  1378. }
  1379. #endif /* INET */
  1380. /*
  1381. * Insert PCB onto various hash lists.
  1382. */
  1383. static int
  1384. in_pcbinshash_internal(struct inpcb *inp)
  1385. {
  1386. struct inpcbhead *pcbhash;
  1387. struct inpcbporthead *pcbporthash;
  1388. struct inpcbinfo *pcbinfo = inp->inp_pcbinfo;
  1389. struct inpcbport *phd;
  1390. u_int32_t hashkey_faddr;
  1391. INP_LOCK_ASSERT(inp);
  1392. INP_HASH_LOCK_ASSERT(pcbinfo);
  1393. KASSERT((inp->inp_flags & INP_INHASHLIST) == 0,
  1394. ("in_pcbinshash: INP_INHASHLIST"));
  1395. #ifdef INET6
  1396. if (inp->inp_vflag & INP_IPV6)
  1397. hashkey_faddr = inp->in6p_faddr.s6_addr32[3] /* XXX */;
  1398. else
  1399. #endif /* INET6 */
  1400. hashkey_faddr = inp->inp_faddr.s_addr;
  1401. pcbhash = &pcbinfo->ipi_hashbase[INP_PCBHASH(hashkey_faddr,
  1402. inp->inp_lport, inp->inp_fport, pcbinfo->ipi_hashmask)];
  1403. pcbporthash = &pcbinfo->ipi_porthashbase[
  1404. INP_PCBPORTHASH(inp->inp_lport, pcbinfo->ipi_porthashmask)];
  1405. /*
  1406. * Go through port list and look for a head for this lport.
  1407. */
  1408. LIST_FOREACH(phd, pcbporthash, phd_hash) {
  1409. if (phd->phd_port == inp->inp_lport)
  1410. break;
  1411. }
  1412. /*
  1413. * If none exists, malloc one and tack it on.
  1414. */
  1415. if (phd == NULL) {
  1416. phd = (inpcbport *)malloc(sizeof(struct inpcbport));
  1417. if (phd == NULL) {
  1418. return (ENOBUFS); /* XXX */
  1419. }
  1420. phd->phd_port = inp->inp_lport;
  1421. LIST_INIT(&phd->phd_pcblist);
  1422. LIST_INSERT_HEAD(pcbporthash, phd, phd_hash);
  1423. }
  1424. inp->inp_phd = phd;
  1425. LIST_INSERT_HEAD(&phd->phd_pcblist, inp, inp_portlist);
  1426. LIST_INSERT_HEAD(pcbhash, inp, inp_hash);
  1427. inp->inp_flags |= INP_INHASHLIST;
  1428. return (0);
  1429. }
  1430. int
  1431. in_pcbinshash(struct inpcb *inp)
  1432. {
  1433. return (in_pcbinshash_internal(inp));
  1434. }
  1435. /*
  1436. * Move PCB to the proper hash bucket when { faddr, fport } have been
  1437. * changed. NOTE: This does not handle the case of the lport changing (the
  1438. * hashed port list would have to be updated as well), so the lport must
  1439. * not change after in_pcbinshash() has been called.
  1440. */
  1441. void
  1442. in_pcbrehash_mbuf(struct inpcb *inp, struct mbuf *m)
  1443. {
  1444. struct inpcbinfo *pcbinfo = inp->inp_pcbinfo;
  1445. struct inpcbhead *head;
  1446. u_int32_t hashkey_faddr;
  1447. INP_LOCK_ASSERT(inp);
  1448. INP_HASH_WLOCK_ASSERT(pcbinfo);
  1449. KASSERT(inp->inp_flags & INP_INHASHLIST,
  1450. ("in_pcbrehash: !INP_INHASHLIST"));
  1451. #ifdef INET6
  1452. if (inp->inp_vflag & INP_IPV6)
  1453. hashkey_faddr = inp->in6p_faddr.s6_addr32[3] /* XXX */;
  1454. else
  1455. #endif /* INET6 */
  1456. hashkey_faddr = inp->inp_faddr.s_addr;
  1457. head = &pcbinfo->ipi_hashbase[INP_PCBHASH(hashkey_faddr,
  1458. inp->inp_lport, inp->inp_fport, pcbinfo->ipi_hashmask)];
  1459. LIST_REMOVE(inp, inp_hash);
  1460. LIST_INSERT_HEAD(head, inp, inp_hash);
  1461. }
  1462. void
  1463. in_pcbrehash(struct inpcb *inp)
  1464. {
  1465. in_pcbrehash_mbuf(inp, NULL);
  1466. }
  1467. /*
  1468. * Remove PCB from various lists.
  1469. */
  1470. static void
  1471. in_pcbremlists(struct inpcb *inp)
  1472. {
  1473. struct inpcbinfo *pcbinfo = inp->inp_pcbinfo;
  1474. INP_INFO_WLOCK_ASSERT(pcbinfo);
  1475. INP_LOCK_ASSERT(inp);
  1476. inp->inp_gencnt = ++pcbinfo->ipi_gencnt;
  1477. if (inp->inp_flags & INP_INHASHLIST) {
  1478. struct inpcbport *phd = inp->inp_phd;
  1479. INP_HASH_WLOCK(pcbinfo);
  1480. LIST_REMOVE(inp, inp_hash);
  1481. LIST_REMOVE(inp, inp_portlist);
  1482. if (LIST_FIRST(&phd->phd_pcblist) == NULL) {
  1483. LIST_REMOVE(phd, phd_hash);
  1484. free(phd);
  1485. }
  1486. INP_HASH_WUNLOCK(pcbinfo);
  1487. inp->inp_flags &= ~INP_INHASHLIST;
  1488. }
  1489. LIST_REMOVE(inp, inp_list);
  1490. pcbinfo->ipi_count--;
  1491. }
  1492. /*
  1493. * A set label operation has occurred at the socket layer, propagate the
  1494. * label change into the in_pcb for the socket.
  1495. */
  1496. void
  1497. in_pcbsosetlabel(struct socket *so)
  1498. {
  1499. #ifdef MAC
  1500. struct inpcb *inp;
  1501. inp = sotoinpcb(so);
  1502. KASSERT(inp != NULL, ("in_pcbsosetlabel: so->so_pcb == NULL"));
  1503. INP_WLOCK(inp);
  1504. SOCK_LOCK(so);
  1505. mac_inpcb_sosetlabel(so, inp);
  1506. SOCK_UNLOCK(so);
  1507. INP_WUNLOCK(inp);
  1508. #endif
  1509. }
  1510. /*
  1511. * ipport_tick runs once per second, determining if random port allocation
  1512. * should be continued. If more than ipport_randomcps ports have been
  1513. * allocated in the last second, then we return to sequential port
  1514. * allocation. We return to random allocation only once we drop below
  1515. * ipport_randomcps for at least ipport_randomtime seconds.
  1516. */
  1517. static void
  1518. ipport_tick(void *xtp)
  1519. {
  1520. VNET_ITERATOR_DECL(vnet_iter);
  1521. VNET_LIST_RLOCK_NOSLEEP();
  1522. VNET_FOREACH(vnet_iter) {
  1523. CURVNET_SET(vnet_iter); /* XXX appease INVARIANTS here */
  1524. if (V_ipport_tcpallocs <=
  1525. V_ipport_tcplastcount + V_ipport_randomcps) {
  1526. if (V_ipport_stoprandom > 0)
  1527. V_ipport_stoprandom--;
  1528. } else
  1529. V_ipport_stoprandom = V_ipport_randomtime;
  1530. V_ipport_tcplastcount = V_ipport_tcpallocs;
  1531. CURVNET_RESTORE();
  1532. }
  1533. VNET_LIST_RUNLOCK_NOSLEEP();
  1534. callout_reset(&ipport_tick_callout, hz, ipport_tick, NULL);
  1535. }
  1536. #if 0
  1537. static void
  1538. ip_fini(void *xtp)
  1539. {
  1540. callout_stop(&ipport_tick_callout);
  1541. }
  1542. #endif
  1543. /*
  1544. * The ipport_callout should start running at about the time we attach the
  1545. * inet or inet6 domains.
  1546. */
  1547. void ipport_tick_init(const void *unused)
  1548. {
  1549. /* Start ipport_tick. */
  1550. callout_init(&ipport_tick_callout, CALLOUT_MPSAFE);
  1551. callout_reset(&ipport_tick_callout, 1, ipport_tick, NULL);
  1552. /* FIXME: OSv: shutdown handler... */
  1553. // EVENTHANDLER_REGISTER(shutdown_pre_sync, ip_fini, NULL,
  1554. // SHUTDOWN_PRI_DEFAULT);
  1555. }
  1556. SYSINIT(ipport_tick_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_MIDDLE,
  1557. ipport_tick_init, NULL);
  1558. #if 0
  1559. void
  1560. inp_wlock(struct inpcb *inp)
  1561. {
  1562. INP_WLOCK(inp);
  1563. }
  1564. void
  1565. inp_wunlock(struct inpcb *inp)
  1566. {
  1567. INP_WUNLOCK(inp);
  1568. }
  1569. void
  1570. inp_rlock(struct inpcb *inp)
  1571. {
  1572. INP_RLOCK(inp);
  1573. }
  1574. void
  1575. inp_runlock(struct inpcb *inp)
  1576. {
  1577. INP_RUNLOCK(inp);
  1578. }
  1579. #ifdef INVARIANTS
  1580. void
  1581. inp_lock_assert(struct inpcb *inp)
  1582. {
  1583. INP_WLOCK_ASSERT(inp);
  1584. }
  1585. void
  1586. inp_unlock_assert(struct inpcb *inp)
  1587. {
  1588. INP_UNLOCK_ASSERT(inp);
  1589. }
  1590. #endif
  1591. void
  1592. inp_apply_all(void (*func)(struct inpcb *, void *), void *arg)
  1593. {
  1594. struct inpcb *inp;
  1595. INP_INFO_RLOCK(&V_tcbinfo);
  1596. LIST_FOREACH(inp, V_tcbinfo.ipi_listhead, inp_list) {
  1597. INP_WLOCK(inp);
  1598. func(inp, arg);
  1599. INP_WUNLOCK(inp);
  1600. }
  1601. INP_INFO_RUNLOCK(&V_tcbinfo);
  1602. }
  1603. struct socket *
  1604. inp_inpcbtosocket(struct inpcb *inp)
  1605. {
  1606. INP_WLOCK_ASSERT(inp);
  1607. return (inp->inp_socket);
  1608. }
  1609. struct tcpcb *
  1610. inp_inpcbtotcpcb(struct inpcb *inp)
  1611. {
  1612. INP_WLOCK_ASSERT(inp);
  1613. return ((struct tcpcb *)inp->inp_ppcb);
  1614. }
  1615. int
  1616. inp_ip_tos_get(const struct inpcb *inp)
  1617. {
  1618. return (inp->inp_ip_tos);
  1619. }
  1620. void
  1621. inp_ip_tos_set(struct inpcb *inp, int val)
  1622. {
  1623. inp->inp_ip_tos = val;
  1624. }
  1625. void
  1626. inp_4tuple_get(struct inpcb *inp, uint32_t *laddr, uint16_t *lp,
  1627. uint32_t *faddr, uint16_t *fp)
  1628. {
  1629. INP_LOCK_ASSERT(inp);
  1630. *laddr = inp->inp_laddr.s_addr;
  1631. *faddr = inp->inp_faddr.s_addr;
  1632. *lp = inp->inp_lport;
  1633. *fp = inp->inp_fport;
  1634. }
  1635. struct inpcb *
  1636. so_sotoinpcb(struct socket *so)
  1637. {
  1638. return (sotoinpcb(so));
  1639. }
  1640. struct tcpcb *
  1641. so_sototcpcb(struct socket *so)
  1642. {
  1643. return (sototcpcb(so));
  1644. }
  1645. #endif
  1646. #ifdef DDB
  1647. static void
  1648. db_print_indent(int indent)
  1649. {
  1650. int i;
  1651. for (i = 0; i < indent; i++)
  1652. db_printf(" ");
  1653. }
  1654. static void
  1655. db_print_inconninfo(struct in_conninfo *inc, const char *name, int indent)
  1656. {
  1657. char faddr_str[48], laddr_str[48];
  1658. db_print_indent(indent);
  1659. db_printf("%s at %p\n", name, inc);
  1660. indent

Large files files are truncated, but you can click here to view the full file