PageRenderTime 26ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 0ms

/bsd/sys/netinet/tcp_usrreq.cc

https://gitlab.com/jforge/osv
C++ | 2031 lines | 1536 code | 187 blank | 308 comment | 265 complexity | 7c85f6781ba6c7b44adfeae6301cd8cd 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, 1988, 1993
  3. * The Regents of the University of California.
  4. * Copyright (c) 2006-2007 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. * From: @(#)tcp_usrreq.c 8.2 (Berkeley) 1/3/94
  36. */
  37. #include <sys/cdefs.h>
  38. #include <osv/initialize.hh>
  39. #include <bsd/porting/netport.h>
  40. #include <bsd/porting/sync_stub.h>
  41. #include <bsd/sys/sys/libkern.h>
  42. #include <bsd/sys/sys/param.h>
  43. #include <bsd/sys/sys/limits.h>
  44. #include <bsd/sys/sys/mbuf.h>
  45. #ifdef INET6
  46. #include <bsd/sys/sys/domain.h>
  47. #endif /* INET6 */
  48. #include <bsd/sys/sys/socket.h>
  49. #include <bsd/sys/sys/socketvar.h>
  50. #include <bsd/sys/sys/protosw.h>
  51. #ifdef DDB
  52. #include <ddb/ddb.h>
  53. #endif
  54. #include <bsd/sys/net/if.h>
  55. #include <bsd/sys/net/route.h>
  56. #include <bsd/sys/net/vnet.h>
  57. #include <bsd/sys/netinet/cc.h>
  58. #include <bsd/sys/netinet/in.h>
  59. #include <bsd/sys/netinet/in_pcb.h>
  60. #include <bsd/sys/netinet/in_systm.h>
  61. #include <bsd/sys/netinet/in_var.h>
  62. #include <bsd/sys/netinet/ip_var.h>
  63. #ifdef INET6
  64. #include <bsd/sys/netinet/ip6.h>
  65. #include <bsd/sys/netinet6/in6_pcb.h>
  66. #include <bsd/sys/netinet6/ip6_var.h>
  67. #include <bsd/sys/netinet6/scope6_var.h>
  68. #endif
  69. #include <bsd/sys/netinet/tcp_fsm.h>
  70. #include <bsd/sys/netinet/tcp_seq.h>
  71. #include <bsd/sys/netinet/tcp_timer.h>
  72. #include <bsd/sys/netinet/tcp_var.h>
  73. #include <bsd/sys/netinet/tcpip.h>
  74. #ifdef TCPDEBUG
  75. #include <bsd/sys/netinet/tcp_debug.h>
  76. #endif
  77. #include <osv/poll.h>
  78. /*
  79. * TCP protocol interface to socket abstraction.
  80. */
  81. static int tcp_attach(struct socket *);
  82. #ifdef INET
  83. static int tcp_connect(struct tcpcb *, struct bsd_sockaddr *,
  84. struct thread *td);
  85. #endif /* INET */
  86. #ifdef INET6
  87. static int tcp6_connect(struct tcpcb *, struct bsd_sockaddr *,
  88. struct thread *td);
  89. #endif /* INET6 */
  90. static void tcp_disconnect(struct tcpcb *);
  91. static void tcp_usrclosed(struct tcpcb *);
  92. static void tcp_fill_info(struct tcpcb *, struct tcp_info *);
  93. #ifdef TCPDEBUG
  94. #define TCPDEBUG0 int ostate = 0
  95. #define TCPDEBUG1() ostate = tp ? tp->get_state() : 0
  96. #define TCPDEBUG2(req) if (tp && (so->so_options & SO_DEBUG)) \
  97. tcp_trace(TA_USER, ostate, tp, 0, 0, req)
  98. #else
  99. #define TCPDEBUG0
  100. #define TCPDEBUG1()
  101. #define TCPDEBUG2(req)
  102. #endif
  103. /*
  104. * TCP attaches to socket via pru_attach(), reserving space,
  105. * and an internet control block.
  106. */
  107. static int
  108. tcp_usr_attach(struct socket *so, int proto, struct thread *td)
  109. {
  110. struct inpcb *inp;
  111. struct tcpcb *tp = NULL;
  112. int error;
  113. TCPDEBUG0;
  114. inp = sotoinpcb(so);
  115. KASSERT(inp == NULL, ("tcp_usr_attach: inp != NULL"));
  116. TCPDEBUG1();
  117. error = tcp_attach(so);
  118. if (error)
  119. goto out;
  120. if ((so->so_options & SO_LINGER) && so->so_linger == 0)
  121. so->so_linger = TCP_LINGERTIME;
  122. inp = sotoinpcb(so);
  123. tp = intotcpcb(inp);
  124. if (tp->nc) {
  125. so->so_nc = tp->nc;
  126. for (auto&& pl : so->fp->f_poll_list) {
  127. so->so_nc->add_poller(*pl._req);
  128. }
  129. if (so->fp->f_epolls) {
  130. for (auto&& ep : *so->fp->f_epolls) {
  131. so->so_nc->add_epoll(ep);
  132. }
  133. }
  134. }
  135. out:
  136. TCPDEBUG2(PRU_ATTACH);
  137. return error;
  138. }
  139. /*
  140. * tcp_detach is called when the socket layer loses its final reference
  141. * to the socket, be it a file descriptor reference, a reference from TCP,
  142. * etc. At this point, there is only one case in which we will keep around
  143. * inpcb state: time wait.
  144. *
  145. * This function can probably be re-absorbed back into tcp_usr_detach() now
  146. * that there is a single detach path.
  147. */
  148. static void
  149. tcp_detach(struct socket *so, struct inpcb *inp)
  150. {
  151. struct tcpcb *tp;
  152. INP_INFO_WLOCK_ASSERT(&V_tcbinfo);
  153. INP_LOCK_ASSERT(inp);
  154. KASSERT(so->so_pcb == inp, ("tcp_detach: so_pcb != inp"));
  155. KASSERT(inp->inp_socket == so, ("tcp_detach: inp_socket != so"));
  156. tp = intotcpcb(inp);
  157. if (inp->inp_flags & INP_TIMEWAIT) {
  158. /*
  159. * There are two cases to handle: one in which the time wait
  160. * state is being discarded (INP_DROPPED), and one in which
  161. * this connection will remain in timewait. In the former,
  162. * it is time to discard all state (except tcptw, which has
  163. * already been discarded by the timewait close code, which
  164. * should be further up the call stack somewhere). In the
  165. * latter case, we detach from the socket, but leave the pcb
  166. * present until timewait ends.
  167. *
  168. * XXXRW: Would it be cleaner to free the tcptw here?
  169. */
  170. if (inp->inp_flags & INP_DROPPED) {
  171. KASSERT(tp == NULL, ("tcp_detach: INP_TIMEWAIT && "
  172. "INP_DROPPED && tp != NULL"));
  173. in_pcbdetach(inp);
  174. in_pcbfree(inp);
  175. } else {
  176. in_pcbdetach(inp);
  177. INP_UNLOCK(inp);
  178. }
  179. } else {
  180. /*
  181. * If the connection is not in timewait, we consider two
  182. * two conditions: one in which no further processing is
  183. * necessary (dropped || embryonic), and one in which TCP is
  184. * not yet done, but no longer requires the socket, so the
  185. * pcb will persist for the time being.
  186. *
  187. * XXXRW: Does the second case still occur?
  188. */
  189. if (inp->inp_flags & INP_DROPPED ||
  190. tp->get_state() < TCPS_SYN_SENT) {
  191. tcp_discardcb(tp);
  192. in_pcbdetach(inp);
  193. in_pcbfree(inp);
  194. } else {
  195. in_pcbdetach(inp);
  196. INP_UNLOCK(inp);
  197. }
  198. }
  199. }
  200. /*
  201. * pru_detach() detaches the TCP protocol from the socket.
  202. * If the protocol state is non-embryonic, then can't
  203. * do this directly: have to initiate a pru_disconnect(),
  204. * which may finish later; embryonic TCB's can just
  205. * be discarded here.
  206. */
  207. static void
  208. tcp_usr_detach(struct socket *so)
  209. {
  210. struct inpcb *inp;
  211. inp = sotoinpcb(so);
  212. KASSERT(inp != NULL, ("tcp_usr_detach: inp == NULL"));
  213. INP_INFO_WLOCK(&V_tcbinfo);
  214. INP_LOCK(inp);
  215. KASSERT(inp->inp_socket != NULL,
  216. ("tcp_usr_detach: inp_socket == NULL"));
  217. tcp_detach(so, inp);
  218. INP_INFO_WUNLOCK(&V_tcbinfo);
  219. }
  220. #ifdef INET
  221. /*
  222. * Give the socket an address.
  223. */
  224. static int
  225. tcp_usr_bind(struct socket *so, struct bsd_sockaddr *nam, struct thread *td)
  226. {
  227. int error = 0;
  228. struct inpcb *inp;
  229. struct tcpcb *tp = NULL;
  230. struct bsd_sockaddr_in *sinp;
  231. sinp = (struct bsd_sockaddr_in *)nam;
  232. if (nam->sa_len != sizeof (*sinp))
  233. return (EINVAL);
  234. /*
  235. * Must check for multicast addresses and disallow binding
  236. * to them.
  237. */
  238. if (sinp->sin_family == AF_INET &&
  239. IN_MULTICAST(ntohl(sinp->sin_addr.s_addr)))
  240. return (EAFNOSUPPORT);
  241. TCPDEBUG0;
  242. inp = sotoinpcb(so);
  243. KASSERT(inp != NULL, ("tcp_usr_bind: inp == NULL"));
  244. INP_LOCK(inp);
  245. if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) {
  246. error = EINVAL;
  247. goto out;
  248. }
  249. tp = intotcpcb(inp);
  250. TCPDEBUG1();
  251. INP_HASH_WLOCK(&V_tcbinfo);
  252. error = in_pcbbind(inp, nam, 0);
  253. INP_HASH_WUNLOCK(&V_tcbinfo);
  254. out:
  255. TCPDEBUG2(PRU_BIND);
  256. INP_UNLOCK(inp);
  257. return (error);
  258. }
  259. #endif /* INET */
  260. #ifdef INET6
  261. static int
  262. tcp6_usr_bind(struct socket *so, struct bsd_sockaddr *nam, struct thread *td)
  263. {
  264. int error = 0;
  265. struct inpcb *inp;
  266. struct tcpcb *tp = NULL;
  267. struct bsd_sockaddr_in6 *sin6p;
  268. sin6p = (struct bsd_sockaddr_in6 *)nam;
  269. if (nam->sa_len != sizeof (*sin6p))
  270. return (EINVAL);
  271. /*
  272. * Must check for multicast addresses and disallow binding
  273. * to them.
  274. */
  275. if (sin6p->sin6_family == AF_INET6 &&
  276. IN6_IS_ADDR_MULTICAST(&sin6p->sin6_addr))
  277. return (EAFNOSUPPORT);
  278. TCPDEBUG0;
  279. inp = sotoinpcb(so);
  280. KASSERT(inp != NULL, ("tcp6_usr_bind: inp == NULL"));
  281. INP_LOCK(inp);
  282. if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) {
  283. error = EINVAL;
  284. goto out;
  285. }
  286. tp = intotcpcb(inp);
  287. TCPDEBUG1();
  288. INP_HASH_WLOCK(&V_tcbinfo);
  289. inp->inp_vflag &= ~INP_IPV4;
  290. inp->inp_vflag |= INP_IPV6;
  291. #ifdef INET
  292. if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0) {
  293. if (IN6_IS_ADDR_UNSPECIFIED(&sin6p->sin6_addr))
  294. inp->inp_vflag |= INP_IPV4;
  295. else if (IN6_IS_ADDR_V4MAPPED(&sin6p->sin6_addr)) {
  296. struct bsd_sockaddr_in sin;
  297. in6_sin6_2_sin(&sin, sin6p);
  298. inp->inp_vflag |= INP_IPV4;
  299. inp->inp_vflag &= ~INP_IPV6;
  300. error = in_pcbbind(inp, (struct bsd_sockaddr *)&sin,
  301. td->td_ucred);
  302. INP_HASH_WUNLOCK(&V_tcbinfo);
  303. goto out;
  304. }
  305. }
  306. #endif
  307. error = in6_pcbbind(inp, nam, td->td_ucred);
  308. INP_HASH_WUNLOCK(&V_tcbinfo);
  309. out:
  310. TCPDEBUG2(PRU_BIND);
  311. INP_UNLOCK(inp);
  312. return (error);
  313. }
  314. #endif /* INET6 */
  315. #ifdef INET
  316. /*
  317. * Prepare to accept connections.
  318. */
  319. static int
  320. tcp_usr_listen(struct socket *so, int backlog, struct thread *td)
  321. {
  322. int error = 0;
  323. struct inpcb *inp;
  324. struct tcpcb *tp = NULL;
  325. TCPDEBUG0;
  326. inp = sotoinpcb(so);
  327. KASSERT(inp != NULL, ("tcp_usr_listen: inp == NULL"));
  328. INP_LOCK(inp);
  329. if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) {
  330. error = EINVAL;
  331. goto out;
  332. }
  333. tp = intotcpcb(inp);
  334. TCPDEBUG1();
  335. SOCK_LOCK(so);
  336. error = solisten_proto_check(so);
  337. INP_HASH_WLOCK(&V_tcbinfo);
  338. if (error == 0 && inp->inp_lport == 0)
  339. error = in_pcbbind(inp, (struct bsd_sockaddr *)0, 0);
  340. INP_HASH_WUNLOCK(&V_tcbinfo);
  341. if (error == 0) {
  342. tp->set_state(TCPS_LISTEN);
  343. solisten_proto(so, backlog);
  344. }
  345. SOCK_UNLOCK(so);
  346. out:
  347. TCPDEBUG2(PRU_LISTEN);
  348. INP_UNLOCK(inp);
  349. return (error);
  350. }
  351. #endif /* INET */
  352. #ifdef INET6
  353. static int
  354. tcp6_usr_listen(struct socket *so, int backlog, struct thread *td)
  355. {
  356. int error = 0;
  357. struct inpcb *inp;
  358. struct tcpcb *tp = NULL;
  359. TCPDEBUG0;
  360. inp = sotoinpcb(so);
  361. KASSERT(inp != NULL, ("tcp6_usr_listen: inp == NULL"));
  362. INP_LOCK(inp);
  363. if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) {
  364. error = EINVAL;
  365. goto out;
  366. }
  367. tp = intotcpcb(inp);
  368. TCPDEBUG1();
  369. SOCK_LOCK(so);
  370. error = solisten_proto_check(so);
  371. INP_HASH_WLOCK(&V_tcbinfo);
  372. if (error == 0 && inp->inp_lport == 0) {
  373. inp->inp_vflag &= ~INP_IPV4;
  374. if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0)
  375. inp->inp_vflag |= INP_IPV4;
  376. error = in6_pcbbind(inp, (struct bsd_sockaddr *)0, td->td_ucred);
  377. }
  378. INP_HASH_WUNLOCK(&V_tcbinfo);
  379. if (error == 0) {
  380. tp->set_state(TCPS_LISTEN);
  381. solisten_proto(so, backlog);
  382. }
  383. SOCK_UNLOCK(so);
  384. out:
  385. TCPDEBUG2(PRU_LISTEN);
  386. INP_UNLOCK(inp);
  387. return (error);
  388. }
  389. #endif /* INET6 */
  390. #ifdef INET
  391. /*
  392. * Initiate connection to peer.
  393. * Create a template for use in transmissions on this connection.
  394. * Enter SYN_SENT state, and mark socket as connecting.
  395. * Start keep-alive timer, and seed output sequence space.
  396. * Send initial segment on connection.
  397. */
  398. static int
  399. tcp_usr_connect(struct socket *so, struct bsd_sockaddr *nam, struct thread *td)
  400. {
  401. int error = 0;
  402. struct inpcb *inp;
  403. struct tcpcb *tp = NULL;
  404. struct bsd_sockaddr_in *sinp;
  405. sinp = (struct bsd_sockaddr_in *)nam;
  406. if (nam->sa_len != sizeof (*sinp))
  407. return (EINVAL);
  408. /*
  409. * Must disallow TCP ``connections'' to multicast addresses.
  410. */
  411. if (sinp->sin_family == AF_INET
  412. && IN_MULTICAST(ntohl(sinp->sin_addr.s_addr)))
  413. return (EAFNOSUPPORT);
  414. TCPDEBUG0;
  415. inp = sotoinpcb(so);
  416. KASSERT(inp != NULL, ("tcp_usr_connect: inp == NULL"));
  417. INP_LOCK(inp);
  418. if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) {
  419. error = EINVAL;
  420. goto out;
  421. }
  422. tp = intotcpcb(inp);
  423. TCPDEBUG1();
  424. if ((error = tcp_connect(tp, nam, td)) != 0)
  425. goto out;
  426. error = tcp_output(tp);
  427. out:
  428. TCPDEBUG2(PRU_CONNECT);
  429. INP_UNLOCK(inp);
  430. return (error);
  431. }
  432. #endif /* INET */
  433. #ifdef INET6
  434. static int
  435. tcp6_usr_connect(struct socket *so, struct bsd_sockaddr *nam, struct thread *td)
  436. {
  437. int error = 0;
  438. struct inpcb *inp;
  439. struct tcpcb *tp = NULL;
  440. struct bsd_sockaddr_in6 *sin6p;
  441. TCPDEBUG0;
  442. sin6p = (struct bsd_sockaddr_in6 *)nam;
  443. if (nam->sa_len != sizeof (*sin6p))
  444. return (EINVAL);
  445. /*
  446. * Must disallow TCP ``connections'' to multicast addresses.
  447. */
  448. if (sin6p->sin6_family == AF_INET6
  449. && IN6_IS_ADDR_MULTICAST(&sin6p->sin6_addr))
  450. return (EAFNOSUPPORT);
  451. inp = sotoinpcb(so);
  452. KASSERT(inp != NULL, ("tcp6_usr_connect: inp == NULL"));
  453. INP_LOCK(inp);
  454. if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) {
  455. error = EINVAL;
  456. goto out;
  457. }
  458. tp = intotcpcb(inp);
  459. TCPDEBUG1();
  460. #ifdef INET
  461. /*
  462. * XXXRW: Some confusion: V4/V6 flags relate to binding, and
  463. * therefore probably require the hash lock, which isn't held here.
  464. * Is this a significant problem?
  465. */
  466. if (IN6_IS_ADDR_V4MAPPED(&sin6p->sin6_addr)) {
  467. struct bsd_sockaddr_in sin;
  468. if ((inp->inp_flags & IN6P_IPV6_V6ONLY) != 0) {
  469. error = EINVAL;
  470. goto out;
  471. }
  472. in6_sin6_2_sin(&sin, sin6p);
  473. inp->inp_vflag |= INP_IPV4;
  474. inp->inp_vflag &= ~INP_IPV6;
  475. if ((error = prison_remote_ip4(td->td_ucred,
  476. &sin.sin_addr)) != 0)
  477. goto out;
  478. if ((error = tcp_connect(tp, (struct bsd_sockaddr *)&sin, td)) != 0)
  479. goto out;
  480. error = tcp_output_connect(so, nam);
  481. goto out;
  482. }
  483. #endif
  484. inp->inp_vflag &= ~INP_IPV4;
  485. inp->inp_vflag |= INP_IPV6;
  486. inp->inp_inc.inc_flags |= INC_ISIPV6;
  487. if ((error = prison_remote_ip6(td->td_ucred, &sin6p->sin6_addr)) != 0)
  488. goto out;
  489. if ((error = tcp6_connect(tp, nam, td)) != 0)
  490. goto out;
  491. error = tcp_output_connect(so, nam);
  492. out:
  493. TCPDEBUG2(PRU_CONNECT);
  494. INP_UNLOCK(inp);
  495. return (error);
  496. }
  497. #endif /* INET6 */
  498. /*
  499. * Initiate disconnect from peer.
  500. * If connection never passed embryonic stage, just drop;
  501. * else if don't need to let data drain, then can just drop anyways,
  502. * else have to begin TCP shutdown process: mark socket disconnecting,
  503. * drain unread data, state switch to reflect user close, and
  504. * send segment (e.g. FIN) to peer. Socket will be really disconnected
  505. * when peer sends FIN and acks ours.
  506. *
  507. * SHOULD IMPLEMENT LATER PRU_CONNECT VIA REALLOC TCPCB.
  508. */
  509. static int
  510. tcp_usr_disconnect(struct socket *so)
  511. {
  512. struct inpcb *inp;
  513. struct tcpcb *tp = NULL;
  514. int error = 0;
  515. TCPDEBUG0;
  516. INP_INFO_WLOCK(&V_tcbinfo);
  517. inp = sotoinpcb(so);
  518. KASSERT(inp != NULL, ("tcp_usr_disconnect: inp == NULL"));
  519. INP_LOCK(inp);
  520. if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) {
  521. error = ECONNRESET;
  522. goto out;
  523. }
  524. tp = intotcpcb(inp);
  525. TCPDEBUG1();
  526. tcp_disconnect(tp);
  527. out:
  528. TCPDEBUG2(PRU_DISCONNECT);
  529. INP_UNLOCK(inp);
  530. INP_INFO_WUNLOCK(&V_tcbinfo);
  531. return (error);
  532. }
  533. #ifdef INET
  534. /*
  535. * Accept a connection. Essentially all the work is done at higher levels;
  536. * just return the address of the peer, storing through addr.
  537. */
  538. static int
  539. tcp_usr_accept(struct socket *so, struct bsd_sockaddr **nam)
  540. {
  541. int error = 0;
  542. struct inpcb *inp = NULL;
  543. struct tcpcb *tp = NULL;
  544. struct in_addr addr;
  545. in_port_t port = 0;
  546. TCPDEBUG0;
  547. if (so->so_state & SS_ISDISCONNECTED)
  548. return (ECONNABORTED);
  549. inp = sotoinpcb(so);
  550. KASSERT(inp != NULL, ("tcp_usr_accept: inp == NULL"));
  551. INP_LOCK(inp);
  552. if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) {
  553. error = ECONNABORTED;
  554. goto out;
  555. }
  556. tp = intotcpcb(inp);
  557. TCPDEBUG1();
  558. /*
  559. * We inline in_getpeeraddr and COMMON_END here, so that we can
  560. * copy the data of interest and defer the malloc until after we
  561. * release the lock.
  562. */
  563. port = inp->inp_fport;
  564. addr = inp->inp_faddr;
  565. out:
  566. TCPDEBUG2(PRU_ACCEPT);
  567. INP_UNLOCK(inp);
  568. if (error == 0)
  569. *nam = in_sockaddr(port, &addr);
  570. return error;
  571. }
  572. #endif /* INET */
  573. #ifdef INET6
  574. static int
  575. tcp6_usr_accept(struct socket *so, struct bsd_sockaddr **nam)
  576. {
  577. struct inpcb *inp = NULL;
  578. int error = 0;
  579. struct tcpcb *tp = NULL;
  580. struct in_addr addr;
  581. struct in6_addr addr6;
  582. in_port_t port = 0;
  583. int v4 = 0;
  584. TCPDEBUG0;
  585. if (so->so_state & SS_ISDISCONNECTED)
  586. return (ECONNABORTED);
  587. inp = sotoinpcb(so);
  588. KASSERT(inp != NULL, ("tcp6_usr_accept: inp == NULL"));
  589. INP_INFO_RLOCK(&V_tcbinfo);
  590. INP_LOCK(inp);
  591. if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) {
  592. error = ECONNABORTED;
  593. goto out;
  594. }
  595. tp = intotcpcb(inp);
  596. TCPDEBUG1();
  597. /*
  598. * We inline in6_mapped_peeraddr and COMMON_END here, so that we can
  599. * copy the data of interest and defer the malloc until after we
  600. * release the lock.
  601. */
  602. if (inp->inp_vflag & INP_IPV4) {
  603. v4 = 1;
  604. port = inp->inp_fport;
  605. addr = inp->inp_faddr;
  606. } else {
  607. port = inp->inp_fport;
  608. addr6 = inp->in6p_faddr;
  609. }
  610. out:
  611. TCPDEBUG2(PRU_ACCEPT);
  612. INP_UNLOCK(inp);
  613. INP_INFO_RUNLOCK(&V_tcbinfo);
  614. if (error == 0) {
  615. if (v4)
  616. *nam = in6_v4mapsin6_sockaddr(port, &addr);
  617. else
  618. *nam = in6_sockaddr(port, &addr6);
  619. }
  620. return error;
  621. }
  622. #endif /* INET6 */
  623. /*
  624. * Mark the connection as being incapable of further output.
  625. */
  626. static int
  627. tcp_usr_shutdown(struct socket *so)
  628. {
  629. int error = 0;
  630. struct inpcb *inp;
  631. struct tcpcb *tp = NULL;
  632. TCPDEBUG0;
  633. INP_INFO_WLOCK(&V_tcbinfo);
  634. inp = sotoinpcb(so);
  635. KASSERT(inp != NULL, ("inp == NULL"));
  636. INP_LOCK(inp);
  637. if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) {
  638. error = ECONNRESET;
  639. goto out;
  640. }
  641. tp = intotcpcb(inp);
  642. TCPDEBUG1();
  643. socantsendmore_locked(so);
  644. tcp_usrclosed(tp);
  645. if (!(inp->inp_flags & INP_DROPPED))
  646. error = tcp_output(tp);
  647. out:
  648. TCPDEBUG2(PRU_SHUTDOWN);
  649. INP_UNLOCK(inp);
  650. INP_INFO_WUNLOCK(&V_tcbinfo);
  651. return (error);
  652. }
  653. /*
  654. * After a receive, possibly send window update to peer.
  655. */
  656. static int
  657. tcp_usr_rcvd(struct socket *so, int flags)
  658. {
  659. struct inpcb *inp;
  660. struct tcpcb *tp = NULL;
  661. int error = 0;
  662. TCPDEBUG0;
  663. inp = sotoinpcb(so);
  664. KASSERT(inp != NULL, ("tcp_usr_rcvd: inp == NULL"));
  665. INP_LOCK(inp);
  666. if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) {
  667. error = ECONNRESET;
  668. goto out;
  669. }
  670. tp = intotcpcb(inp);
  671. TCPDEBUG1();
  672. tcp_output(tp);
  673. out:
  674. TCPDEBUG2(PRU_RCVD);
  675. INP_UNLOCK(inp);
  676. return (error);
  677. }
  678. /*
  679. * Do a send by putting data in output queue and updating urgent
  680. * marker if URG set. Possibly send more data. Unlike the other
  681. * pru_*() routines, the mbuf chains are our responsibility. We
  682. * must either enqueue them or free them. The other pru_* routines
  683. * generally are caller-frees.
  684. */
  685. static int
  686. tcp_usr_send(struct socket *so, int flags, struct mbuf *m,
  687. struct bsd_sockaddr *nam, struct mbuf *control, struct thread *td)
  688. {
  689. int error = 0;
  690. struct inpcb *inp;
  691. struct tcpcb *tp = NULL;
  692. #ifdef INET6
  693. int isipv6;
  694. #endif
  695. TCPDEBUG0;
  696. /*
  697. * We require the pcbinfo lock if we will close the socket as part of
  698. * this call.
  699. */
  700. if (flags & PRUS_EOF)
  701. INP_INFO_WLOCK(&V_tcbinfo);
  702. inp = sotoinpcb(so);
  703. KASSERT(inp != NULL, ("tcp_usr_send: inp == NULL"));
  704. INP_LOCK(inp);
  705. if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) {
  706. if (control)
  707. m_freem(control);
  708. if (m)
  709. m_freem(m);
  710. error = ECONNRESET;
  711. goto out;
  712. }
  713. #ifdef INET6
  714. isipv6 = nam && nam->sa_family == AF_INET6;
  715. #endif /* INET6 */
  716. tp = intotcpcb(inp);
  717. TCPDEBUG1();
  718. if (control) {
  719. /* TCP doesn't do control messages (rights, creds, etc) */
  720. if (control->m_hdr.mh_len) {
  721. m_freem(control);
  722. if (m)
  723. m_freem(m);
  724. error = EINVAL;
  725. goto out;
  726. }
  727. m_freem(control); /* empty control, just free it */
  728. }
  729. if (!(flags & PRUS_OOB)) {
  730. sbappendstream(so, &so->so_snd, m);
  731. if (nam && tp->get_state() < TCPS_SYN_SENT) {
  732. /*
  733. * Do implied connect if not yet connected,
  734. * initialize window to default value, and
  735. * initialize maxseg/maxopd using peer's cached
  736. * MSS.
  737. */
  738. #ifdef INET6
  739. if (isipv6)
  740. error = tcp6_connect(tp, nam, td);
  741. #endif /* INET6 */
  742. #if defined(INET6) && defined(INET)
  743. else
  744. #endif
  745. #ifdef INET
  746. error = tcp_connect(tp, nam, td);
  747. #endif
  748. if (error)
  749. goto out;
  750. tp->snd_wnd = TTCP_CLIENT_SND_WND;
  751. tcp_mss(tp, -1);
  752. }
  753. if (flags & PRUS_EOF) {
  754. /*
  755. * Close the send side of the connection after
  756. * the data is sent.
  757. */
  758. INP_INFO_WLOCK_ASSERT(&V_tcbinfo);
  759. socantsendmore_locked(so);
  760. tcp_usrclosed(tp);
  761. }
  762. if (!(inp->inp_flags & INP_DROPPED)) {
  763. if (flags & PRUS_MORETOCOME)
  764. tp->t_flags |= TF_MORETOCOME;
  765. error = tcp_output(tp);
  766. if (flags & PRUS_MORETOCOME)
  767. tp->t_flags &= ~TF_MORETOCOME;
  768. }
  769. } else {
  770. /*
  771. * XXXRW: PRUS_EOF not implemented with PRUS_OOB?
  772. */
  773. if (sbspace(&so->so_snd) < -512) {
  774. SOCK_UNLOCK(so);
  775. m_freem(m);
  776. error = ENOBUFS;
  777. goto out;
  778. }
  779. /*
  780. * According to RFC961 (Assigned Protocols),
  781. * the urgent pointer points to the last octet
  782. * of urgent data. We continue, however,
  783. * to consider it to indicate the first octet
  784. * of data past the urgent section.
  785. * Otherwise, snd_up should be one lower.
  786. */
  787. sbappendstream_locked(so, &so->so_snd, m);
  788. if (nam && tp->get_state() < TCPS_SYN_SENT) {
  789. /*
  790. * Do implied connect if not yet connected,
  791. * initialize window to default value, and
  792. * initialize maxseg/maxopd using peer's cached
  793. * MSS.
  794. */
  795. #ifdef INET6
  796. if (isipv6)
  797. error = tcp6_connect(tp, nam, td);
  798. #endif /* INET6 */
  799. #if defined(INET6) && defined(INET)
  800. else
  801. #endif
  802. #ifdef INET
  803. error = tcp_connect(tp, nam, td);
  804. #endif
  805. if (error)
  806. goto out;
  807. tp->snd_wnd = TTCP_CLIENT_SND_WND;
  808. tcp_mss(tp, -1);
  809. }
  810. tp->snd_up = tp->snd_una + so->so_snd.sb_cc;
  811. tp->t_flags |= TF_FORCEDATA;
  812. error = tcp_output(tp);
  813. tp->t_flags &= ~TF_FORCEDATA;
  814. }
  815. out:
  816. TCPDEBUG2((flags & PRUS_OOB) ? PRU_SENDOOB :
  817. ((flags & PRUS_EOF) ? PRU_SEND_EOF : PRU_SEND));
  818. INP_UNLOCK(inp);
  819. if (flags & PRUS_EOF)
  820. INP_INFO_WUNLOCK(&V_tcbinfo);
  821. return (error);
  822. }
  823. /*
  824. * Abort the TCP. Drop the connection abruptly.
  825. */
  826. static void
  827. tcp_usr_abort(struct socket *so)
  828. {
  829. struct inpcb *inp;
  830. struct tcpcb *tp = NULL;
  831. TCPDEBUG0;
  832. inp = sotoinpcb(so);
  833. KASSERT(inp != NULL, ("tcp_usr_abort: inp == NULL"));
  834. INP_INFO_WLOCK(&V_tcbinfo);
  835. INP_LOCK(inp);
  836. KASSERT(inp->inp_socket != NULL,
  837. ("tcp_usr_abort: inp_socket == NULL"));
  838. /*
  839. * If we still have full TCP state, and we're not dropped, drop.
  840. */
  841. if (!(inp->inp_flags & INP_TIMEWAIT) &&
  842. !(inp->inp_flags & INP_DROPPED)) {
  843. tp = intotcpcb(inp);
  844. TCPDEBUG1();
  845. tcp_drop(tp, ECONNABORTED);
  846. TCPDEBUG2(PRU_ABORT);
  847. }
  848. if (!(inp->inp_flags & INP_DROPPED)) {
  849. so->so_state |= SS_PROTOREF;
  850. inp->inp_flags |= INP_SOCKREF;
  851. }
  852. INP_UNLOCK(inp);
  853. INP_INFO_WUNLOCK(&V_tcbinfo);
  854. }
  855. /*
  856. * TCP socket is closed. Start friendly disconnect.
  857. */
  858. static void
  859. tcp_usr_close(struct socket *so)
  860. {
  861. struct inpcb *inp;
  862. struct tcpcb *tp = NULL;
  863. TCPDEBUG0;
  864. inp = sotoinpcb(so);
  865. KASSERT(inp != NULL, ("tcp_usr_close: inp == NULL"));
  866. INP_INFO_WLOCK(&V_tcbinfo);
  867. INP_LOCK(inp);
  868. KASSERT(inp->inp_socket != NULL,
  869. ("tcp_usr_close: inp_socket == NULL"));
  870. /*
  871. * If we still have full TCP state, and we're not dropped, initiate
  872. * a disconnect.
  873. */
  874. if (!(inp->inp_flags & INP_TIMEWAIT) &&
  875. !(inp->inp_flags & INP_DROPPED)) {
  876. tp = intotcpcb(inp);
  877. tcp_teardown_net_channel(tp);
  878. TCPDEBUG1();
  879. tcp_disconnect(tp);
  880. TCPDEBUG2(PRU_CLOSE);
  881. }
  882. if (!(inp->inp_flags & INP_DROPPED)) {
  883. SOCK_LOCK(so);
  884. so->so_state |= SS_PROTOREF;
  885. SOCK_UNLOCK(so);
  886. inp->inp_flags |= INP_SOCKREF;
  887. }
  888. INP_UNLOCK(inp);
  889. INP_INFO_WUNLOCK(&V_tcbinfo);
  890. }
  891. /*
  892. * Receive out-of-band data.
  893. */
  894. static int
  895. tcp_usr_rcvoob(struct socket *so, struct mbuf *m, int flags)
  896. {
  897. int error = 0;
  898. struct inpcb *inp;
  899. struct tcpcb *tp = NULL;
  900. TCPDEBUG0;
  901. inp = sotoinpcb(so);
  902. KASSERT(inp != NULL, ("tcp_usr_rcvoob: inp == NULL"));
  903. INP_LOCK(inp);
  904. if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) {
  905. error = ECONNRESET;
  906. goto out;
  907. }
  908. tp = intotcpcb(inp);
  909. TCPDEBUG1();
  910. if ((so->so_oobmark == 0 &&
  911. (so->so_rcv.sb_state & SBS_RCVATMARK) == 0) ||
  912. so->so_options & SO_OOBINLINE ||
  913. tp->t_oobflags & TCPOOB_HADDATA) {
  914. error = EINVAL;
  915. goto out;
  916. }
  917. if ((tp->t_oobflags & TCPOOB_HAVEDATA) == 0) {
  918. error = EWOULDBLOCK;
  919. goto out;
  920. }
  921. m->m_hdr.mh_len = 1;
  922. *mtod(m, caddr_t) = tp->t_iobc;
  923. if ((flags & MSG_PEEK) == 0)
  924. tp->t_oobflags ^= (TCPOOB_HAVEDATA | TCPOOB_HADDATA);
  925. out:
  926. TCPDEBUG2(PRU_RCVOOB);
  927. INP_UNLOCK(inp);
  928. return (error);
  929. }
  930. #ifdef INET
  931. struct pr_usrreqs tcp_usrreqs = initialize_with([] (pr_usrreqs& x) {
  932. x.pru_abort = tcp_usr_abort;
  933. x.pru_accept = tcp_usr_accept;
  934. x.pru_attach = tcp_usr_attach;
  935. x.pru_bind = tcp_usr_bind;
  936. x.pru_connect = tcp_usr_connect;
  937. x.pru_control = in_control;
  938. x.pru_detach = tcp_usr_detach;
  939. x.pru_disconnect = tcp_usr_disconnect;
  940. x.pru_listen = tcp_usr_listen;
  941. x.pru_peeraddr = in_getpeeraddr;
  942. x.pru_rcvd = tcp_usr_rcvd;
  943. x.pru_rcvoob = tcp_usr_rcvoob;
  944. x.pru_send = tcp_usr_send;
  945. x.pru_shutdown = tcp_usr_shutdown;
  946. x.pru_sockaddr = in_getsockaddr;
  947. x.pru_sosetlabel = in_pcbsosetlabel;
  948. x.pru_close = tcp_usr_close;
  949. });
  950. #endif /* INET */
  951. #ifdef INET6
  952. struct pr_usrreqs tcp6_usrreqs = {
  953. .pru_abort = tcp_usr_abort,
  954. .pru_accept = tcp6_usr_accept,
  955. .pru_attach = tcp_usr_attach,
  956. .pru_bind = tcp6_usr_bind,
  957. .pru_connect = tcp6_usr_connect,
  958. .pru_control = in6_control,
  959. .pru_detach = tcp_usr_detach,
  960. .pru_disconnect = tcp_usr_disconnect,
  961. .pru_listen = tcp6_usr_listen,
  962. .pru_peeraddr = in6_mapped_peeraddr,
  963. .pru_rcvd = tcp_usr_rcvd,
  964. .pru_rcvoob = tcp_usr_rcvoob,
  965. .pru_send = tcp_usr_send,
  966. .pru_shutdown = tcp_usr_shutdown,
  967. .pru_sockaddr = in6_mapped_sockaddr,
  968. .pru_sosetlabel = in_pcbsosetlabel,
  969. .pru_close = tcp_usr_close,
  970. };
  971. #endif /* INET6 */
  972. #ifdef INET
  973. /*
  974. * Common subroutine to open a TCP connection to remote host specified
  975. * by struct bsd_sockaddr_in in mbuf *nam. Call in_pcbbind to assign a local
  976. * port number if needed. Call in_pcbconnect_setup to do the routing and
  977. * to choose a local host address (interface). If there is an existing
  978. * incarnation of the same connection in TIME-WAIT state and if the remote
  979. * host was sending CC options and if the connection duration was < MSL, then
  980. * truncate the previous TIME-WAIT state and proceed.
  981. * Initialize connection parameters and enter SYN-SENT state.
  982. */
  983. static int
  984. tcp_connect(struct tcpcb *tp, struct bsd_sockaddr *nam, struct thread *td)
  985. {
  986. struct inpcb *inp = tp->t_inpcb, *oinp;
  987. struct socket *so = inp->inp_socket;
  988. struct in_addr laddr;
  989. u_short lport;
  990. int error;
  991. INP_LOCK_ASSERT(inp);
  992. INP_HASH_WLOCK(&V_tcbinfo);
  993. if (inp->inp_lport == 0) {
  994. error = in_pcbbind(inp, (struct bsd_sockaddr *)0, 0);
  995. if (error)
  996. goto out;
  997. }
  998. /*
  999. * Cannot simply call in_pcbconnect, because there might be an
  1000. * earlier incarnation of this same connection still in
  1001. * TIME_WAIT state, creating an ADDRINUSE error.
  1002. */
  1003. laddr = inp->inp_laddr;
  1004. lport = inp->inp_lport;
  1005. error = in_pcbconnect_setup(inp, nam, &laddr.s_addr, &lport,
  1006. &inp->inp_faddr.s_addr, &inp->inp_fport, &oinp, 0);
  1007. if (error && oinp == NULL)
  1008. goto out;
  1009. if (oinp) {
  1010. error = EADDRINUSE;
  1011. goto out;
  1012. }
  1013. inp->inp_laddr = laddr;
  1014. in_pcbrehash(inp);
  1015. INP_HASH_WUNLOCK(&V_tcbinfo);
  1016. /*
  1017. * Compute window scaling to request:
  1018. * Scale to fit into sweet spot. See tcp_syncache.c.
  1019. * XXX: This should move to tcp_output().
  1020. */
  1021. while (tp->request_r_scale < TCP_MAX_WINSHIFT &&
  1022. (TCP_MAXWIN << tp->request_r_scale) < sb_max)
  1023. tp->request_r_scale++;
  1024. soisconnecting(so);
  1025. TCPSTAT_INC(tcps_connattempt);
  1026. tp->set_state(TCPS_SYN_SENT);
  1027. tcp_timer_activate(tp, TT_KEEP, TP_KEEPINIT(tp));
  1028. tp->iss = tcp_new_isn(tp);
  1029. tcp_sendseqinit(tp);
  1030. return 0;
  1031. out:
  1032. INP_HASH_WUNLOCK(&V_tcbinfo);
  1033. return (error);
  1034. }
  1035. #endif /* INET */
  1036. #ifdef INET6
  1037. static int
  1038. tcp6_connect(struct tcpcb *tp, struct bsd_sockaddr *nam, struct thread *td)
  1039. {
  1040. struct inpcb *inp = tp->t_inpcb, *oinp;
  1041. struct socket *so = inp->inp_socket;
  1042. struct bsd_sockaddr_in6 *sin6 = (struct bsd_sockaddr_in6 *)nam;
  1043. struct in6_addr addr6;
  1044. int error;
  1045. INP_LOCK_ASSERT(inp);
  1046. INP_HASH_WLOCK(&V_tcbinfo);
  1047. if (inp->inp_lport == 0) {
  1048. error = in6_pcbbind(inp, (struct bsd_sockaddr *)0, td->td_ucred);
  1049. if (error)
  1050. goto out;
  1051. }
  1052. /*
  1053. * Cannot simply call in_pcbconnect, because there might be an
  1054. * earlier incarnation of this same connection still in
  1055. * TIME_WAIT state, creating an ADDRINUSE error.
  1056. * in6_pcbladdr() also handles scope zone IDs.
  1057. *
  1058. * XXXRW: We wouldn't need to expose in6_pcblookup_hash_locked()
  1059. * outside of in6_pcb.c if there were an in6_pcbconnect_setup().
  1060. */
  1061. error = in6_pcbladdr(inp, nam, &addr6);
  1062. if (error)
  1063. goto out;
  1064. oinp = in6_pcblookup_hash_locked(inp->inp_pcbinfo,
  1065. &sin6->sin6_addr, sin6->sin6_port,
  1066. IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr)
  1067. ? &addr6
  1068. : &inp->in6p_laddr,
  1069. inp->inp_lport, 0, NULL);
  1070. if (oinp) {
  1071. error = EADDRINUSE;
  1072. goto out;
  1073. }
  1074. if (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr))
  1075. inp->in6p_laddr = addr6;
  1076. inp->in6p_faddr = sin6->sin6_addr;
  1077. inp->inp_fport = sin6->sin6_port;
  1078. /* update flowinfo - draft-itojun-ipv6-flowlabel-api-00 */
  1079. inp->inp_flow &= ~IPV6_FLOWLABEL_MASK;
  1080. if (inp->inp_flags & IN6P_AUTOFLOWLABEL)
  1081. inp->inp_flow |=
  1082. (htonl(ip6_randomflowlabel()) & IPV6_FLOWLABEL_MASK);
  1083. in_pcbrehash(inp);
  1084. INP_HASH_WUNLOCK(&V_tcbinfo);
  1085. /* Compute window scaling to request. */
  1086. while (tp->request_r_scale < TCP_MAX_WINSHIFT &&
  1087. (TCP_MAXWIN << tp->request_r_scale) < sb_max)
  1088. tp->request_r_scale++;
  1089. soisconnecting(so);
  1090. TCPSTAT_INC(tcps_connattempt);
  1091. tp->set_state(TCPS_SYN_SENT);
  1092. tcp_timer_activate(tp, TT_KEEP, TP_KEEPINIT(tp));
  1093. tp->iss = tcp_new_isn(tp);
  1094. tcp_sendseqinit(tp);
  1095. return 0;
  1096. out:
  1097. INP_HASH_WUNLOCK(&V_tcbinfo);
  1098. return error;
  1099. }
  1100. #endif /* INET6 */
  1101. /*
  1102. * Export TCP internal state information via a struct tcp_info, based on the
  1103. * Linux 2.6 API. Not ABI compatible as our constants are mapped differently
  1104. * (TCP state machine, etc). We export all information using FreeBSD-native
  1105. * constants -- for example, the numeric values for tcpi_state will differ
  1106. * from Linux.
  1107. */
  1108. static void
  1109. tcp_fill_info(struct tcpcb *tp, struct tcp_info *ti)
  1110. {
  1111. INP_LOCK_ASSERT(tp->t_inpcb);
  1112. bzero(ti, sizeof(*ti));
  1113. ti->tcpi_state = tp->get_state();
  1114. if ((tp->t_flags & TF_REQ_TSTMP) && (tp->t_flags & TF_RCVD_TSTMP))
  1115. ti->tcpi_options |= TCPI_OPT_TIMESTAMPS;
  1116. if (tp->t_flags & TF_SACK_PERMIT)
  1117. ti->tcpi_options |= TCPI_OPT_SACK;
  1118. if ((tp->t_flags & TF_REQ_SCALE) && (tp->t_flags & TF_RCVD_SCALE)) {
  1119. ti->tcpi_options |= TCPI_OPT_WSCALE;
  1120. ti->tcpi_snd_wscale = tp->snd_scale;
  1121. ti->tcpi_rcv_wscale = tp->rcv_scale;
  1122. }
  1123. ti->tcpi_rto = tp->t_rxtcur * tick;
  1124. ti->tcpi_last_data_recv = (long)(bsd_ticks - (int)tp->t_rcvtime) * tick;
  1125. ti->tcpi_rtt = ((u_int64_t)tp->t_srtt * tick) >> TCP_RTT_SHIFT;
  1126. ti->tcpi_rttvar = ((u_int64_t)tp->t_rttvar * tick) >> TCP_RTTVAR_SHIFT;
  1127. ti->tcpi_snd_ssthresh = tp->snd_ssthresh;
  1128. ti->tcpi_snd_cwnd = tp->snd_cwnd;
  1129. /*
  1130. * FreeBSD-specific extension fields for tcp_info.
  1131. */
  1132. ti->tcpi_rcv_space = tp->rcv_wnd;
  1133. ti->tcpi_rcv_nxt = tp->rcv_nxt.raw();
  1134. ti->tcpi_snd_wnd = tp->snd_wnd;
  1135. ti->tcpi_snd_bwnd = 0; /* Unused, kept for compat. */
  1136. ti->tcpi_snd_nxt = tp->snd_nxt.raw();
  1137. ti->tcpi_snd_mss = tp->t_maxseg;
  1138. ti->tcpi_rcv_mss = tp->t_maxseg;
  1139. if (tp->t_flags & TF_TOE)
  1140. ti->tcpi_options |= TCPI_OPT_TOE;
  1141. ti->tcpi_snd_rexmitpack = tp->t_sndrexmitpack;
  1142. ti->tcpi_rcv_ooopack = tp->t_rcvoopack;
  1143. ti->tcpi_snd_zerowin = tp->t_sndzerowin;
  1144. }
  1145. /*
  1146. * tcp_ctloutput() must drop the inpcb lock before performing copyin on
  1147. * socket option arguments. When it re-acquires the lock after the copy, it
  1148. * has to revalidate that the connection is still valid for the socket
  1149. * option.
  1150. */
  1151. #define INP_LOCK_RECHECK(inp) do { \
  1152. INP_LOCK(inp); \
  1153. if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) { \
  1154. INP_UNLOCK(inp); \
  1155. return (ECONNRESET); \
  1156. } \
  1157. tp = intotcpcb(inp); \
  1158. } while(0)
  1159. int
  1160. tcp_ctloutput(struct socket *so, struct sockopt *sopt)
  1161. {
  1162. int error, opt, optval;
  1163. u_int ui;
  1164. struct inpcb *inp;
  1165. struct tcpcb *tp;
  1166. struct tcp_info ti;
  1167. char buf[TCP_CA_NAME_MAX];
  1168. struct cc_algo *algo;
  1169. error = 0;
  1170. inp = sotoinpcb(so);
  1171. KASSERT(inp != NULL, ("tcp_ctloutput: inp == NULL"));
  1172. INP_LOCK(inp);
  1173. if (sopt->sopt_level != IPPROTO_TCP) {
  1174. #ifdef INET6
  1175. if (inp->inp_vflag & INP_IPV6PROTO) {
  1176. INP_UNLOCK(inp);
  1177. error = ip6_ctloutput(so, sopt);
  1178. }
  1179. #endif /* INET6 */
  1180. #if defined(INET6) && defined(INET)
  1181. else
  1182. #endif
  1183. #ifdef INET
  1184. {
  1185. INP_UNLOCK(inp);
  1186. error = ip_ctloutput(so, sopt);
  1187. }
  1188. #endif
  1189. return (error);
  1190. }
  1191. if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) {
  1192. INP_UNLOCK(inp);
  1193. return (ECONNRESET);
  1194. }
  1195. switch (sopt->sopt_dir) {
  1196. case SOPT_SET:
  1197. switch (sopt->sopt_name) {
  1198. #ifdef TCP_SIGNATURE
  1199. case TCP_MD5SIG:
  1200. INP_UNLOCK(inp);
  1201. error = sooptcopyin(sopt, &optval, sizeof optval,
  1202. sizeof optval);
  1203. if (error)
  1204. return (error);
  1205. INP_LOCK_RECHECK(inp);
  1206. if (optval > 0)
  1207. tp->t_flags |= TF_SIGNATURE;
  1208. else
  1209. tp->t_flags &= ~TF_SIGNATURE;
  1210. INP_UNLOCK(inp);
  1211. break;
  1212. #endif /* TCP_SIGNATURE */
  1213. case TCP_NODELAY:
  1214. case TCP_NOOPT:
  1215. INP_UNLOCK(inp);
  1216. error = sooptcopyin(sopt, &optval, sizeof optval,
  1217. sizeof optval);
  1218. if (error)
  1219. return (error);
  1220. INP_LOCK_RECHECK(inp);
  1221. switch (sopt->sopt_name) {
  1222. case TCP_NODELAY:
  1223. opt = TF_NODELAY;
  1224. break;
  1225. case TCP_NOOPT:
  1226. opt = TF_NOOPT;
  1227. break;
  1228. default:
  1229. opt = 0; /* dead code to fool gcc */
  1230. break;
  1231. }
  1232. if (optval)
  1233. tp->t_flags |= opt;
  1234. else
  1235. tp->t_flags &= ~opt;
  1236. INP_UNLOCK(inp);
  1237. break;
  1238. case TCP_NOPUSH:
  1239. INP_UNLOCK(inp);
  1240. error = sooptcopyin(sopt, &optval, sizeof optval,
  1241. sizeof optval);
  1242. if (error)
  1243. return (error);
  1244. INP_LOCK_RECHECK(inp);
  1245. if (optval)
  1246. tp->t_flags |= TF_NOPUSH;
  1247. else if (tp->t_flags & TF_NOPUSH) {
  1248. tp->t_flags &= ~TF_NOPUSH;
  1249. if (TCPS_HAVEESTABLISHED(tp->get_state()))
  1250. error = tcp_output(tp);
  1251. }
  1252. INP_UNLOCK(inp);
  1253. break;
  1254. case TCP_MAXSEG:
  1255. INP_UNLOCK(inp);
  1256. error = sooptcopyin(sopt, &optval, sizeof optval,
  1257. sizeof optval);
  1258. if (error)
  1259. return (error);
  1260. INP_LOCK_RECHECK(inp);
  1261. if (optval > 0 && optval <= tp->t_maxseg &&
  1262. optval + 40 >= V_tcp_minmss)
  1263. tp->t_maxseg = optval;
  1264. else
  1265. error = EINVAL;
  1266. INP_UNLOCK(inp);
  1267. break;
  1268. case TCP_INFO:
  1269. INP_UNLOCK(inp);
  1270. error = EINVAL;
  1271. break;
  1272. case TCP_CONGESTION:
  1273. INP_UNLOCK(inp);
  1274. bzero(buf, sizeof(buf));
  1275. error = sooptcopyin(sopt, &buf, sizeof(buf), 1);
  1276. if (error)
  1277. break;
  1278. INP_LOCK_RECHECK(inp);
  1279. /*
  1280. * Return EINVAL if we can't find the requested cc algo.
  1281. */
  1282. error = EINVAL;
  1283. CC_LIST_RLOCK();
  1284. STAILQ_FOREACH(algo, &cc_list, entries) {
  1285. if (strncmp(buf, algo->name, TCP_CA_NAME_MAX)
  1286. == 0) {
  1287. /* We've found the requested algo. */
  1288. error = 0;
  1289. /*
  1290. * We hold a write lock over the tcb
  1291. * so it's safe to do these things
  1292. * without ordering concerns.
  1293. */
  1294. if (CC_ALGO(tp)->cb_destroy != NULL)
  1295. CC_ALGO(tp)->cb_destroy(tp->ccv);
  1296. CC_ALGO(tp) = algo;
  1297. /*
  1298. * If something goes pear shaped
  1299. * initialising the new algo,
  1300. * fall back to newreno (which
  1301. * does not require initialisation).
  1302. */
  1303. if (algo->cb_init != NULL)
  1304. if (algo->cb_init(tp->ccv) > 0) {
  1305. CC_ALGO(tp) = &newreno_cc_algo;
  1306. /*
  1307. * The only reason init
  1308. * should fail is
  1309. * because of malloc.
  1310. */
  1311. error = ENOMEM;
  1312. }
  1313. break; /* Break the STAILQ_FOREACH. */
  1314. }
  1315. }
  1316. CC_LIST_RUNLOCK();
  1317. INP_UNLOCK(inp);
  1318. break;
  1319. case TCP_KEEPIDLE:
  1320. case TCP_KEEPINTVL:
  1321. case TCP_KEEPINIT:
  1322. INP_UNLOCK(inp);
  1323. error = sooptcopyin(sopt, &ui, sizeof(ui), sizeof(ui));
  1324. if (error)
  1325. return (error);
  1326. if (ui > (UINT_MAX / hz)) {
  1327. error = EINVAL;
  1328. break;
  1329. }
  1330. ui *= hz;
  1331. INP_LOCK_RECHECK(inp);
  1332. switch (sopt->sopt_name) {
  1333. case TCP_KEEPIDLE:
  1334. tp->t_keepidle = ui;
  1335. /*
  1336. * XXX: better check current remaining
  1337. * timeout and "merge" it with new value.
  1338. */
  1339. if ((tp->get_state() > TCPS_LISTEN) &&
  1340. (tp->get_state() <= TCPS_CLOSING))
  1341. tcp_timer_activate(tp, TT_KEEP,
  1342. TP_KEEPIDLE(tp));
  1343. break;
  1344. case TCP_KEEPINTVL:
  1345. tp->t_keepintvl = ui;
  1346. if ((tp->get_state() == TCPS_FIN_WAIT_2) &&
  1347. (TP_MAXIDLE(tp) > 0))
  1348. tcp_timer_activate(tp, TT_2MSL,
  1349. TP_MAXIDLE(tp));
  1350. break;
  1351. case TCP_KEEPINIT:
  1352. tp->t_keepinit = ui;
  1353. if (tp->get_state() == TCPS_SYN_RECEIVED ||
  1354. tp->get_state() == TCPS_SYN_SENT)
  1355. tcp_timer_activate(tp, TT_KEEP,
  1356. TP_KEEPINIT(tp));
  1357. break;
  1358. }
  1359. INP_UNLOCK(inp);
  1360. break;
  1361. case TCP_KEEPCNT:
  1362. INP_UNLOCK(inp);
  1363. error = sooptcopyin(sopt, &ui, sizeof(ui), sizeof(ui));
  1364. if (error)
  1365. return (error);
  1366. INP_LOCK_RECHECK(inp);
  1367. tp->t_keepcnt = ui;
  1368. if ((tp->get_state() == TCPS_FIN_WAIT_2) &&
  1369. (TP_MAXIDLE(tp) > 0))
  1370. tcp_timer_activate(tp, TT_2MSL,
  1371. TP_MAXIDLE(tp));
  1372. INP_UNLOCK(inp);
  1373. break;
  1374. default:
  1375. INP_UNLOCK(inp);
  1376. error = ENOPROTOOPT;
  1377. break;
  1378. }
  1379. break;
  1380. case SOPT_GET:
  1381. tp = intotcpcb(inp);
  1382. switch (sopt->sopt_name) {
  1383. #ifdef TCP_SIGNATURE
  1384. case TCP_MD5SIG:
  1385. optval = (tp->t_flags & TF_SIGNATURE) ? 1 : 0;
  1386. INP_UNLOCK(inp);
  1387. error = sooptcopyout(sopt, &optval, sizeof optval);
  1388. break;
  1389. #endif
  1390. case TCP_NODELAY:
  1391. optval = tp->t_flags & TF_NODELAY;
  1392. INP_UNLOCK(inp);
  1393. error = sooptcopyout(sopt, &optval, sizeof optval);
  1394. break;
  1395. case TCP_MAXSEG:
  1396. optval = tp->t_maxseg;
  1397. INP_UNLOCK(inp);
  1398. error = sooptcopyout(sopt, &optval, sizeof optval);
  1399. break;
  1400. case TCP_NOOPT:
  1401. optval = tp->t_flags & TF_NOOPT;
  1402. INP_UNLOCK(inp);
  1403. error = sooptcopyout(sopt, &optval, sizeof optval);
  1404. break;
  1405. case TCP_NOPUSH:
  1406. optval = tp->t_flags & TF_NOPUSH;
  1407. INP_UNLOCK(inp);
  1408. error = sooptcopyout(sopt, &optval, sizeof optval);
  1409. break;
  1410. case TCP_INFO:
  1411. tcp_fill_info(tp, &ti);
  1412. INP_UNLOCK(inp);
  1413. error = sooptcopyout(sopt, &ti, sizeof ti);
  1414. break;
  1415. case TCP_CONGESTION:
  1416. bzero(buf, sizeof(buf));
  1417. strlcpy(buf, CC_ALGO(tp)->name, TCP_CA_NAME_MAX);
  1418. INP_UNLOCK(inp);
  1419. error = sooptcopyout(sopt, buf, TCP_CA_NAME_MAX);
  1420. break;
  1421. case TCP_KEEPINTVL:
  1422. optval = tp->t_keepintvl;
  1423. INP_UNLOCK(inp);
  1424. error = sooptcopyout(sopt, &optval, sizeof optval);
  1425. break;
  1426. case TCP_KEEPIDLE:
  1427. optval = tp->t_keepidle;
  1428. INP_UNLOCK(inp);
  1429. error = sooptcopyout(sopt, &optval, sizeof optval);
  1430. break;
  1431. case TCP_KEEPINIT:
  1432. optval = tp->t_keepinit;
  1433. INP_UNLOCK(inp);
  1434. error = sooptcopyout(sopt, &optval, sizeof optval);
  1435. break;
  1436. default:
  1437. INP_UNLOCK(inp);
  1438. error = ENOPROTOOPT;
  1439. break;
  1440. }
  1441. break;
  1442. }
  1443. return (error);
  1444. }
  1445. #undef INP_LOCK_RECHECK
  1446. /*
  1447. * tcp_sendspace and tcp_recvspace are the default send and receive window
  1448. * sizes, respectively. These are obsolescent (this information should
  1449. * be set by the route).
  1450. */
  1451. u_long tcp_sendspace = 1024*32;
  1452. SYSCTL_ULONG(_net_inet_tcp, TCPCTL_SENDSPACE, sendspace, CTLFLAG_RW,
  1453. &tcp_sendspace , 0, "Maximum outgoing TCP datagram size");
  1454. u_long tcp_recvspace = 1024*64;
  1455. SYSCTL_ULONG(_net_inet_tcp, TCPCTL_RECVSPACE, recvspace, CTLFLAG_RW,
  1456. &tcp_recvspace , 0, "Maximum incoming TCP datagram size");
  1457. /*
  1458. * Attach TCP protocol to socket, allocating
  1459. * internet protocol control block, tcp control block,
  1460. * bufer space, and entering LISTEN state if to accept connections.
  1461. */
  1462. static int
  1463. tcp_attach(struct socket *so)
  1464. {
  1465. struct tcpcb *tp;
  1466. struct inpcb *inp;
  1467. int error;
  1468. if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {
  1469. error = soreserve_internal(so, tcp_sendspace, tcp_recvspace);
  1470. if (error)
  1471. return (error);
  1472. }
  1473. so->so_rcv.sb_flags |= SB_AUTOSIZE;
  1474. so->so_snd.sb_flags |= SB_AUTOSIZE;
  1475. INP_INFO_WLOCK(&V_tcbinfo);
  1476. inp = new inpcb(so, &V_tcbinfo);
  1477. #ifdef INET6
  1478. if (inp->inp_vflag & INP_IPV6PROTO) {
  1479. inp->inp_vflag |= INP_IPV6;
  1480. inp->in6p_hops = -1; /* use kernel default */
  1481. }
  1482. else
  1483. #endif
  1484. inp->inp_vflag |= INP_IPV4;
  1485. tp = tcp_newtcpcb(inp);
  1486. if (tp == NULL) {
  1487. in_pcbdetach(inp);
  1488. in_pcbfree(inp);
  1489. INP_INFO_WUNLOCK(&V_tcbinfo);
  1490. return (ENOBUFS);
  1491. }
  1492. tp->set_state(TCPS_CLOSED);
  1493. INP_UNLOCK(inp);
  1494. INP_INFO_WUNLOCK(&V_tcbinfo);
  1495. return (0);
  1496. }
  1497. /*
  1498. * Initiate (or continue) disconnect.
  1499. * If embryonic state, just send reset (once).
  1500. * If in ``let data drain'' option and linger null, just drop.
  1501. * Otherwise (hard), mark socket disconnecting and drop
  1502. * current input data; switch states based on user close, and
  1503. * send segment to peer (with FIN).
  1504. */
  1505. static void
  1506. tcp_disconnect(struct tcpcb *tp)
  1507. {
  1508. struct inpcb *inp = tp->t_inpcb;
  1509. struct socket *so = inp->inp_socket;
  1510. INP_INFO_WLOCK_ASSERT(&V_tcbinfo);
  1511. INP_LOCK_ASSERT(inp);
  1512. /*
  1513. * Neither tcp_close() nor tcp_drop() should return NULL, as the
  1514. * socket is still open.
  1515. */
  1516. if (tp->get_state() < TCPS_ESTABLISHED) {
  1517. tp = tcp_close(tp);
  1518. KASSERT(tp != NULL,
  1519. ("tcp_disconnect: tcp_close() returned NULL"));
  1520. } else if ((so->so_options & SO_LINGER) && so->so_linger == 0) {
  1521. tp = tcp_drop(tp, 0);
  1522. KASSERT(tp != NULL,
  1523. ("tcp_disconnect: tcp_drop() returned NULL"));
  1524. } else {
  1525. soisdisconnecting(so);
  1526. sbflush(so, &so->so_rcv);
  1527. tcp_usrclosed(tp);
  1528. if (!(inp->inp_flags & INP_DROPPED))
  1529. tcp_output(tp);
  1530. }
  1531. }
  1532. /*
  1533. * User issued close, and wish to trail through shutdown states:
  1534. * if never received SYN, just forget it. If got a SYN from peer,
  1535. * but haven't sent FIN, then go to FIN_WAIT_1 state to send peer a FIN.
  1536. * If already got a FIN from peer, then almost done; go to LAST_ACK
  1537. * state. In all other cases, have already sent FIN to peer (e.g.
  1538. * after PRU_SHUTDOWN), and just have to play tedious game waiting
  1539. * for peer to send FIN or not respond to keep-alives, etc.
  1540. * We can let the user exit from the close as soon as the FIN is acked.
  1541. */
  1542. static void
  1543. tcp_usrclosed(struct tcpcb *tp)
  1544. {
  1545. INP_INFO_WLOCK_ASSERT(&V_tcbinfo);
  1546. INP_LOCK_ASSERT(tp->t_inpcb);
  1547. tcp_teardown_net_channel(tp);
  1548. switch (tp->get_state()) {
  1549. case TCPS_LISTEN:
  1550. /* FALLTHROUGH */
  1551. case TCPS_CLOSED:
  1552. tp->set_state(TCPS_CLOSED);
  1553. tp = tcp_close(tp);
  1554. /*
  1555. * tcp_close() should never return NULL here as the socket is
  1556. * still open.
  1557. */
  1558. KASSERT(tp != NULL,
  1559. ("tcp_usrclosed: tcp_close() returned NULL"));
  1560. break;
  1561. case TCPS_SYN_SENT:
  1562. case TCPS_SYN_RECEIVED:
  1563. tp->t_flags |= TF_NEEDFIN;
  1564. break;
  1565. case TCPS_ESTABLISHED:
  1566. tp->set_state(TCPS_FIN_WAIT_1);
  1567. break;
  1568. case TCPS_CLOSE_WAIT:
  1569. tp->set_state(TCPS_LAST_ACK);
  1570. break;
  1571. }
  1572. if (tp->get_state() >= TCPS_FIN_WAIT_2) {
  1573. soisdisconnected(tp->t_inpcb->inp_socket);
  1574. /* Prevent the connection hanging in FIN_WAIT_2 forever. */
  1575. if (tp->get_state() == TCPS_FIN_WAIT_2) {
  1576. int timeout;
  1577. timeout = (tcp_fast_finwait2_recycle) ?
  1578. tcp_finwait2_timeout : TP_MAXIDLE(tp);
  1579. tcp_timer_activate(tp, TT_2MSL, timeout);
  1580. }
  1581. }
  1582. }
  1583. #ifdef DDB
  1584. static void
  1585. db_print_indent(int indent)
  1586. {
  1587. int i;
  1588. for (i = 0; i < indent; i++)
  1589. db_printf(" ");
  1590. }
  1591. static void
  1592. db_print_tstate(int t_state)
  1593. {
  1594. switch (t_state) {
  1595. case TCPS_CLOSED:
  1596. db_printf("TCPS_CLOSED");
  1597. return;
  1598. case TCPS_LISTEN:
  1599. db_printf("TCPS_LISTEN");
  1600. return;
  1601. case TCPS_SYN_SENT:
  1602. db_printf("TCPS_SYN_SENT");
  1603. return;
  1604. case TCPS_SYN_RECEIVED:
  1605. db_printf("TCPS_SYN_RECEIVED");
  1606. return;
  1607. case TCPS_ESTABLISHED:
  1608. db_printf("TCPS_ESTABLISHED");
  1609. return;
  1610. case TCPS_CLOSE_WAIT:
  1611. db_printf("TCPS_CLOSE_WAIT");
  1612. return;
  1613. case TCPS_FIN_WAIT_1:
  1614. db_printf("TCPS_FIN_WAIT_1");
  1615. return;
  1616. case TCPS_CLOSING:
  1617. db_printf("TCPS_CLOSING");
  1618. return;
  1619. case TCPS_LAST_ACK:
  1620. db_printf("TCPS_LAST_ACK");
  1621. return;
  1622. case TCPS_FIN_WAIT_2:
  1623. db_printf("TCPS_FIN_WAIT_2");
  1624. return;
  1625. case TCPS_TIME_WAIT:
  1626. db_printf("TCPS_TIME_WAIT");
  1627. return;
  1628. default:
  1629. db_printf("unknown");
  1630. return;
  1631. }
  1632. }
  1633. static void
  1634. db_print_tflags(u_int t_flags)
  1635. {
  1636. int comma;
  1637. comma = 0;
  1638. if (t_flags & TF_ACKNOW) {
  1639. db_printf("%sTF_ACKNOW", comma ? ", " : "");
  1640. comma = 1;
  1641. }
  1642. if (t_flags & TF_DELACK) {
  1643. db_printf("%sTF_DELACK", comma ? ", " : "");
  1644. comma = 1;
  1645. }
  1646. if (t_flags & TF_NODELAY) {
  1647. db_printf("%sTF_NODELAY", comma ? ", " : "");
  1648. comma = 1;
  1649. }
  1650. if (t_flags & TF_NOOPT) {
  1651. db_printf("%sTF_NOOPT", comma ? ", " : "");
  1652. comma = 1;
  1653. }
  1654. if (t_flags & TF_SENTFIN) {
  1655. db_printf("%sTF_SENTFIN", comma ? ", " : "");
  1656. comma = 1;
  1657. }
  1658. if (t_flags & TF_REQ_SCALE) {
  1659. db_printf("%sTF_REQ_SCALE", comma ? ", " : "");
  1660. comma = 1;
  1661. }
  1662. if (t_flags & TF_RCVD_SCALE) {
  1663. db_printf("%sTF_RECVD_SCALE", comma ? ", " : "");
  1664. comma = 1;
  1665. }
  1666. if (t_flags & TF_REQ_TSTMP) {
  1667. db_printf("%sTF_REQ_TSTMP", comma ? ", " : "");
  1668. comma = 1;
  1669. }
  1670. if (t_flags & TF_RCVD_TSTMP) {
  1671. db_printf("%sTF_RCVD_TSTMP", comma ? ", " : "");
  1672. comma = 1;
  1673. }
  1674. if (t_flags & TF_SACK_PERMIT) {
  1675. db_printf("%sTF_SACK_PERMIT", comma ? ", " : "");
  1676. comma = 1;
  1677. }
  1678. if (t_flags & TF_NEEDSYN) {
  1679. db_printf("%sTF_NEEDSYN", comma ? ", " : "");
  1680. comma = 1;
  1681. }
  1682. if (t_flags & TF_NEEDFIN) {
  1683. db_printf("%sTF_NEEDFIN", comma ? ", " : "");
  1684. comma = 1;
  1685. }
  1686. if (t_flags & TF_NOPUSH) {
  1687. db_printf("%sTF_NOPUSH", comma ? ", " : "");
  1688. comma = 1;
  1689. }
  1690. if (t_flags & TF_MORETOCOME) {
  1691. db_printf("%sTF_MORETOCOME", comma ? ", " : "");
  1692. comma = 1;
  1693. }
  1694. if (t_flags & TF_LQ_OVERFLOW) {
  1695. db_printf("%sTF_LQ_OVERFLOW", comma ? ", " : "");
  1696. comma = 1;
  1697. }
  1698. if (t_flags & TF_LASTIDLE) {
  1699. db_printf("%sTF_LASTIDLE", comma ? ", " : "");
  1700. comma = 1;
  1701. }
  1702. if (t_flags & TF_RXWIN0SENT) {
  1703. db_printf("%sTF_RXWIN0SENT", comma ? ", " : "");
  1704. comma = 1;
  1705. }
  1706. if (t_flags & TF_FASTRECOVERY) {
  1707. db_printf("%sTF_FASTRECOVERY", comma ? ", " : "");
  1708. comma = 1;
  1709. }
  1710. if (t_flags & TF_CONGRECOVERY) {
  1711. db_printf("%sTF_CONGRECOVERY", comma ? ", " : "");
  1712. comma = 1;
  1713. }
  1714. if (t_flags & TF_WASFRECOVERY) {
  1715. db_printf("%sTF_WASFRECOVERY", comma ? ", " : "");
  1716. comma = 1;
  1717. }
  1718. if (t_flags & TF_SIGNATURE) {
  1719. db_printf("%sTF_SIGNATURE", comma ? ", " : "");
  1720. comma = 1;
  1721. }
  1722. if (t_flags & TF_FORCEDATA) {
  1723. db_printf("%sTF_FORCEDATA", comma ? ", " : "");
  1724. comma = 1;
  1725. }
  1726. if (t_flags & TF_TSO) {
  1727. db_printf("%sTF_TSO", comma ? ", " : "");
  1728. comma = 1;
  1729. }
  1730. if (t_flags & TF_ECN_PERMIT) {
  1731. db_printf("%sTF_ECN_PERMIT", comma ? ", " : "");
  1732. comma = 1;
  1733. }
  1734. }
  1735. static void
  1736. db_print_toobflags(char t_oobflags)
  1737. {
  1738. int comma;
  1739. comma = 0;
  1740. if (t_oobflags & TCPOOB_HAVEDATA) {
  1741. db_printf("%sTCPOOB_HAVEDATA", comma ? ", " : "");
  1742. comma = 1;
  1743. }
  1744. if (t_oobflags & TCPOOB_HADDATA) {
  1745. db_printf("%sTCPOOB_HADDATA", comma ? ", " : "");
  1746. comma = 1;
  1747. }
  1748. }
  1749. static void
  1750. db_print_tcpcb(struct tcpcb *tp, const char *name, int indent)
  1751. {
  1752. db_print_indent(indent);
  1753. db_printf("%s at %p\n", name, tp);
  1754. indent += 2;
  1755. db_print_indent(indent);
  1756. db_printf("t_segq first: %p t_segqlen: %d t_dupacks: %d\n",
  1757. LIST_FIRST(&tp->t_segq), tp->t_segqlen, tp->t_dupacks);
  1758. db_print_indent(indent);
  1759. db_printf("tt_rexmt: %p tt_persist: %p tt_keep: %p\n",
  1760. &tp->t_timers->tt_rexmt, &tp->t_timers->tt_persist, &tp->t_timers->tt_keep);
  1761. db_print_indent(indent);
  1762. db_printf("tt_2msl: %p tt_delack: %p t_inpcb: %p\n", &tp->t_timers->tt_2msl,
  1763. &tp->t_timers->tt_delack, tp->t_inpcb);
  1764. db_print_indent(indent);
  1765. db_printf("t_state: %d (", tp->get_state());
  1766. db_print_tstate(tp->get_state());
  1767. db_printf(")\n");
  1768. db_print_indent(indent);
  1769. db_printf("t_flags: 0x%x (", tp->t_flags);
  1770. db_print_tflags(tp->t_flags);
  1771. db_printf(")\n");
  1772. db_print_indent(indent);
  1773. db_printf("snd_una: 0x%08x snd_max: 0x%08x snd_nxt: x0%08x\n",
  1774. tp->snd_una, tp->snd_max, tp->snd_nxt);
  1775. db_print_indent(indent);
  1776. db_printf("snd_up: 0x%08x snd_wl1: 0x%08x snd_wl2: 0x%08x\n",
  1777. tp->snd_up, tp->snd_wl1, tp->snd_wl2);
  1778. db_print_indent(indent);
  1779. db_printf("iss: 0x%08x irs: 0x%08x rcv_nxt: 0x%08x\n",
  1780. tp->iss, tp->irs, tp->rcv_nxt);
  1781. db_print_indent(indent);
  1782. db_printf("rcv_adv: 0x%08x rcv_wnd: %lu rcv_up: 0x%08x\n",
  1783. tp->rcv_adv, tp->rcv_wnd, tp->rcv_up);
  1784. db_print_indent(indent);
  1785. db_printf("snd_wnd: %lu snd_cwnd: %lu\n",
  1786. tp->snd_wnd, tp->snd_cwnd);
  1787. db_print_indent(indent);
  1788. db_printf("snd_ssthresh: %lu snd_recover: "
  1789. "0x%08x\n", tp->snd_ssthresh, tp->snd_recover);
  1790. db_print_indent(indent);
  1791. db_printf("t_maxopd: %u t_rcvtime: %u t_startime: %u\n",
  1792. tp->t_maxopd, tp->t_rcvtime, tp->t_starttime);
  1793. db_print_indent(indent);
  1794. db_printf("t_rttime: %u t_rtsq: 0x%08x\n",
  1795. tp->t_rtttime, tp->t_rtseq);
  1796. db_print_indent(indent);
  1797. db_printf("t_rxtcur: %d t_maxseg: %u t_srtt: %d\n",
  1798. tp->t_rxtcur, tp->t_maxseg, tp->t_srtt);
  1799. db_print_indent(indent);
  1800. db_printf("t_rttvar: %d t_rxtshift: %d t_rttmin: %u "
  1801. "t_rttbest: %u\n", tp->t_rttvar, tp->t_rxtshift, tp->t_rttmin,
  1802. tp->t_rttbest);
  1803. db_print_indent(indent);
  1804. db_printf("t_rttupdated: %lu max_sndwnd: %lu t_softerror: %d\n",
  1805. tp->t_rttupdated, tp->max_sndwnd, tp->t_softerror);
  1806. db_print_indent(indent);
  1807. db_printf("t_oobflags: 0x%x (", tp->t_oobflags);
  1808. db_print_toobflags(tp->t_oobflags);
  1809. db_printf(") t_iobc: 0x%02x\n", tp->t_iobc);
  1810. db_print_indent(indent);
  1811. db_printf("snd_scale: %u rcv_scale: %u request_r_scale: %u\n",
  1812. tp->snd_scale, tp->rcv_scale, tp->request_r_scale);
  1813. db_print_indent(indent);
  1814. db_printf("ts_recent: %u ts_recent_age: %u\n",
  1815. tp->ts_recent, tp->ts_recent_age);
  1816. db_print_indent(indent);
  1817. db_printf("ts_offset: %u last_ack_sent: 0x%08x snd_cwnd_prev: "
  1818. "%lu\n", tp->ts_offset, tp->last_ack_sent, tp->snd_cwnd_prev);
  1819. db_print_indent(indent);
  1820. db_printf("snd_ssthresh_prev: %lu snd_recover_prev: 0x%08x "
  1821. "t_badrxtwin: %u\n", tp->snd_ssthresh_prev,
  1822. tp->snd_recover_prev, tp->t_badrxtwin);
  1823. db_print_indent(indent);
  1824. db_printf("snd_numholes: %d snd_holes first: %p\n",
  1825. tp->snd_numholes, TAILQ_FIRST(&tp->snd_holes));

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