Deleted Added
full compact
tcp_input.c (292003) tcp_input.c (292309)
1/*-
2 * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1994, 1995
3 * The Regents of the University of California. All rights reserved.
4 * Copyright (c) 2007-2008,2010
5 * Swinburne University of Technology, Melbourne, Australia.
6 * Copyright (c) 2009-2010 Lawrence Stewart <lstewart@freebsd.org>
7 * Copyright (c) 2010 The FreeBSD Foundation
8 * Copyright (c) 2010-2011 Juniper Networks, Inc.

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

43 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
44 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
45 * SUCH DAMAGE.
46 *
47 * @(#)tcp_input.c 8.12 (Berkeley) 5/24/95
48 */
49
50#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1994, 1995
3 * The Regents of the University of California. All rights reserved.
4 * Copyright (c) 2007-2008,2010
5 * Swinburne University of Technology, Melbourne, Australia.
6 * Copyright (c) 2009-2010 Lawrence Stewart <lstewart@freebsd.org>
7 * Copyright (c) 2010 The FreeBSD Foundation
8 * Copyright (c) 2010-2011 Juniper Networks, Inc.

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

43 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
44 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
45 * SUCH DAMAGE.
46 *
47 * @(#)tcp_input.c 8.12 (Berkeley) 5/24/95
48 */
49
50#include <sys/cdefs.h>
51__FBSDID("$FreeBSD: head/sys/netinet/tcp_input.c 292003 2015-12-08 21:21:48Z hiren $");
51__FBSDID("$FreeBSD: head/sys/netinet/tcp_input.c 292309 2015-12-16 00:56:45Z rrs $");
52
53#include "opt_ipfw.h" /* for ipfw_fwd */
54#include "opt_inet.h"
55#include "opt_inet6.h"
56#include "opt_ipsec.h"
57#include "opt_tcpdebug.h"
58
59#include <sys/param.h>

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

225SYSCTL_INT(_net_inet_tcp, OID_AUTO, recvbuf_max, CTLFLAG_VNET | CTLFLAG_RW,
226 &VNET_NAME(tcp_autorcvbuf_max), 0,
227 "Max size of automatic receive buffer");
228
229VNET_DEFINE(struct inpcbhead, tcb);
230#define tcb6 tcb /* for KAME src sync over BSD*'s */
231VNET_DEFINE(struct inpcbinfo, tcbinfo);
232
52
53#include "opt_ipfw.h" /* for ipfw_fwd */
54#include "opt_inet.h"
55#include "opt_inet6.h"
56#include "opt_ipsec.h"
57#include "opt_tcpdebug.h"
58
59#include <sys/param.h>

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

225SYSCTL_INT(_net_inet_tcp, OID_AUTO, recvbuf_max, CTLFLAG_VNET | CTLFLAG_RW,
226 &VNET_NAME(tcp_autorcvbuf_max), 0,
227 "Max size of automatic receive buffer");
228
229VNET_DEFINE(struct inpcbhead, tcb);
230#define tcb6 tcb /* for KAME src sync over BSD*'s */
231VNET_DEFINE(struct inpcbinfo, tcbinfo);
232
233static void tcp_dooptions(struct tcpopt *, u_char *, int, int);
234static void tcp_do_segment(struct mbuf *, struct tcphdr *,
235 struct socket *, struct tcpcb *, int, int, uint8_t,
236 int);
237static void tcp_dropwithreset(struct mbuf *, struct tcphdr *,
238 struct tcpcb *, int, int);
239static void tcp_pulloutofband(struct socket *,
240 struct tcphdr *, struct mbuf *, int);
241static void tcp_xmit_timer(struct tcpcb *, int);
242static void tcp_newreno_partial_ack(struct tcpcb *, struct tcphdr *);
243static void inline cc_ack_received(struct tcpcb *tp, struct tcphdr *th,
244 uint16_t type);
245static void inline cc_conn_init(struct tcpcb *tp);
246static void inline cc_post_recovery(struct tcpcb *tp, struct tcphdr *th);
247static void inline hhook_run_tcp_est_in(struct tcpcb *tp,
248 struct tcphdr *th, struct tcpopt *to);
249
250/*
251 * TCP statistics are stored in an "array" of counter(9)s.
252 */
253VNET_PCPUSTAT_DEFINE(struct tcpstat, tcpstat);
254VNET_PCPUSTAT_SYSINIT(tcpstat);
255SYSCTL_VNET_PCPUSTAT(_net_inet_tcp, TCPCTL_STATS, stats, struct tcpstat,
256 tcpstat, "TCP statistics (struct tcpstat, netinet/tcp_var.h)");
257

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

267{
268
269 counter_u64_add(VNET(tcpstat)[statnum], 1);
270}
271
272/*
273 * Wrapper for the TCP established input helper hook.
274 */
233/*
234 * TCP statistics are stored in an "array" of counter(9)s.
235 */
236VNET_PCPUSTAT_DEFINE(struct tcpstat, tcpstat);
237VNET_PCPUSTAT_SYSINIT(tcpstat);
238SYSCTL_VNET_PCPUSTAT(_net_inet_tcp, TCPCTL_STATS, stats, struct tcpstat,
239 tcpstat, "TCP statistics (struct tcpstat, netinet/tcp_var.h)");
240

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

250{
251
252 counter_u64_add(VNET(tcpstat)[statnum], 1);
253}
254
255/*
256 * Wrapper for the TCP established input helper hook.
257 */
275static void inline
258void
276hhook_run_tcp_est_in(struct tcpcb *tp, struct tcphdr *th, struct tcpopt *to)
277{
278 struct tcp_hhook_data hhook_data;
279
280 if (V_tcp_hhh[HHOOK_TCP_EST_IN]->hhh_nhooks > 0) {
281 hhook_data.tp = tp;
282 hhook_data.th = th;
283 hhook_data.to = to;
284
285 hhook_run_hooks(V_tcp_hhh[HHOOK_TCP_EST_IN], &hhook_data,
286 tp->osd);
287 }
288}
289
290/*
291 * CC wrapper hook functions
292 */
259hhook_run_tcp_est_in(struct tcpcb *tp, struct tcphdr *th, struct tcpopt *to)
260{
261 struct tcp_hhook_data hhook_data;
262
263 if (V_tcp_hhh[HHOOK_TCP_EST_IN]->hhh_nhooks > 0) {
264 hhook_data.tp = tp;
265 hhook_data.th = th;
266 hhook_data.to = to;
267
268 hhook_run_hooks(V_tcp_hhh[HHOOK_TCP_EST_IN], &hhook_data,
269 tp->osd);
270 }
271}
272
273/*
274 * CC wrapper hook functions
275 */
293static void inline
276void
294cc_ack_received(struct tcpcb *tp, struct tcphdr *th, uint16_t type)
295{
296 INP_WLOCK_ASSERT(tp->t_inpcb);
297
298 tp->ccv->bytes_this_ack = BYTES_THIS_ACK(tp, th);
299 if (tp->snd_cwnd <= tp->snd_wnd)
300 tp->ccv->flags |= CCF_CWND_LIMITED;
301 else

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

317
318 if (CC_ALGO(tp)->ack_received != NULL) {
319 /* XXXLAS: Find a way to live without this */
320 tp->ccv->curack = th->th_ack;
321 CC_ALGO(tp)->ack_received(tp->ccv, type);
322 }
323}
324
277cc_ack_received(struct tcpcb *tp, struct tcphdr *th, uint16_t type)
278{
279 INP_WLOCK_ASSERT(tp->t_inpcb);
280
281 tp->ccv->bytes_this_ack = BYTES_THIS_ACK(tp, th);
282 if (tp->snd_cwnd <= tp->snd_wnd)
283 tp->ccv->flags |= CCF_CWND_LIMITED;
284 else

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

300
301 if (CC_ALGO(tp)->ack_received != NULL) {
302 /* XXXLAS: Find a way to live without this */
303 tp->ccv->curack = th->th_ack;
304 CC_ALGO(tp)->ack_received(tp->ccv, type);
305 }
306}
307
325static void inline
308void
326cc_conn_init(struct tcpcb *tp)
327{
328 struct hc_metrics_lite metrics;
329 struct inpcb *inp = tp->t_inpcb;
330 int rtt;
331
332 INP_WLOCK_ASSERT(tp->t_inpcb);
333

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

441
442 if (CC_ALGO(tp)->cong_signal != NULL) {
443 if (th != NULL)
444 tp->ccv->curack = th->th_ack;
445 CC_ALGO(tp)->cong_signal(tp->ccv, type);
446 }
447}
448
309cc_conn_init(struct tcpcb *tp)
310{
311 struct hc_metrics_lite metrics;
312 struct inpcb *inp = tp->t_inpcb;
313 int rtt;
314
315 INP_WLOCK_ASSERT(tp->t_inpcb);
316

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

424
425 if (CC_ALGO(tp)->cong_signal != NULL) {
426 if (th != NULL)
427 tp->ccv->curack = th->th_ack;
428 CC_ALGO(tp)->cong_signal(tp->ccv, type);
429 }
430}
431
449static void inline
432void inline
450cc_post_recovery(struct tcpcb *tp, struct tcphdr *th)
451{
452 INP_WLOCK_ASSERT(tp->t_inpcb);
453
454 /* XXXLAS: KASSERT that we're in recovery? */
455
456 if (CC_ALGO(tp)->post_recovery != NULL) {
457 tp->ccv->curack = th->th_ack;

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

596 struct ip6_hdr *ip6 = NULL;
597 int isipv6;
598#else
599 const void *ip6 = NULL;
600#endif /* INET6 */
601 struct tcpopt to; /* options in this segment */
602 char *s = NULL; /* address and port logging */
603 int ti_locked;
433cc_post_recovery(struct tcpcb *tp, struct tcphdr *th)
434{
435 INP_WLOCK_ASSERT(tp->t_inpcb);
436
437 /* XXXLAS: KASSERT that we're in recovery? */
438
439 if (CC_ALGO(tp)->post_recovery != NULL) {
440 tp->ccv->curack = th->th_ack;

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

579 struct ip6_hdr *ip6 = NULL;
580 int isipv6;
581#else
582 const void *ip6 = NULL;
583#endif /* INET6 */
584 struct tcpopt to; /* options in this segment */
585 char *s = NULL; /* address and port logging */
586 int ti_locked;
604#define TI_UNLOCKED 1
605#define TI_RLOCKED 2
606
607#ifdef TCPDEBUG
608 /*
609 * The size of tcp_saveipgen must be the size of the max ip header,
610 * now IPv6.
611 */
612 u_char tcp_saveipgen[IP6_HDR_LEN];
613 struct tcphdr tcp_savetcp;
614 short ostate = 0;

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

1170 }
1171#endif
1172
1173 /*
1174 * Process the segment and the data it
1175 * contains. tcp_do_segment() consumes
1176 * the mbuf chain and unlocks the inpcb.
1177 */
587#ifdef TCPDEBUG
588 /*
589 * The size of tcp_saveipgen must be the size of the max ip header,
590 * now IPv6.
591 */
592 u_char tcp_saveipgen[IP6_HDR_LEN];
593 struct tcphdr tcp_savetcp;
594 short ostate = 0;

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

1150 }
1151#endif
1152
1153 /*
1154 * Process the segment and the data it
1155 * contains. tcp_do_segment() consumes
1156 * the mbuf chain and unlocks the inpcb.
1157 */
1178 tcp_do_segment(m, th, so, tp, drop_hdrlen, tlen,
1158 tp->t_fb->tfb_tcp_do_segment(m, th, so, tp, drop_hdrlen, tlen,
1179 iptos, ti_locked);
1180 INP_INFO_UNLOCK_ASSERT(&V_tcbinfo);
1181 return (IPPROTO_DONE);
1182 }
1183 /*
1184 * Segment flag validation for new connection attempts:
1185 *
1186 * Our (SYN|ACK) response was rejected.

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

1416
1417 TCP_PROBE5(receive, NULL, tp, mtod(m, const char *), tp, th);
1418
1419 /*
1420 * Segment belongs to a connection in SYN_SENT, ESTABLISHED or later
1421 * state. tcp_do_segment() always consumes the mbuf chain, unlocks
1422 * the inpcb, and unlocks pcbinfo.
1423 */
1159 iptos, ti_locked);
1160 INP_INFO_UNLOCK_ASSERT(&V_tcbinfo);
1161 return (IPPROTO_DONE);
1162 }
1163 /*
1164 * Segment flag validation for new connection attempts:
1165 *
1166 * Our (SYN|ACK) response was rejected.

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

1396
1397 TCP_PROBE5(receive, NULL, tp, mtod(m, const char *), tp, th);
1398
1399 /*
1400 * Segment belongs to a connection in SYN_SENT, ESTABLISHED or later
1401 * state. tcp_do_segment() always consumes the mbuf chain, unlocks
1402 * the inpcb, and unlocks pcbinfo.
1403 */
1424 tcp_do_segment(m, th, so, tp, drop_hdrlen, tlen, iptos, ti_locked);
1404 tp->t_fb->tfb_tcp_do_segment(m, th, so, tp, drop_hdrlen, tlen, iptos, ti_locked);
1425 INP_INFO_UNLOCK_ASSERT(&V_tcbinfo);
1426 return (IPPROTO_DONE);
1427
1428dropwithreset:
1429 TCP_PROBE5(receive, NULL, tp, mtod(m, const char *), tp, th);
1430
1431 if (ti_locked == TI_RLOCKED) {
1432 INP_INFO_RUNLOCK(&V_tcbinfo);

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

1471 INP_INFO_UNLOCK_ASSERT(&V_tcbinfo);
1472 if (s != NULL)
1473 free(s, M_TCPLOG);
1474 if (m != NULL)
1475 m_freem(m);
1476 return (IPPROTO_DONE);
1477}
1478
1405 INP_INFO_UNLOCK_ASSERT(&V_tcbinfo);
1406 return (IPPROTO_DONE);
1407
1408dropwithreset:
1409 TCP_PROBE5(receive, NULL, tp, mtod(m, const char *), tp, th);
1410
1411 if (ti_locked == TI_RLOCKED) {
1412 INP_INFO_RUNLOCK(&V_tcbinfo);

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

1451 INP_INFO_UNLOCK_ASSERT(&V_tcbinfo);
1452 if (s != NULL)
1453 free(s, M_TCPLOG);
1454 if (m != NULL)
1455 m_freem(m);
1456 return (IPPROTO_DONE);
1457}
1458
1479static void
1459void
1480tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
1481 struct tcpcb *tp, int drop_hdrlen, int tlen, uint8_t iptos,
1482 int ti_locked)
1483{
1484 int thflags, acked, ourfinisacked, needoutput = 0, sack_changed;
1485 int rstreason, todrop, win;
1486 u_long tiwin;
1487 char *s;

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

1783 mtod(m, const char *));
1784 if (tp->snd_una == tp->snd_max)
1785 tcp_timer_activate(tp, TT_REXMT, 0);
1786 else if (!tcp_timer_active(tp, TT_PERSIST))
1787 tcp_timer_activate(tp, TT_REXMT,
1788 tp->t_rxtcur);
1789 sowwakeup(so);
1790 if (sbavail(&so->so_snd))
1460tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
1461 struct tcpcb *tp, int drop_hdrlen, int tlen, uint8_t iptos,
1462 int ti_locked)
1463{
1464 int thflags, acked, ourfinisacked, needoutput = 0, sack_changed;
1465 int rstreason, todrop, win;
1466 u_long tiwin;
1467 char *s;

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

1763 mtod(m, const char *));
1764 if (tp->snd_una == tp->snd_max)
1765 tcp_timer_activate(tp, TT_REXMT, 0);
1766 else if (!tcp_timer_active(tp, TT_PERSIST))
1767 tcp_timer_activate(tp, TT_REXMT,
1768 tp->t_rxtcur);
1769 sowwakeup(so);
1770 if (sbavail(&so->so_snd))
1791 (void) tcp_output(tp);
1771 (void) tp->t_fb->tfb_tcp_output(tp);
1792 goto check_delack;
1793 }
1794 } else if (th->th_ack == tp->snd_una &&
1795 tlen <= sbspace(&so->so_rcv)) {
1796 int newsize = 0; /* automatic sockbuf scaling */
1797
1798 /*
1799 * This is a pure, in-sequence data packet with

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

1902 sbappendstream_locked(&so->so_rcv, m, 0);
1903 }
1904 /* NB: sorwakeup_locked() does an implicit unlock. */
1905 sorwakeup_locked(so);
1906 if (DELAY_ACK(tp, tlen)) {
1907 tp->t_flags |= TF_DELACK;
1908 } else {
1909 tp->t_flags |= TF_ACKNOW;
1772 goto check_delack;
1773 }
1774 } else if (th->th_ack == tp->snd_una &&
1775 tlen <= sbspace(&so->so_rcv)) {
1776 int newsize = 0; /* automatic sockbuf scaling */
1777
1778 /*
1779 * This is a pure, in-sequence data packet with

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

1882 sbappendstream_locked(&so->so_rcv, m, 0);
1883 }
1884 /* NB: sorwakeup_locked() does an implicit unlock. */
1885 sorwakeup_locked(so);
1886 if (DELAY_ACK(tp, tlen)) {
1887 tp->t_flags |= TF_DELACK;
1888 } else {
1889 tp->t_flags |= TF_ACKNOW;
1910 tcp_output(tp);
1890 tp->t_fb->tfb_tcp_output(tp);
1911 }
1912 goto check_delack;
1913 }
1914 }
1915
1916 /*
1917 * Calculate amount of space in receive window,
1918 * and then do TCP input processing.

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

2517
2518 if (awnd < tp->snd_ssthresh) {
2519 tp->snd_cwnd += tp->t_maxseg;
2520 if (tp->snd_cwnd > tp->snd_ssthresh)
2521 tp->snd_cwnd = tp->snd_ssthresh;
2522 }
2523 } else
2524 tp->snd_cwnd += tp->t_maxseg;
1891 }
1892 goto check_delack;
1893 }
1894 }
1895
1896 /*
1897 * Calculate amount of space in receive window,
1898 * and then do TCP input processing.

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

2497
2498 if (awnd < tp->snd_ssthresh) {
2499 tp->snd_cwnd += tp->t_maxseg;
2500 if (tp->snd_cwnd > tp->snd_ssthresh)
2501 tp->snd_cwnd = tp->snd_ssthresh;
2502 }
2503 } else
2504 tp->snd_cwnd += tp->t_maxseg;
2525 (void) tcp_output(tp);
2505 (void) tp->t_fb->tfb_tcp_output(tp);
2526 goto drop;
2527 } else if (tp->t_dupacks == tcprexmtthresh) {
2528 tcp_seq onxt = tp->snd_nxt;
2529
2530 /*
2531 * If we're doing sack, check to
2532 * see if we're already in sack
2533 * recovery. If we're not doing sack,

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

2551 cc_ack_received(tp, th, CC_DUPACK);
2552 tcp_timer_activate(tp, TT_REXMT, 0);
2553 tp->t_rtttime = 0;
2554 if (tp->t_flags & TF_SACK_PERMIT) {
2555 TCPSTAT_INC(
2556 tcps_sack_recovery_episode);
2557 tp->sack_newdata = tp->snd_nxt;
2558 tp->snd_cwnd = tp->t_maxseg;
2506 goto drop;
2507 } else if (tp->t_dupacks == tcprexmtthresh) {
2508 tcp_seq onxt = tp->snd_nxt;
2509
2510 /*
2511 * If we're doing sack, check to
2512 * see if we're already in sack
2513 * recovery. If we're not doing sack,

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

2531 cc_ack_received(tp, th, CC_DUPACK);
2532 tcp_timer_activate(tp, TT_REXMT, 0);
2533 tp->t_rtttime = 0;
2534 if (tp->t_flags & TF_SACK_PERMIT) {
2535 TCPSTAT_INC(
2536 tcps_sack_recovery_episode);
2537 tp->sack_newdata = tp->snd_nxt;
2538 tp->snd_cwnd = tp->t_maxseg;
2559 (void) tcp_output(tp);
2539 (void) tp->t_fb->tfb_tcp_output(tp);
2560 goto drop;
2561 }
2562 tp->snd_nxt = th->th_ack;
2563 tp->snd_cwnd = tp->t_maxseg;
2540 goto drop;
2541 }
2542 tp->snd_nxt = th->th_ack;
2543 tp->snd_cwnd = tp->t_maxseg;
2564 (void) tcp_output(tp);
2544 (void) tp->t_fb->tfb_tcp_output(tp);
2565 KASSERT(tp->snd_limited <= 2,
2566 ("%s: tp->snd_limited too big",
2567 __func__));
2568 tp->snd_cwnd = tp->snd_ssthresh +
2569 tp->t_maxseg *
2570 (tp->t_dupacks - tp->snd_limited);
2571 if (SEQ_GT(onxt, tp->snd_nxt))
2572 tp->snd_nxt = onxt;

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

2603 * is new data available to be sent.
2604 * Otherwise we would send pure ACKs.
2605 */
2606 SOCKBUF_LOCK(&so->so_snd);
2607 avail = sbavail(&so->so_snd) -
2608 (tp->snd_nxt - tp->snd_una);
2609 SOCKBUF_UNLOCK(&so->so_snd);
2610 if (avail > 0)
2545 KASSERT(tp->snd_limited <= 2,
2546 ("%s: tp->snd_limited too big",
2547 __func__));
2548 tp->snd_cwnd = tp->snd_ssthresh +
2549 tp->t_maxseg *
2550 (tp->t_dupacks - tp->snd_limited);
2551 if (SEQ_GT(onxt, tp->snd_nxt))
2552 tp->snd_nxt = onxt;

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

2583 * is new data available to be sent.
2584 * Otherwise we would send pure ACKs.
2585 */
2586 SOCKBUF_LOCK(&so->so_snd);
2587 avail = sbavail(&so->so_snd) -
2588 (tp->snd_nxt - tp->snd_una);
2589 SOCKBUF_UNLOCK(&so->so_snd);
2590 if (avail > 0)
2611 (void) tcp_output(tp);
2591 (void) tp->t_fb->tfb_tcp_output(tp);
2612 sent = tp->snd_max - oldsndmax;
2613 if (sent > tp->t_maxseg) {
2614 KASSERT((tp->t_dupacks == 2 &&
2615 tp->snd_limited == 0) ||
2616 (sent == tp->t_maxseg + 1 &&
2617 tp->t_flags & TF_SENTFIN),
2618 ("%s: sent too much",
2619 __func__));

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

3069 &tcp_savetcp, 0);
3070#endif
3071 TCP_PROBE3(debug__input, tp, th, mtod(m, const char *));
3072
3073 /*
3074 * Return any desired output.
3075 */
3076 if (needoutput || (tp->t_flags & TF_ACKNOW))
2592 sent = tp->snd_max - oldsndmax;
2593 if (sent > tp->t_maxseg) {
2594 KASSERT((tp->t_dupacks == 2 &&
2595 tp->snd_limited == 0) ||
2596 (sent == tp->t_maxseg + 1 &&
2597 tp->t_flags & TF_SENTFIN),
2598 ("%s: sent too much",
2599 __func__));

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

3049 &tcp_savetcp, 0);
3050#endif
3051 TCP_PROBE3(debug__input, tp, th, mtod(m, const char *));
3052
3053 /*
3054 * Return any desired output.
3055 */
3056 if (needoutput || (tp->t_flags & TF_ACKNOW))
3077 (void) tcp_output(tp);
3057 (void) tp->t_fb->tfb_tcp_output(tp);
3078
3079check_delack:
3080 KASSERT(ti_locked == TI_UNLOCKED, ("%s: check_delack ti_locked %d",
3081 __func__, ti_locked));
3082 INP_INFO_UNLOCK_ASSERT(&V_tcbinfo);
3083 INP_WLOCK_ASSERT(tp->t_inpcb);
3084
3085 if (tp->t_flags & TF_DELACK) {

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

3117 &tcp_savetcp, 0);
3118#endif
3119 TCP_PROBE3(debug__input, tp, th, mtod(m, const char *));
3120 if (ti_locked == TI_RLOCKED)
3121 INP_INFO_RUNLOCK(&V_tcbinfo);
3122 ti_locked = TI_UNLOCKED;
3123
3124 tp->t_flags |= TF_ACKNOW;
3058
3059check_delack:
3060 KASSERT(ti_locked == TI_UNLOCKED, ("%s: check_delack ti_locked %d",
3061 __func__, ti_locked));
3062 INP_INFO_UNLOCK_ASSERT(&V_tcbinfo);
3063 INP_WLOCK_ASSERT(tp->t_inpcb);
3064
3065 if (tp->t_flags & TF_DELACK) {

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

3097 &tcp_savetcp, 0);
3098#endif
3099 TCP_PROBE3(debug__input, tp, th, mtod(m, const char *));
3100 if (ti_locked == TI_RLOCKED)
3101 INP_INFO_RUNLOCK(&V_tcbinfo);
3102 ti_locked = TI_UNLOCKED;
3103
3104 tp->t_flags |= TF_ACKNOW;
3125 (void) tcp_output(tp);
3105 (void) tp->t_fb->tfb_tcp_output(tp);
3126 INP_WUNLOCK(tp->t_inpcb);
3127 m_freem(m);
3128 return;
3129
3130dropwithreset:
3131 if (ti_locked == TI_RLOCKED)
3132 INP_INFO_RUNLOCK(&V_tcbinfo);
3133 ti_locked = TI_UNLOCKED;

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

3163 m_freem(m);
3164}
3165
3166/*
3167 * Issue RST and make ACK acceptable to originator of segment.
3168 * The mbuf must still include the original packet header.
3169 * tp may be NULL.
3170 */
3106 INP_WUNLOCK(tp->t_inpcb);
3107 m_freem(m);
3108 return;
3109
3110dropwithreset:
3111 if (ti_locked == TI_RLOCKED)
3112 INP_INFO_RUNLOCK(&V_tcbinfo);
3113 ti_locked = TI_UNLOCKED;

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

3143 m_freem(m);
3144}
3145
3146/*
3147 * Issue RST and make ACK acceptable to originator of segment.
3148 * The mbuf must still include the original packet header.
3149 * tp may be NULL.
3150 */
3171static void
3151void
3172tcp_dropwithreset(struct mbuf *m, struct tcphdr *th, struct tcpcb *tp,
3173 int tlen, int rstreason)
3174{
3175#ifdef INET
3176 struct ip *ip;
3177#endif
3178#ifdef INET6
3179 struct ip6_hdr *ip6;

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

3226 return;
3227drop:
3228 m_freem(m);
3229}
3230
3231/*
3232 * Parse TCP options and place in tcpopt.
3233 */
3152tcp_dropwithreset(struct mbuf *m, struct tcphdr *th, struct tcpcb *tp,
3153 int tlen, int rstreason)
3154{
3155#ifdef INET
3156 struct ip *ip;
3157#endif
3158#ifdef INET6
3159 struct ip6_hdr *ip6;

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

3206 return;
3207drop:
3208 m_freem(m);
3209}
3210
3211/*
3212 * Parse TCP options and place in tcpopt.
3213 */
3234static void
3214void
3235tcp_dooptions(struct tcpopt *to, u_char *cp, int cnt, int flags)
3236{
3237 int opt, optlen;
3238
3239 to->to_flags = 0;
3240 for (; cnt > 0; cnt -= optlen, cp += optlen) {
3241 opt = cp[0];
3242 if (opt == TCPOPT_EOL)

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

3320}
3321
3322/*
3323 * Pull out of band byte out of a segment so
3324 * it doesn't appear in the user's data queue.
3325 * It is still reflected in the segment length for
3326 * sequencing purposes.
3327 */
3215tcp_dooptions(struct tcpopt *to, u_char *cp, int cnt, int flags)
3216{
3217 int opt, optlen;
3218
3219 to->to_flags = 0;
3220 for (; cnt > 0; cnt -= optlen, cp += optlen) {
3221 opt = cp[0];
3222 if (opt == TCPOPT_EOL)

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

3300}
3301
3302/*
3303 * Pull out of band byte out of a segment so
3304 * it doesn't appear in the user's data queue.
3305 * It is still reflected in the segment length for
3306 * sequencing purposes.
3307 */
3328static void
3308void
3329tcp_pulloutofband(struct socket *so, struct tcphdr *th, struct mbuf *m,
3330 int off)
3331{
3332 int cnt = off + th->th_urp - 1;
3333
3334 while (cnt >= 0) {
3335 if (m->m_len > cnt) {
3336 char *cp = mtod(m, caddr_t) + cnt;

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

3353 }
3354 panic("tcp_pulloutofband");
3355}
3356
3357/*
3358 * Collect new round-trip time estimate
3359 * and update averages and current timeout.
3360 */
3309tcp_pulloutofband(struct socket *so, struct tcphdr *th, struct mbuf *m,
3310 int off)
3311{
3312 int cnt = off + th->th_urp - 1;
3313
3314 while (cnt >= 0) {
3315 if (m->m_len > cnt) {
3316 char *cp = mtod(m, caddr_t) + cnt;

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

3333 }
3334 panic("tcp_pulloutofband");
3335}
3336
3337/*
3338 * Collect new round-trip time estimate
3339 * and update averages and current timeout.
3340 */
3361static void
3341void
3362tcp_xmit_timer(struct tcpcb *tp, int rtt)
3363{
3364 int delta;
3365
3366 INP_WLOCK_ASSERT(tp->t_inpcb);
3367
3368 TCPSTAT_INC(tcps_rttupdated);
3369 tp->t_rttupdated++;

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

3733
3734
3735/*
3736 * On a partial ack arrives, force the retransmission of the
3737 * next unacknowledged segment. Do not clear tp->t_dupacks.
3738 * By setting snd_nxt to ti_ack, this forces retransmission timer to
3739 * be started again.
3740 */
3342tcp_xmit_timer(struct tcpcb *tp, int rtt)
3343{
3344 int delta;
3345
3346 INP_WLOCK_ASSERT(tp->t_inpcb);
3347
3348 TCPSTAT_INC(tcps_rttupdated);
3349 tp->t_rttupdated++;

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

3713
3714
3715/*
3716 * On a partial ack arrives, force the retransmission of the
3717 * next unacknowledged segment. Do not clear tp->t_dupacks.
3718 * By setting snd_nxt to ti_ack, this forces retransmission timer to
3719 * be started again.
3720 */
3741static void
3721void
3742tcp_newreno_partial_ack(struct tcpcb *tp, struct tcphdr *th)
3743{
3744 tcp_seq onxt = tp->snd_nxt;
3745 u_long ocwnd = tp->snd_cwnd;
3746
3747 INP_WLOCK_ASSERT(tp->t_inpcb);
3748
3749 tcp_timer_activate(tp, TT_REXMT, 0);
3750 tp->t_rtttime = 0;
3751 tp->snd_nxt = th->th_ack;
3752 /*
3753 * Set snd_cwnd to one segment beyond acknowledged offset.
3754 * (tp->snd_una has not yet been updated when this function is called.)
3755 */
3756 tp->snd_cwnd = tp->t_maxseg + BYTES_THIS_ACK(tp, th);
3757 tp->t_flags |= TF_ACKNOW;
3722tcp_newreno_partial_ack(struct tcpcb *tp, struct tcphdr *th)
3723{
3724 tcp_seq onxt = tp->snd_nxt;
3725 u_long ocwnd = tp->snd_cwnd;
3726
3727 INP_WLOCK_ASSERT(tp->t_inpcb);
3728
3729 tcp_timer_activate(tp, TT_REXMT, 0);
3730 tp->t_rtttime = 0;
3731 tp->snd_nxt = th->th_ack;
3732 /*
3733 * Set snd_cwnd to one segment beyond acknowledged offset.
3734 * (tp->snd_una has not yet been updated when this function is called.)
3735 */
3736 tp->snd_cwnd = tp->t_maxseg + BYTES_THIS_ACK(tp, th);
3737 tp->t_flags |= TF_ACKNOW;
3758 (void) tcp_output(tp);
3738 (void) tp->t_fb->tfb_tcp_output(tp);
3759 tp->snd_cwnd = ocwnd;
3760 if (SEQ_GT(onxt, tp->snd_nxt))
3761 tp->snd_nxt = onxt;
3762 /*
3763 * Partial window deflation. Relies on fact that tp->snd_una
3764 * not updated yet.
3765 */
3766 if (tp->snd_cwnd > BYTES_THIS_ACK(tp, th))

--- 13 unchanged lines hidden ---
3739 tp->snd_cwnd = ocwnd;
3740 if (SEQ_GT(onxt, tp->snd_nxt))
3741 tp->snd_nxt = onxt;
3742 /*
3743 * Partial window deflation. Relies on fact that tp->snd_una
3744 * not updated yet.
3745 */
3746 if (tp->snd_cwnd > BYTES_THIS_ACK(tp, th))

--- 13 unchanged lines hidden ---