Loading...
   1
   2
   3
   4
   5
   6
   7
   8
   9
  10
  11
  12
  13
  14
  15
  16
  17
  18
  19
  20
  21
  22
  23
  24
  25
  26
  27
  28
  29
  30
  31
  32
  33
  34
  35
  36
  37
  38
  39
  40
  41
  42
  43
  44
  45
  46
  47
  48
  49
  50
  51
  52
  53
  54
  55
  56
  57
  58
  59
  60
  61
  62
  63
  64
  65
  66
  67
  68
  69
  70
  71
  72
  73
  74
  75
  76
  77
  78
  79
  80
  81
  82
  83
  84
  85
  86
  87
  88
  89
  90
  91
  92
  93
  94
  95
  96
  97
  98
  99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 167
 168
 169
 170
 171
 172
 173
 174
 175
 176
 177
 178
 179
 180
 181
 182
 183
 184
 185
 186
 187
 188
 189
 190
 191
 192
 193
 194
 195
 196
 197
 198
 199
 200
 201
 202
 203
 204
 205
 206
 207
 208
 209
 210
 211
 212
 213
 214
 215
 216
 217
 218
 219
 220
 221
 222
 223
 224
 225
 226
 227
 228
 229
 230
 231
 232
 233
 234
 235
 236
 237
 238
 239
 240
 241
 242
 243
 244
 245
 246
 247
 248
 249
 250
 251
 252
 253
 254
 255
 256
 257
 258
 259
 260
 261
 262
 263
 264
 265
 266
 267
 268
 269
 270
 271
 272
 273
 274
 275
 276
 277
 278
 279
 280
 281
 282
 283
 284
 285
 286
 287
 288
 289
 290
 291
 292
 293
 294
 295
 296
 297
 298
 299
 300
 301
 302
 303
 304
 305
 306
 307
 308
 309
 310
 311
 312
 313
 314
 315
 316
 317
 318
 319
 320
 321
 322
 323
 324
 325
 326
 327
 328
 329
 330
 331
 332
 333
 334
 335
 336
 337
 338
 339
 340
 341
 342
 343
 344
 345
 346
 347
 348
 349
 350
 351
 352
 353
 354
 355
 356
 357
 358
 359
 360
 361
 362
 363
 364
 365
 366
 367
 368
 369
 370
 371
 372
 373
 374
 375
 376
 377
 378
 379
 380
 381
 382
 383
 384
 385
 386
 387
 388
 389
 390
 391
 392
 393
 394
 395
 396
 397
 398
 399
 400
 401
 402
 403
 404
 405
 406
 407
 408
 409
 410
 411
 412
 413
 414
 415
 416
 417
 418
 419
 420
 421
 422
 423
 424
 425
 426
 427
 428
 429
 430
 431
 432
 433
 434
 435
 436
 437
 438
 439
 440
 441
 442
 443
 444
 445
 446
 447
 448
 449
 450
 451
 452
 453
 454
 455
 456
 457
 458
 459
 460
 461
 462
 463
 464
 465
 466
 467
 468
 469
 470
 471
 472
 473
 474
 475
 476
 477
 478
 479
 480
 481
 482
 483
 484
 485
 486
 487
 488
 489
 490
 491
 492
 493
 494
 495
 496
 497
 498
 499
 500
 501
 502
 503
 504
 505
 506
 507
 508
 509
 510
 511
 512
 513
 514
 515
 516
 517
 518
 519
 520
 521
 522
 523
 524
 525
 526
 527
 528
 529
 530
 531
 532
 533
 534
 535
 536
 537
 538
 539
 540
 541
 542
 543
 544
 545
 546
 547
 548
 549
 550
 551
 552
 553
 554
 555
 556
 557
 558
 559
 560
 561
 562
 563
 564
 565
 566
 567
 568
 569
 570
 571
 572
 573
 574
 575
 576
 577
 578
 579
 580
 581
 582
 583
 584
 585
 586
 587
 588
 589
 590
 591
 592
 593
 594
 595
 596
 597
 598
 599
 600
 601
 602
 603
 604
 605
 606
 607
 608
 609
 610
 611
 612
 613
 614
 615
 616
 617
 618
 619
 620
 621
 622
 623
 624
 625
 626
 627
 628
 629
 630
 631
 632
 633
 634
 635
 636
 637
 638
 639
 640
 641
 642
 643
 644
 645
 646
 647
 648
 649
 650
 651
 652
 653
 654
 655
 656
 657
 658
 659
 660
 661
 662
 663
 664
 665
 666
 667
 668
 669
 670
 671
 672
 673
 674
 675
 676
 677
 678
 679
 680
 681
 682
 683
 684
 685
 686
 687
 688
 689
 690
 691
 692
 693
 694
 695
 696
 697
 698
 699
 700
 701
 702
 703
 704
 705
 706
 707
 708
 709
 710
 711
 712
 713
 714
 715
 716
 717
 718
 719
 720
 721
 722
 723
 724
 725
 726
 727
 728
 729
 730
 731
 732
 733
 734
 735
 736
 737
 738
 739
 740
 741
 742
 743
 744
 745
 746
 747
 748
 749
 750
 751
 752
 753
 754
 755
 756
 757
 758
 759
 760
 761
 762
 763
 764
 765
 766
 767
 768
 769
 770
 771
 772
 773
 774
 775
 776
 777
 778
 779
 780
 781
 782
 783
 784
 785
 786
 787
 788
 789
 790
 791
 792
 793
 794
 795
 796
 797
 798
 799
 800
 801
 802
 803
 804
 805
 806
 807
 808
 809
 810
 811
 812
 813
 814
 815
 816
 817
 818
 819
 820
 821
 822
 823
 824
 825
 826
 827
 828
 829
 830
 831
 832
 833
 834
 835
 836
 837
 838
 839
 840
 841
 842
 843
 844
 845
 846
 847
 848
 849
 850
 851
 852
 853
 854
 855
 856
 857
 858
 859
 860
 861
 862
 863
 864
 865
 866
 867
 868
 869
 870
 871
 872
 873
 874
 875
 876
 877
 878
 879
 880
 881
 882
 883
 884
 885
 886
 887
 888
 889
 890
 891
 892
 893
 894
 895
 896
 897
 898
 899
 900
 901
 902
 903
 904
 905
 906
 907
 908
 909
 910
 911
 912
 913
 914
 915
 916
 917
 918
 919
 920
 921
 922
 923
 924
 925
 926
 927
 928
 929
 930
 931
 932
 933
 934
 935
 936
 937
 938
 939
 940
 941
 942
 943
 944
 945
 946
 947
 948
 949
 950
 951
 952
 953
 954
 955
 956
 957
 958
 959
 960
 961
 962
 963
 964
 965
 966
 967
 968
 969
 970
 971
 972
 973
 974
 975
 976
 977
 978
 979
 980
 981
 982
 983
 984
 985
 986
 987
 988
 989
 990
 991
 992
 993
 994
 995
 996
 997
 998
 999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
/*
 * Copyright (c) 2000-2020 Apple Inc. All rights reserved.
 *
 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
 *
 * This file contains Original Code and/or Modifications of Original Code
 * as defined in and that are subject to the Apple Public Source License
 * Version 2.0 (the 'License'). You may not use this file except in
 * compliance with the License. The rights granted to you under the License
 * may not be used to create, or enable the creation or redistribution of,
 * unlawful or unlicensed copies of an Apple operating system, or to
 * circumvent, violate, or enable the circumvention or violation of, any
 * terms of an Apple operating system software license agreement.
 *
 * Please obtain a copy of the License at
 * http://www.opensource.apple.com/apsl/ and read it before using this file.
 *
 * The Original Code and all software distributed under the License are
 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
 * Please see the License for the specific language governing rights and
 * limitations under the License.
 *
 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
 */
/*
 * Copyright (c) 1982, 1986, 1993, 1994, 1995
 *	The Regents of the University of California.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by the University of
 *	California, Berkeley and its contributors.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *	@(#)tcp_var.h	8.4 (Berkeley) 5/24/95
 * $FreeBSD: src/sys/netinet/tcp_var.h,v 1.56.2.8 2001/08/22 00:59:13 silby Exp $
 */

#ifndef _NETINET_TCP_VAR_H_
#define _NETINET_TCP_VAR_H_
#include <sys/types.h>
#include <sys/appleapiopts.h>
#include <sys/queue.h>
#include <netinet/in_pcb.h>
#include <netinet/tcp.h>
#include <netinet/tcp_timer.h>

#if defined(__LP64__)
#define _TCPCB_PTR(x)                   u_int32_t
#define _TCPCB_LIST_HEAD(name, type)    \
struct name {                           \
	u_int32_t	lh_first;       \
}
#else
#define _TCPCB_PTR(x)                   x
#define _TCPCB_LIST_HEAD(name, type)    LIST_HEAD(name, type)
#endif

#ifdef KERNEL_PRIVATE

#define TCP_RETRANSHZ   1000    /* granularity of TCP timestamps, 1ms */
/* Minimum time quantum within which the timers are coalesced */
#define TCP_TIMER_10MS_QUANTUM  (TCP_RETRANSHZ/100) /* every 10ms */
#define TCP_TIMER_100MS_QUANTUM   (TCP_RETRANSHZ/10) /* every 100ms */
#define TCP_TIMER_500MS_QUANTUM   (TCP_RETRANSHZ/2) /* every 500ms */

#define TCP_RETRANSHZ_TO_USEC 1000

#define N_TIME_WAIT_SLOTS   128         /* must be power of 2 */

/* Always allow at least 16 packets worth of recv window when adjusting
 * recv window using inter-packet arrival jitter.
 */
#define MIN_IAJ_WIN 16

/* A variation in delay of this many milliseconds is tolerable. This limit has to
 * be low but greater than zero. We also use standard deviation on jitter to adjust
 * this limit for different link and connection types.
 */
#define ALLOWED_IAJ 5

/* Ignore the first few packets on a connection until the ACK clock gets going
 */
#define IAJ_IGNORE_PKTCNT 40

/* Let the accumulated IAJ value increase by this threshold at most. This limit
 * will control how many ALLOWED_IAJ measurements a receiver will have to see
 * before opening the receive window
 */
#define ACC_IAJ_HIGH_THRESH 100

/* When accumulated IAJ reaches this value, the receiver starts to react by
 * closing the window
 */
#define ACC_IAJ_REACT_LIMIT 200

/* If the number of small packets (smaller than IAJ packet size) seen on a
 * connection is more than this threshold, reset the size and learn it again.
 * This is needed because the sender might send smaller segments after PMTU
 * discovery and the receiver has to learn the new size.
 */
#define RESET_IAJ_SIZE_THRESH 20

/*
 * Adaptive timeout is a read/write timeout specified by the application to
 * get a socket event when the transport layer detects a stall in data
 * transfer. The value specified is the number of probes that can be sent
 * to the peer before generating an event. Since it is not specified as
 * a time value, the timeout will adjust based on the RTT seen on the link.
 * The timeout will start only when there is an indication that the read/write
 * operation is not making progress.
 *
 * If a write operation stalls, the probe will be retransmission of data.
 * If a read operation stalls, the probe will be a keep-alive packet.
 *
 * The maximum value of adaptive timeout is set to 10 which will allow
 * transmission of enough number of probes to the peer.
 */
#define TCP_ADAPTIVE_TIMEOUT_MAX        10

#define TCP_CONNECTIVITY_PROBES_MAX     5

/*
 * Kernel variables for tcp.
 */

/* TCP segment queue entry */
struct tseg_qent {
	LIST_ENTRY(tseg_qent) tqe_q;
	int     tqe_len;                /* TCP segment data length */
	struct  tcphdr *tqe_th;         /* a pointer to tcp header */
	struct  mbuf    *tqe_m;         /* mbuf contains packet */
};
LIST_HEAD(tsegqe_head, tseg_qent);

struct sackblk {
	tcp_seq start;          /* start seq no. of sack block */
	tcp_seq end;            /* end seq no. */
};

struct sackhole {
	tcp_seq start;          /* start seq no. of hole */
	tcp_seq end;            /* end seq no. */
	tcp_seq rxmit;          /* next seq. no in hole to be retransmitted */
	u_int32_t rxmit_start;  /* timestamp of first retransmission */
	TAILQ_ENTRY(sackhole) scblink;  /* scoreboard linkage */
};

struct sackhint {
	struct sackhole *nexthole;
	int     sack_bytes_rexmit;
	int sack_bytes_acked;
};

struct tcp_rxt_seg {
	tcp_seq rx_start;
	tcp_seq rx_end;
	u_int16_t rx_count;
	u_int16_t rx_flags;
#define TCP_RXT_SPURIOUS        0x1     /* received DSACK notification */
#define TCP_RXT_DSACK_FOR_TLP   0x2
	SLIST_ENTRY(tcp_rxt_seg) rx_link;
};

struct tcp_notify_ack_marker {
	tcp_seq notify_snd_una; /* Notify when snd_una crosses this seq */
	tcp_notify_ack_id_t notify_id;
	SLIST_ENTRY(tcp_notify_ack_marker) notify_next;
};

struct tcptemp {
	u_char  tt_ipgen[40]; /* the size must be of max ip header, now IPv6 */
	struct  tcphdr tt_t;
};

struct bwmeas {
	tcp_seq bw_start;       /* start of bw measurement */
	uint32_t bw_ts;         /* timestamp when bw measurement started */
	uint32_t bw_size;       /* burst size in bytes for this bw measurement */
	uint32_t bw_minsizepkts; /* Min burst size as segments */
	uint32_t bw_maxsizepkts; /* Max burst size as segments */
	uint32_t bw_minsize;    /* Min size in bytes */
	uint32_t bw_maxsize;    /* Max size in bytes */
	uint32_t bw_sndbw;      /* Measured send bandwidth */
	uint32_t bw_sndbw_max;  /* Max measured bandwidth */
	uint32_t bw_rcvbw_max;  /* Max receive bandwidth measured */
};

/* MPTCP Data sequence map entry */
struct mpt_dsn_map {
	uint64_t                mpt_dsn;        /* data seq num recvd */
	uint32_t                mpt_sseq;       /* relative subflow # */
	uint16_t                mpt_len;        /* length of mapping */
	uint16_t                mpt_csum;       /* checksum value if on */
	uint8_t                 mpt_dfin;       /* It's a DATA_FIN */
};
#define tcp6cb          tcpcb  /* for KAME src sync over BSD*'s */

struct tcp_ccstate {
	union {
		struct tcp_cubic_state {
			u_int32_t tc_last_max;  /* cwnd at last loss */
			u_int32_t tc_epoch_start; /* TS of last loss */
			u_int32_t tc_origin_point; /* window at the start of an epoch */
			u_int32_t tc_tcp_win; /* computed tcp win */
			u_int32_t tc_tcp_bytes_acked; /* bytes acked */
			u_int32_t tc_avg_lastmax; /* Average of last max */
			u_int32_t tc_mean_deviation; /* Mean absolute deviation */
			float     tc_epoch_period; /* K parameter */
		} _cubic_state_;
#define cub_last_max __u__._cubic_state_.tc_last_max
#define cub_epoch_start __u__._cubic_state_.tc_epoch_start
#define cub_origin_point __u__._cubic_state_.tc_origin_point
#define cub_tcp_win __u__._cubic_state_.tc_tcp_win
#define cub_tcp_bytes_acked __u__._cubic_state_.tc_tcp_bytes_acked
#define cub_epoch_period __u__._cubic_state_.tc_epoch_period
#define cub_avg_lastmax __u__._cubic_state_.tc_avg_lastmax
#define cub_mean_dev __u__._cubic_state_.tc_mean_deviation
	} __u__;
};

/*
 * Tcp control block, one per tcp; fields:
 * Organized for 16 byte cacheline efficiency.
 */
struct tcpcb {
	struct  tsegqe_head t_segq;
	int     t_dupacks;              /* consecutive dup acks recd */
	int     t_state;                /* state of this connection */
	uint32_t t_timer[TCPT_NTIMERS]; /* tcp timers */
	struct tcptimerentry tentry;    /* entry in timer list */

	struct  inpcb *t_inpcb;         /* back pointer to internet pcb */
	uint32_t        t_flags;
#define TF_ACKNOW       0x00001         /* ack peer immediately */
#define TF_DELACK       0x00002         /* ack, but try to delay it */
#define TF_NODELAY      0x00004         /* don't delay packets to coalesce */
#define TF_NOOPT        0x00008         /* don't use tcp options */
#define TF_SENTFIN      0x00010         /* have sent FIN */
#define TF_REQ_SCALE    0x00020         /* have/will request window scaling */
#define TF_RCVD_SCALE   0x00040         /* other side has requested scaling */
#define TF_REQ_TSTMP    0x00080         /* have/will request timestamps */
#define TF_RCVD_TSTMP   0x00100         /* a timestamp was received in SYN */
#define TF_SACK_PERMIT  0x00200         /* other side said I could SACK */
#define TF_NEEDSYN      0x00400         /* send SYN (implicit state) - unused but needed for backwards compatibility */
#define TF_NEEDFIN      0x00800         /* send FIN (implicit state) */
#define TF_NOPUSH       0x01000         /* don't push */
#define TF_REQ_CC       0x02000         /* have/will request CC */
#define TF_RCVD_CC      0x04000         /* a CC was received in SYN */
#define TF_SENDCCNEW    0x08000         /* Unused */
#define TF_MORETOCOME   0x10000         /* More data to be appended to sock */
#define TF_LOCAL        0x20000         /* connection to a host on local link */
#define TF_RXWIN0SENT   0x40000         /* sent a receiver win 0 in response */
#define TF_SLOWLINK     0x80000         /* route is a on a modem speed link */
#define TF_LASTIDLE     0x100000        /* connection was previously idle */
#define TF_FASTRECOVERY 0x200000        /* in NewReno Fast Recovery */
#define TF_WASFRECOVERY 0x400000        /* was in NewReno Fast Recovery */
#define TF_SIGNATURE    0x800000        /* require MD5 digests (RFC2385) */
#define TF_MAXSEGSNT    0x1000000       /* last segment sent was a full segment */
#define TF_STREAMING_ON 0x2000000       /* Receiver detected streaming */
#define TF_PMTUD        0x4000000       /* Perform Path MTU Discovery for this connection */
#define TF_CLOSING      0x8000000       /* pending tcp close */
#define TF_TSO          0x10000000      /* TCP Segment Offloading is enable on this connection */
#define TF_BLACKHOLE    0x20000000      /* Path MTU Discovery Black Hole detection */
#define TF_TIMER_ONLIST 0x40000000      /* pcb is on tcp_timer_list */
#define TF_STRETCHACK   0x80000000      /* receiver is going to delay acks */

	tcp_seq snd_una;                /* send unacknowledged */
	tcp_seq snd_max;                /* highest sequence number sent;
	                                 * used to recognize retransmits
	                                 */
	tcp_seq snd_nxt;                /* send next */
	tcp_seq snd_up;                 /* send urgent pointer */

	tcp_seq snd_wl1;                /* window update seg seq number */
	tcp_seq snd_wl2;                /* window update seg ack number */
	tcp_seq iss;                    /* initial send sequence number */
	tcp_seq irs;                    /* initial receive sequence number */

	tcp_seq rcv_nxt;                /* receive next */
	tcp_seq rcv_adv;                /* advertised window */
	uint32_t        rcv_wnd;        /* receive window */
	uint32_t        t_last_recwin;
	tcp_seq rcv_up;                 /* receive urgent pointer */

	uint32_t        snd_wnd;        /* send window */
	uint32_t        snd_cwnd;       /* congestion-controlled window */
	uint32_t        snd_ssthresh;   /* snd_cwnd size threshold for
	                                 * for slow start exponential to
	                                 * linear switch
	                                 */
	tcp_seq snd_recover;            /* for use in NewReno Fast Recovery */

	uint32_t        t_maxopd;       /* mss plus options */
	uint32_t        t_rcvtime;      /* time at which a packet was received */
	uint32_t        t_sndtime;      /* time at which we last sent new data */
	uint32_t        t_starttime;    /* time connection was established */
	int     t_rtttime;              /* tcp clock when rtt calculation was started */
	tcp_seq t_rtseq;                /* sequence number being timed */

	uint32_t rfbuf_ts;              /* recv buffer autoscaling timestamp */
	uint32_t rfbuf_cnt;             /* recv buffer autoscaling byte count */
	uint32_t rfbuf_space;           /* Current "ideal" estimate of the space */

	int            t_rxtcur;        /* current retransmit value (ticks) */
	unsigned int   t_maxseg;        /* maximum segment size */
	int            t_srtt;          /* smoothed round-trip time */
	int            t_rttvar;        /* variance in round-trip time */

	uint64_t t_accsleep_ms;         /* accumulated sleep time since last boot */
	uint16_t t_reassqlen;           /* length of reassembly queue */
	uint16_t t_rxtshift;            /* log(2) of rexmt exp. backoff */
	uint32_t t_rttmin;              /* minimum rtt allowed */
	uint32_t t_rttbest;             /* best rtt we've seen */
	uint32_t t_rttcur;              /* most recent value of rtt */
	uint32_t t_rttupdated;          /* number of times rtt sampled */
	uint32_t t_rxt_conndroptime;    /* retxmt conn gets dropped after this time, when set */
	uint32_t t_rxtstart;            /* time at which retransmission started */
	uint32_t max_sndwnd;            /* largest window peer has offered */

	int     t_softerror;            /* possible error not yet reported */
/* out-of-band data */
	char    t_oobflags;             /* have some */
	char    t_iobc;                 /* input character */
#define TCPOOB_HAVEDATA 0x01
#define TCPOOB_HADDATA  0x02
/* RFC 1323 variables */
	u_int8_t        snd_scale;      /* window scaling for send window */
	u_int8_t        rcv_scale;      /* window scaling for recv window */
	u_int8_t        request_r_scale; /* pending window scaling */
	u_int8_t        requested_s_scale;
	u_int8_t        tcp_cc_index;   /* index of congestion control algorithm */
	u_int8_t        t_adaptive_rtimo;       /* Read timeout used as a multiple of RTT */
	u_int8_t        t_adaptive_wtimo;       /* Write timeout used as a multiple of RTT */
	u_int8_t        t_stretchack_delayed;   /* stretch ack delayed */

/* State for limiting early retransmits when SACK is not enabled */
	u_int16_t       t_early_rexmt_count; /* count of early rexmts */
	u_int32_t       t_early_rexmt_win; /* window for limiting early rexmts */

	u_int32_t       ts_recent;      /* timestamp echo data */

	u_int32_t       ts_recent_age;  /* when last updated */
	tcp_seq last_ack_sent;
/* RFC 3465 variables */
	u_int32_t       t_bytes_acked;  /* ABC "bytes_acked" parameter */

	int             t_lastchain;    /* amount of packets chained last time around */
	uint16_t        t_unacksegs;    /* received but unacked segments for delaying acks */

	/*
	 * Pretty arbitrary value ;-)
	 * Goal is to make sure that some ACKs are being sent more frequently
	 * to allow the other side to ramp-up.
	 */
#define TCP_FORCED_ACKS_COUNT 16
	uint16_t        t_forced_acks;  /* count of pure ACKs that need to be forced out */
	uint8_t         t_rexmtthresh;  /* duplicate ack threshold for entering fast recovery */
	uint8_t         t_rtimo_probes; /* number of adaptive rtimo probes sent */
	uint32_t        t_persist_timeout; /* ZWP persistence limit as set by PERSIST_TIMEOUT */
	uint32_t        t_persist_stop;    /* persistence limit deadline if triggered by ZWP */
	uint32_t        t_notsent_lowat;   /* Low water for not sent data */

/* Receiver state for stretch-ack algorithm */
	u_int32_t       rcv_unackwin;   /* to measure win for stretching acks */
	u_int32_t       rcv_by_unackwin; /* bytes seen during the last ack-stretching win */
	u_int32_t       rcv_by_unackhalfwin;
	u_int32_t       rcv_nostrack_ts; /* timestamp when stretch ack was disabled automatically */
	u_int32_t       rcv_nostrack_pkts; /* pkts received since strech ack was disabled */
	u_int16_t       rcv_waitforss;  /* wait for packets during slow-start */

/* ECN stats */
	u_int16_t       ecn_flags;
#define TE_SETUPSENT            0x0001  /* Indicate we have sent ECN-SETUP SYN or SYN-ACK */
#define TE_SETUPRECEIVED        0x0002  /* Indicate we have received ECN-SETUP SYN or SYN-ACK */
#define TE_SENDIPECT            0x0004  /* Indicate we haven't sent or received non-ECN-setup SYN or SYN-ACK */
#define TE_SENDCWR              0x0008  /* Indicate that the next non-retransmit should have the TCP CWR flag set */
#define TE_SENDECE              0x0010  /* Indicate that the next packet should have the TCP ECE flag set */
#define TE_INRECOVERY           0x0020  /* connection entered recovery after receiving ECE */
#define TE_RECV_ECN_CE          0x0040  /* Received IPTOS_ECN_CE marking atleast once */
#define TE_RECV_ECN_ECE         0x0080  /* Received ECE marking atleast once */
#define TE_LOST_SYN             0x0100  /* Lost SYN with ECN setup */
#define TE_LOST_SYNACK          0x0200  /* Lost SYN-ACK with ECN setup */
#define TE_ECN_MODE_ENABLE      0x0400  /* Option ECN mode set to enable */
#define TE_ECN_MODE_DISABLE     0x0800  /* Option ECN mode set to disable */
#define TE_ENABLE_ECN           0x1000  /* Enable negotiation of ECN */
#define TE_ECN_ON               (TE_SETUPSENT | TE_SETUPRECEIVED) /* Indicate ECN was successfully negotiated on a connection) */
#define TE_CEHEURI_SET          0x2000 /* We did our CE-probing at the beginning */
#define TE_CLIENT_SETUP         0x4000  /* setup from client side */
#define TE_RCVD_SYN_RST         0x8000  /* Received RST to the first ECN enabled SYN */

	u_int32_t       t_ecn_recv_ce;  /* Received CE from the network */
	u_int32_t       t_ecn_recv_cwr; /* Packets received with CWR */

/* state for bad retransmit recovery */
	u_int32_t       snd_cwnd_prev;  /* cwnd prior to retransmit */
	u_int32_t       snd_ssthresh_prev; /* ssthresh prior to retransmit */
	tcp_seq snd_recover_prev;       /* snd_recover prior to retransmit */
	int     t_srtt_prev;            /* srtt prior to retransmit */
	int     t_rttvar_prev;          /* rttvar prior to retransmit */
	u_int32_t       t_badrexmt_time; /* bad rexmt detection time */

/* Packet reordering metric */
	u_int32_t       t_reorderwin; /* Reordering late time offset */

/* SACK related state */
	int16_t snd_numholes;           /* number of holes seen by sender */
	tcp_seq sack_newdata;           /* New data xmitted in this recovery
	                                 *   episode starts at this seq number */
	TAILQ_HEAD(sackhole_head, sackhole) snd_holes;
	/* SACK scoreboard (sorted) */
	tcp_seq snd_fack;               /* last seq number(+1) sack'd by rcv'r*/
	int     rcv_numsacks;           /* # distinct sack blks present */
	struct sackblk sackblks[MAX_SACK_BLKS]; /* seq nos. of sack blocks */
	struct sackhint sackhint;       /* SACK scoreboard hint */
	tcp_seq         send_highest_sack; /* Sequence number of fresh data sent after the most recent fast-retransmit */
	int             t_new_dupacks; /* Dupacks received above send_highest_sack */

	struct mbuf     *t_pktlist_head; /* First packet in transmit chain */
	struct mbuf     *t_pktlist_tail; /* Last packet in transmit chain */
	u_int32_t       t_pktlist_sentlen; /* total bytes in transmit chain */

	u_int32_t       t_keepidle;     /* keepalive idle timer (override global if > 0) */
	u_int32_t       t_keepinit;     /* connection timeout, i.e. idle time
	                                 *  in SYN_SENT or SYN_RECV state */
	u_int32_t       t_keepintvl;    /* interval between keepalives */
	u_int32_t       t_keepcnt;      /* number of keepalives before close */

	u_int32_t       tso_max_segment_size;   /* TSO maximum segment unit for NIC */
	u_int16_t       t_pmtud_lastseg_size;   /* size of the last sent segment */
	u_int32_t       t_pmtud_saved_maxopd;   /* MSS saved before performing PMTU-D BlackHole detection */
	u_int32_t       t_pmtud_start_ts;       /* Time of PMTUD blackhole detection */

	struct{
		u_int32_t       rxduplicatebytes;
		u_int32_t       rxoutoforderbytes;
		u_int32_t       txretransmitbytes;
		u_int16_t       synrxtshift;
		u_int16_t       rxmitsyns;
		u_int16_t       unused_pad_to_8;
		u_int32_t       rxmitpkts;
		uint32_t        delayed_acks_sent;
		uint32_t        acks_delayed;
	} t_stat;
	u_int8_t        t_notify_ack_count;
	u_int8_t        t_ecn_recv_ce_pkt; /* Received packet with CE-bit set (independent from last_ack_sent) */
	u_int32_t       t_cached_maxopd; /* default for MSS adjustment using link status report */

	uint32_t        bg_ssthresh;            /* Slow start threshold until delay increases */
	uint32_t        t_flagsext;             /* Another field to accommodate more flags */
#define TF_RXTFINDROP           0x1                     /* Drop conn after retransmitting FIN 3 times */
#define TF_RCVUNACK_WAITSS      0x2             /* set when the receiver should not stretch acks */
#define TF_BWMEAS_INPROGRESS    0x4             /* Indicate BW meas is happening */
#define TF_MEASURESNDBW         0x8             /* Measure send bw on this connection */
#define TF_LAST_IS_PSH          0x10            /* Indicates whether the last packet in the rcv socket buffer had the PUSH-flag set */
#define TF_SACK_ENABLE          0x20            /* SACK is enabled */
#define TF_RECOMPUTE_RTT        0x40            /* recompute RTT after spurious retransmit */
#define TF_DETECT_READSTALL     0x80            /* Used to detect a stall during read operation */
#define TF_RECV_THROTTLE        0x100           /* Input throttling active */
#define TF_NOSTRETCHACK         0x200           /* ack every other packet */
#define TF_NOTIMEWAIT           0x800           /* Avoid going into time-wait */
#define TF_SENT_TLPROBE         0x1000          /* Sent data in PTO */
#define TF_PKTS_REORDERED       0x2000          /* Detected reordering */
#define TF_DELAY_RECOVERY       0x4000          /* delay fast recovery */
#define TF_FORCE                0x8000          /* force 1 byte out */
#define TF_DISABLE_STRETCHACK   0x10000         /* auto-disable stretch ack */
#define TF_NOBLACKHOLE_DETECTION 0x20000        /* Disable PMTU blackhole detection */
#define TF_RESCUE_RXT           0x80000         /* SACK rescue retransmit */
#define TF_CWND_NONVALIDATED    0x100000        /* cwnd non validated */
#define TF_IF_PROBING           0x200000        /* Trigger interface probe timeout */
#define TF_FASTOPEN             0x400000        /* TCP Fastopen is enabled */
#define TF_REASS_INPROG         0x800000        /* Reassembly is in progress */
#define TF_FASTOPEN_FORCE_ENABLE 0x1000000      /* Force-enable TCP Fastopen */
#define TF_LOGGED_CONN_SUMMARY  0x2000000       /* Connection summary was logged */

#if TRAFFIC_MGT
	/* Inter-arrival jitter related state */
	uint32_t        iaj_rcv_ts;             /* tcp clock when the first packet was received */
	uint16_t        iaj_size;               /* Size of packet for iaj measurement */
	uint8_t         iaj_small_pkt;          /* Count of packets smaller than iaj_size */
	uint8_t         t_pipeack_ind;          /* index for next pipeack sample */
	uint16_t        iaj_pktcnt;             /* packet count, to avoid throttling initially */
	uint16_t        acc_iaj;                /* Accumulated iaj */
	uint32_t        avg_iaj;                /* Mean */
	uint32_t        std_dev_iaj;            /* Standard deviation */
#endif /* TRAFFIC_MGT */
	struct bwmeas   *t_bwmeas;              /* State for bandwidth measurement */
	tcp_seq         t_idleat;               /* rcv_nxt at idle time */
	TAILQ_ENTRY(tcpcb) t_twentry;           /* link for time wait queue */
	struct tcp_ccstate      *t_ccstate;     /* congestion control related state */
/* Tail loss probe related state */
	tcp_seq         t_tlphighrxt;           /* snd_nxt after PTO */
	u_int32_t       t_tlpstart;             /* timestamp at PTO */
/* DSACK data receiver state */
	tcp_seq         t_dsack_lseq;           /* DSACK left sequence */
	tcp_seq         t_dsack_rseq;           /* DSACK right sequence */
/* DSACK data sender state */
	SLIST_HEAD(tcp_rxt_seghead, tcp_rxt_seg) t_rxt_segments;
	tcp_seq         t_dsack_lastuna;        /* snd_una when last recovery episode started */
/* state for congestion window validation (draft-ietf-tcpm-newcwv-07) */
#define TCP_PIPEACK_SAMPLE_COUNT        3
	u_int32_t       t_pipeack_sample[TCP_PIPEACK_SAMPLE_COUNT];     /* pipeack, bytes acked within RTT */
	tcp_seq         t_pipeack_lastuna; /* una when pipeack measurement started */
	u_int32_t       t_pipeack;
	u_int32_t       t_lossflightsize;

#if MPTCP
	u_int32_t       t_mpflags;              /* flags for multipath TCP */

#define TMPF_PREESTABLISHED     0x00000001 /* conn in pre-established state */
#define TMPF_SND_KEYS           0x00000002 /* indicates that keys should be send */
#define TMPF_MPTCP_TRUE         0x00000004 /* negotiated MPTCP successfully */
#define TMPF_MPTCP_RCVD_KEY     0x00000008 /* state for 3-way handshake */
#define TMPF_SND_MPPRIO         0x00000010 /* send priority of subflow */
#define TMPF_SND_REM_ADDR       0x00000020 /* initiate address removal */
#define TMPF_RCVD_DACK          0x00000040 /* received a data-ack */
#define TMPF_JOINED_FLOW        0x00000080 /* Indicates additional flow */
#define TMPF_BACKUP_PATH        0x00000100 /* Indicates backup path */
#define TMPF_MPTCP_ACKNOW       0x00000200 /* Send Data ACK */
#define TMPF_SEND_DSN           0x00000400 /* Send DSN mapping */
#define TMPF_SEND_DFIN          0x00000800 /* Send Data FIN */
#define TMPF_RECV_DFIN          0x00001000 /* Recv Data FIN */
#define TMPF_SENT_JOIN          0x00002000 /* Sent Join */
#define TMPF_RECVD_JOIN         0x00004000 /* Received Join */
#define TMPF_RESET              0x00008000 /* Send RST */
#define TMPF_TCP_FALLBACK       0x00010000 /* Fallback to TCP */
#define TMPF_FASTCLOSERCV       0x00020000 /* Received Fastclose option */
#define TMPF_EMBED_DSN          0x00040000 /* tp has DSN mapping */
#define TMPF_MPTCP_READY        0x00080000 /* Can send DSS options on data */
#define TMPF_INFIN_SENT         0x00100000 /* Sent infinite mapping */
#define TMPF_SND_MPFAIL         0x00200000 /* Received mapping csum failure */
#define TMPF_SND_JACK           0x00400000 /* Send a Join-ACK */
#define TMPF_TFO_REQUEST        0x00800000 /* TFO Requested */

#define TMPF_MPTCP_SIGNALS      (TMPF_SND_MPPRIO | TMPF_SND_REM_ADDR | TMPF_SND_MPFAIL | TMPF_SND_KEYS | TMPF_SND_JACK)

	tcp_seq                 t_mpuna;        /* unacknowledged sequence */
	struct mptcb            *t_mptcb;       /* pointer to MPTCP TCB */
	struct mptsub           *t_mpsub;       /* pointer to the MPTCP subflow */
	struct mpt_dsn_map      t_rcv_map;      /* Receive mapping list */
	u_int8_t                t_local_aid;    /* Addr Id for authentication */
	u_int8_t                t_rem_aid;      /* Addr ID of another subflow */
	u_int8_t                t_mprxtshift;   /* join retransmission */
#endif /* MPTCP */

#define TFO_F_OFFER_COOKIE      0x01 /* We will offer a cookie */
#define TFO_F_COOKIE_VALID      0x02 /* The received cookie is valid */
#define TFO_F_COOKIE_REQ        0x04 /* Client requested a new cookie */
#define TFO_F_COOKIE_SENT       0x08 /* Client did send a cookie in the SYN */
#define TFO_F_SYN_LOSS          0x10 /* A SYN-loss triggered a fallback to regular TCP on the client-side */
#define TFO_F_NO_SNDPROBING     0x20 /* This network is guaranteed to support TFO in the upstream direction */
#define TFO_F_HEURISTIC_DONE    0x40 /* We have already marked this network as bad */
	u_int8_t                t_tfo_flags;
#define TFO_S_SYNDATA_RCV       0x01 /* SYN+data has been received */
#define TFO_S_COOKIEREQ_RECV    0x02 /* TFO-cookie request received */
#define TFO_S_COOKIE_SENT       0x04 /* TFO-cookie announced in SYN/ACK */
#define TFO_S_COOKIE_INVALID    0x08 /* Received TFO-cookie is invalid */
#define TFO_S_COOKIE_REQ        0x10 /* TFO-cookie requested within the SYN */
#define TFO_S_COOKIE_RCV        0x20 /* TFO-cookie received in SYN/ACK */
#define TFO_S_SYN_DATA_SENT     0x40 /* SYN+data sent */
#define TFO_S_SYN_DATA_ACKED    0x80 /* SYN+data has been acknowledged in SYN/ACK */
#define TFO_S_SYN_LOSS          0x0100 /* SYN+TFO has been lost - fallback to regular TCP */
#define TFO_S_COOKIE_WRONG      0x0200 /* Cookie we sent in the SYN was wrong */
#define TFO_S_NO_COOKIE_RCV     0x0400 /* We asked for a cookie but didn't get one */
#define TFO_S_HEURISTICS_DISABLE 0x0800 /* TFO-heuristics disabled it for this connection */
#define TFO_S_SEND_BLACKHOLE    0x1000 /* TFO got blackholed in the send direction */
#define TFO_S_RECV_BLACKHOLE    0x2000 /* TFO got blackholed in the recv direction */
#define TFO_S_ONE_BYTE_PROXY    0x4000 /* TFO failed because of a proxy acknowledging just one byte */
	u_int16_t               t_tfo_stats;

	u_int8_t                t_tfo_probes; /* TFO-probes we did send */
/*
 * This here is the TFO-probing state-machine. Transitions are as follows:
 *
 * Current state: PROBE_NONE
 *		  Event: SYN+DATA acknowledged
 *			 Action: Transition to PROBE_PROBING and set keepalive-timer
 *
 * Current state: PROBE_PROBING (initial state)
 *		  Event: Receive data
 *			 Action: Transition to PROBE_NONE and cancel keepalive-timer
 *		  Event: Receive ACK that does not indicate a hole
 *			 Action: Transition to PROBE_NONE and cancel keepalive-timer
 *		  Event: Receive ACK that indicates a hole
 *			 Action: Transition to PROBE_WAIT_DATA and set a short timer
 *				 to wait for the final segment.
 *		  Event: Keepalive-timeout (did not receive any segment)
 *			 Action: Signal ETIMEDOUT as with regular keepalive-timers
 *
 * Current state: PROBE_WAIT_DATA
 *		  Event: Receive data
 *			 Action: Transition to PROBE_NONE and cancel keepalive-timer
 *		  Event: Data-timeout (did not receive the expected data)
 *			 Action: Signal ENODATA up to the app and close everything.
 */
#define TFO_PROBE_NONE          0 /* Not probing now */
#define TFO_PROBE_PROBING       1 /* Sending out TCP-keepalives waiting for reply */
#define TFO_PROBE_WAIT_DATA     2 /* Received reply, waiting for data */
	u_int8_t                t_tfo_probe_state;

	u_int32_t       t_rcvoopack;            /* out-of-order packets received */
	u_int32_t       t_pawsdrop;             /* segments dropped due to PAWS */
	u_int32_t       t_sack_recovery_episode; /* SACK recovery episodes */
	u_int32_t       t_reordered_pkts;       /* packets reorderd */
	u_int32_t       t_dsack_sent;           /* Sent DSACK notification */
	u_int32_t       t_dsack_recvd;          /* Received a valid DSACK option */
	SLIST_HEAD(, tcp_notify_ack_marker) t_notify_ack; /* state for notifying data acknowledgements */
	u_int32_t       t_recv_throttle_ts;     /* TS for start of recv throttle */
	u_int32_t       t_rxt_minimum_timeout;  /* minimum retransmit timeout in ms */
	uint32_t        t_challengeack_last;    /* last time challenge ACK was sent per sec */
	uint32_t        t_challengeack_count;   /* # of challenge ACKs already sent per sec */

	u_int32_t       t_log_flags;            /* TCP logging flags*/
	u_int32_t       t_connect_time;         /* time when the connection started */

	uint32_t        t_comp_gencnt; /* Current compression generation-count */
	uint32_t        t_comp_lastinc; /* Last time the gen-count was changed - should change every TCP_COMP_CHANGE_RATE ms */
#define TCP_COMP_CHANGE_RATE    5 /* Intervals at which we change the gencnt. Means that worst-case we send one ACK every TCP_COMP_CHANGE_RATE ms */

	uuid_t          t_fsw_uuid;
	uuid_t          t_flow_uuid;
};

#define IN_FASTRECOVERY(tp)     (tp->t_flags & TF_FASTRECOVERY)
#define SACK_ENABLED(tp)        (tp->t_flagsext & TF_SACK_ENABLE)

/*
 * If the connection is in a throttled state due to advisory feedback from
 * the interface output queue, reset that state. We do this in favor
 * of entering recovery because the data transfer during recovery
 * should be just a trickle and it will help to improve performance.
 * We also do not want to back off twice in the same RTT.
 */
#define ENTER_FASTRECOVERY(_tp_) do {                                           \
	(_tp_)->t_flags |= TF_FASTRECOVERY;                                     \
	if (INP_IS_FLOW_CONTROLLED((_tp_)->t_inpcb))                            \
	        inp_reset_fc_state((_tp_)->t_inpcb);                            \
	if (!SLIST_EMPTY(&tp->t_rxt_segments))                                  \
	        tcp_rxtseg_clean(tp);                                           \
	(_tp_)->t_new_dupacks = 0;                                              \
} while(0)

#define EXIT_FASTRECOVERY(_tp_) do {                                            \
	(_tp_)->t_flags &= ~TF_FASTRECOVERY;                                    \
	(_tp_)->t_dupacks = 0;                                                  \
	(_tp_)->t_new_dupacks = 0;                                              \
	(_tp_)->t_rexmtthresh = (uint8_t)tcprexmtthresh;                        \
	(_tp_)->t_bytes_acked = 0;                                              \
	(_tp_)->ecn_flags &= ~TE_INRECOVERY;                                    \
	(_tp_)->t_timer[TCPT_PTO] = 0;                                          \
	(_tp_)->t_flagsext &= ~TF_RESCUE_RXT;                                   \
	(_tp_)->t_lossflightsize = 0;                                           \
	(_tp_)->sackhint.sack_bytes_acked = 0;                                  \
} while(0)

/*
 * When the number of duplicate acks received is less than
 * the retransmit threshold, use Limited Transmit algorithm
 */
extern int tcprexmtthresh;
#define ALLOW_LIMITED_TRANSMIT(_tp_)                                            \
	((_tp_)->t_dupacks > 0 &&                                               \
	(_tp_)->t_dupacks < (_tp_)->t_rexmtthresh &&                            \
	((_tp_)->t_flagsext & (TF_PKTS_REORDERED|TF_DELAY_RECOVERY))            \
	    != (TF_PKTS_REORDERED|TF_DELAY_RECOVERY))

/*
 * This condition is true is timestamp option is supported
 * on a connection.
 */
#define TSTMP_SUPPORTED(_tp_) \
	(((_tp_)->t_flags & (TF_REQ_TSTMP|TF_RCVD_TSTMP)) == \
	        (TF_REQ_TSTMP|TF_RCVD_TSTMP))

/*
 * This condition is true if window scale option is supported
 * on a connection
 */
#define TCP_WINDOW_SCALE_ENABLED(_tp_) \
	(((_tp_)->t_flags & (TF_RCVD_SCALE|TF_REQ_SCALE)) == \
	        (TF_RCVD_SCALE|TF_REQ_SCALE))

/* Is ECN enabled end-to-end */
#define TCP_ECN_ENABLED(_tp_) \
	(((_tp_)->ecn_flags & (TE_ECN_ON)) == (TE_ECN_ON))

/*
 * Gives number of bytes acked by this ack
 */
#define BYTES_ACKED(_th_, _tp_) \
	((_th_)->th_ack - (_tp_)->snd_una)

/* Returns true if a DSACK option should be sent */
#define TCP_SEND_DSACK_OPT(_tp_) \
	((_tp_)->t_dsack_lseq > 0 && (_tp_)->t_dsack_rseq > 0)

/*
 * Returns true if a DSACK sequence is within the max send window that will
 * be accepted. In order to set a window to validate sequence numbers, the
 * max send window within which a DSACK option is processed is limited.
 *
 * We need to choose a maximum window to check if the sequence number is
 * within the window. One arbitrary choice is 256 * MSS because if the
 * window is as large as 256 segments it might be big enough to ignore the
 * DSACK option. Choosing a much larger limit means that the memory for
 * retransmit segments can be held for a longer time.
 */
#define TCP_DSACK_MAX_SEND_WINDOW(_tp_) (MIN((_tp_)->snd_wnd, tcp_autosndbuf_max))
#define TCP_DSACK_SEQ_IN_WINDOW(_tp_, _seq_, _una_) \
    (SEQ_LEQ((_seq_), (_tp_)->snd_max) && \
    SEQ_GEQ((_seq_), ((_una_) - TCP_DSACK_MAX_SEND_WINDOW(_tp_))))

#define TCP_RESET_REXMT_STATE(_tp_) do { \
	(_tp_)->t_rxtshift = 0; \
	(_tp_)->t_rxtstart = 0; \
	mptcp_reset_rexmit_state((_tp_)); \
} while(0);

#define TCP_IF_STATE_CHANGED(tp, probe_if_index)                        \
	(probe_if_index > 0 && tp->t_inpcb->inp_last_outifp != NULL &&  \
	probe_if_index == tp->t_inpcb->inp_last_outifp->if_index)

/*
 * Structure to hold TCP options that are only used during segment
 * processing (in tcp_input), but not held in the tcpcb.
 * It's basically used to reduce the number of parameters
 * to tcp_dooptions.
 */
struct tcpopt {
	u_int32_t       to_flags;               /* which options are present */
#define TOF_TS          0x0001          /* timestamp */
#define TOF_MSS         0x0010
#define TOF_SCALE       0x0020
#define TOF_SIGNATURE   0x0040  /* signature option present */
#define TOF_SIGLEN      0x0080  /* signature length valid (RFC2385) */
#define TOF_SACK        0x0100          /* Peer sent SACK option */
#define TOF_MPTCP       0x0200  /* MPTCP options to be dropped */
#define TOF_TFO         0x0400  /* TFO cookie option present */
#define TOF_TFOREQ      0x0800  /* TFO cookie request present */
	u_int32_t               to_tsval;
	u_int32_t               to_tsecr;
	u_int16_t       to_mss;
	u_int8_t        to_requested_s_scale;
	u_int8_t        to_nsacks;      /* number of SACK blocks */
	u_char          *to_sacks;      /* pointer to the first SACK blocks */
	u_char          *to_tfo;        /* pointer to the TFO cookie */
};

#define intotcpcb(ip)   ((struct tcpcb *)(ip)->inp_ppcb)
#define sototcpcb(so)   (intotcpcb(sotoinpcb(so)))

/* TFO-specific defines */
#define TFO_COOKIE_LEN_MIN      4
#define TFO_COOKIE_LEN_DEFAULT  8
#define TFO_COOKIE_LEN_MAX      16

/*
 * The initial retransmission should happen at rtt + 4 * rttvar.
 * Because of the way we do the smoothing, srtt and rttvar
 * will each average +1/2 tick of bias.  When we compute
 * the retransmit timer, we want 1/2 tick of rounding and
 * 1 extra tick because of +-1/2 tick uncertainty in the
 * firing of the timer.  The bias will give us exactly the
 * 1.5 tick we need.  But, because the bias is
 * statistical, we have to test that we don't drop below
 * the minimum feasible timer (which is 2 ticks).
 * This version of the macro adapted from a paper by Lawrence
 * Brakmo and Larry Peterson which outlines a problem caused
 * by insufficient precision in the original implementation,
 * which results in inappropriately large RTO values for very
 * fast networks.
 */
#define TCP_REXMTVAL(tp) \
	max((tp)->t_rttmin, (((tp)->t_srtt >> (TCP_RTT_SHIFT - TCP_DELTA_SHIFT))  \
	  + (tp)->t_rttvar) >> TCP_DELTA_SHIFT)

/*
 * Jaguar compatible TCP control block, for xtcpcb
 * Does not have the old fields
 */
struct otcpcb {
#else
struct tseg_qent;
_TCPCB_LIST_HEAD(tsegqe_head, tseg_qent);

struct tcpcb {
#endif /* KERNEL_PRIVATE */
#if defined(KERNEL_PRIVATE)
	u_int32_t t_segq;
#else
	struct  tsegqe_head t_segq;
#endif /* KERNEL_PRIVATE */
	int     t_dupacks;              /* consecutive dup acks recd */
	u_int32_t unused;               /* unused now: was t_template */

	int     t_timer[TCPT_NTIMERS_EXT];      /* tcp timers */

	_TCPCB_PTR(struct inpcb *) t_inpcb;     /* back pointer to internet pcb */
	int     t_state;                /* state of this connection */
	u_int   t_flags;
#define TF_ACKNOW       0x00001         /* ack peer immediately */
#define TF_DELACK       0x00002         /* ack, but try to delay it */
#define TF_NODELAY      0x00004         /* don't delay packets to coalesce */
#define TF_NOOPT        0x00008         /* don't use tcp options */
#define TF_SENTFIN      0x00010         /* have sent FIN */
#define TF_REQ_SCALE    0x00020         /* have/will request window scaling */
#define TF_RCVD_SCALE   0x00040         /* other side has requested scaling */
#define TF_REQ_TSTMP    0x00080         /* have/will request timestamps */
#define TF_RCVD_TSTMP   0x00100         /* a timestamp was received in SYN */
#define TF_SACK_PERMIT  0x00200         /* other side said I could SACK */
#define TF_NEEDSYN      0x00400         /* send SYN (implicit state) - unused but needed for backwards compatibility */
#define TF_NEEDFIN      0x00800         /* send FIN (implicit state) */
#define TF_NOPUSH       0x01000         /* don't push */
#define TF_REQ_CC       0x02000         /* have/will request CC */
#define TF_RCVD_CC      0x04000         /* a CC was received in SYN */
#define TF_SENDCCNEW    0x08000         /* Not implemented */
#define TF_MORETOCOME   0x10000         /* More data to be appended to sock */
#define TF_LQ_OVERFLOW  0x20000         /* listen queue overflow */
#define TF_RXWIN0SENT   0x40000         /* sent a receiver win 0 in response */
#define TF_SLOWLINK     0x80000         /* route is a on a modem speed link */

	int     t_force;                /* 1 if forcing out a byte */

	tcp_seq snd_una;                /* send unacknowledged */
	tcp_seq snd_max;                /* highest sequence number sent;
	                                 * used to recognize retransmits
	                                 */
	tcp_seq snd_nxt;                /* send next */
	tcp_seq snd_up;                 /* send urgent pointer */

	tcp_seq snd_wl1;                /* window update seg seq number */
	tcp_seq snd_wl2;                /* window update seg ack number */
	tcp_seq iss;                    /* initial send sequence number */
	tcp_seq irs;                    /* initial receive sequence number */

	tcp_seq rcv_nxt;                /* receive next */
	tcp_seq rcv_adv;                /* advertised window */
	u_int32_t rcv_wnd;              /* receive window */
	tcp_seq rcv_up;                 /* receive urgent pointer */

	u_int32_t snd_wnd;              /* send window */
	u_int32_t snd_cwnd;             /* congestion-controlled window */
	u_int32_t snd_ssthresh;         /* snd_cwnd size threshold for
	                                 * for slow start exponential to
	                                 * linear switch
	                                 */
	u_int   t_maxopd;               /* mss plus options */

	u_int32_t t_rcvtime;            /* time at which a packet was received */
	u_int32_t t_starttime;          /* time connection was established */
	int     t_rtttime;              /* round trip time */
	tcp_seq t_rtseq;                /* sequence number being timed */

	int     t_rxtcur;               /* current retransmit value (ticks) */
	u_int   t_maxseg;               /* maximum segment size */
	int     t_srtt;                 /* smoothed round-trip time */
	int     t_rttvar;               /* variance in round-trip time */

	int     t_rxtshift;             /* log(2) of rexmt exp. backoff */
	u_int   t_rttmin;               /* minimum rtt allowed */
	u_int32_t t_rttupdated;         /* number of times rtt sampled */
	u_int32_t max_sndwnd;           /* largest window peer has offered */

	int     t_softerror;            /* possible error not yet reported */
/* out-of-band data */
	char    t_oobflags;             /* have some */
	char    t_iobc;                 /* input character */
#define TCPOOB_HAVEDATA 0x01
#define TCPOOB_HADDATA  0x02
/* RFC 1323 variables */
	u_char  snd_scale;              /* window scaling for send window */
	u_char  rcv_scale;              /* window scaling for recv window */
	u_char  request_r_scale;        /* pending window scaling */
	u_char  requested_s_scale;
	u_int32_t ts_recent;            /* timestamp echo data */

	u_int32_t ts_recent_age;        /* when last updated */
	tcp_seq last_ack_sent;
/* RFC 1644 variables */
	tcp_cc  cc_send;                /* send connection count */
	tcp_cc  cc_recv;                /* receive connection count */
	tcp_seq snd_recover;            /* for use in fast recovery */
/* experimental */
	u_int32_t snd_cwnd_prev;        /* cwnd prior to retransmit */
	u_int32_t snd_ssthresh_prev;    /* ssthresh prior to retransmit */
	u_int32_t t_badrxtwin;          /* window for retransmit recovery */
};

#define        tcps_ecn_setup  tcps_ecn_client_success
#define        tcps_sent_cwr   tcps_ecn_recv_ece
#define        tcps_sent_ece   tcps_ecn_sent_ece

/*
 * TCP statistics.
 * Many of these should be kept per connection,
 * but that's inconvenient at the moment.
 */
struct  tcpstat {
	u_int32_t       tcps_connattempt;       /* connections initiated */
	u_int32_t       tcps_accepts;           /* connections accepted */
	u_int32_t       tcps_connects;          /* connections established */
	u_int32_t       tcps_drops;             /* connections dropped */
	u_int32_t       tcps_conndrops;         /* embryonic connections dropped */
	u_int32_t       tcps_closed;            /* conn. closed (includes drops) */
	u_int32_t       tcps_segstimed;         /* segs where we tried to get rtt */
	u_int32_t       tcps_rttupdated;        /* times we succeeded */
	u_int32_t       tcps_delack;            /* delayed acks sent */
	u_int32_t       tcps_timeoutdrop;       /* conn. dropped in rxmt timeout */
	u_int32_t       tcps_rexmttimeo;        /* retransmit timeouts */
	u_int32_t       tcps_persisttimeo;      /* persist timeouts */
	u_int32_t       tcps_keeptimeo;         /* keepalive timeouts */
	u_int32_t       tcps_keepprobe;         /* keepalive probes sent */
	u_int32_t       tcps_keepdrops;         /* connections dropped in keepalive */

	u_int32_t       tcps_sndtotal;          /* total packets sent */
	u_int32_t       tcps_sndpack;           /* data packets sent */
	u_int32_t       tcps_sndbyte;           /* data bytes sent */
	u_int32_t       tcps_sndrexmitpack;     /* data packets retransmitted */
	u_int32_t       tcps_sndrexmitbyte;     /* data bytes retransmitted */
	u_int32_t       tcps_sndacks;           /* ack-only packets sent */
	u_int32_t       tcps_sndprobe;          /* window probes sent */
	u_int32_t       tcps_sndurg;            /* packets sent with URG only */
	u_int32_t       tcps_sndwinup;          /* window update-only packets sent */
	u_int32_t       tcps_sndctrl;           /* control (SYN|FIN|RST) packets sent */

	u_int32_t       tcps_rcvtotal;          /* total packets received */
	u_int32_t       tcps_rcvpack;           /* packets received in sequence */
	u_int32_t       tcps_rcvbyte;           /* bytes received in sequence */
	u_int32_t       tcps_rcvbadsum;         /* packets received with ccksum errs */
	u_int32_t       tcps_rcvbadoff;         /* packets received with bad offset */
	u_int32_t       tcps_rcvmemdrop;        /* packets dropped for lack of memory */
	u_int32_t       tcps_rcvshort;          /* packets received too short */
	u_int32_t       tcps_rcvduppack;        /* duplicate-only packets received */
	u_int32_t       tcps_rcvdupbyte;        /* duplicate-only bytes received */
	u_int32_t       tcps_rcvpartduppack;    /* packets with some duplicate data */
	u_int32_t       tcps_rcvpartdupbyte;    /* dup. bytes in part-dup. packets */
	u_int32_t       tcps_rcvoopack;         /* out-of-order packets received */
	u_int32_t       tcps_rcvoobyte;         /* out-of-order bytes received */
	u_int32_t       tcps_rcvpackafterwin;   /* packets with data after window */
	u_int32_t       tcps_rcvbyteafterwin;   /* bytes rcvd after window */
	u_int32_t       tcps_rcvafterclose;     /* packets rcvd after "close" */
	u_int32_t       tcps_rcvwinprobe;       /* rcvd window probe packets */
	u_int32_t       tcps_rcvdupack;         /* rcvd duplicate acks */
	u_int32_t       tcps_rcvacktoomuch;     /* rcvd acks for unsent data */
	u_int32_t       tcps_rcvackpack;        /* rcvd ack packets */
	u_int32_t       tcps_rcvackbyte;        /* bytes acked by rcvd acks */
	u_int32_t       tcps_rcvwinupd;         /* rcvd window update packets */
	u_int32_t       tcps_pawsdrop;          /* segments dropped due to PAWS */
	u_int32_t       tcps_predack;           /* times hdr predict ok for acks */
	u_int32_t       tcps_preddat;           /* times hdr predict ok for data pkts */
	u_int32_t       tcps_pcbcachemiss;
	u_int32_t       tcps_cachedrtt;         /* times cached RTT in route updated */
	u_int32_t       tcps_cachedrttvar;      /* times cached rttvar updated */
	u_int32_t       tcps_cachedssthresh;    /* times cached ssthresh updated */
	u_int32_t       tcps_usedrtt;           /* times RTT initialized from route */
	u_int32_t       tcps_usedrttvar;        /* times RTTVAR initialized from rt */
	u_int32_t       tcps_usedssthresh;      /* times ssthresh initialized from rt*/
	u_int32_t       tcps_persistdrop;       /* timeout in persist state */
	u_int32_t       tcps_badsyn;            /* bogus SYN, e.g. premature ACK */
	u_int32_t       tcps_mturesent;         /* resends due to MTU discovery */
	u_int32_t       tcps_listendrop;        /* listen queue overflows */
	u_int32_t       tcps_synchallenge;      /* challenge ACK due to bad SYN */
	u_int32_t       tcps_rstchallenge;      /* challenge ACK due to bad RST */

	/* new stats from FreeBSD 5.4 sync up */
	u_int32_t       tcps_minmssdrops;       /* average minmss too low drops */

	u_int32_t       tcps_sndrexmitbad;      /* unnecessary packet retransmissions */
	u_int32_t       tcps_badrst;            /* ignored RSTs in the window */

	u_int32_t       tcps_sc_added;          /* entry added to syncache */
	u_int32_t       tcps_sc_retransmitted;  /* syncache entry was retransmitted */
	u_int32_t       tcps_sc_dupsyn;         /* duplicate SYN packet */
	u_int32_t       tcps_sc_dropped;        /* could not reply to packet */
	u_int32_t       tcps_sc_completed;      /* successful extraction of entry */
	u_int32_t       tcps_sc_bucketoverflow; /* syncache per-bucket limit hit */
	u_int32_t       tcps_sc_cacheoverflow;  /* syncache cache limit hit */
	u_int32_t       tcps_sc_reset;          /* RST removed entry from syncache */
	u_int32_t       tcps_sc_stale;          /* timed out or listen socket gone */
	u_int32_t       tcps_sc_aborted;        /* syncache entry aborted */
	u_int32_t       tcps_sc_badack;         /* removed due to bad ACK */
	u_int32_t       tcps_sc_unreach;        /* ICMP unreachable received */
	u_int32_t       tcps_sc_zonefail;       /* zalloc() failed */
	u_int32_t       tcps_sc_sendcookie;     /* SYN cookie sent */
	u_int32_t       tcps_sc_recvcookie;     /* SYN cookie received */

	u_int32_t       tcps_hc_added;          /* entry added to hostcache */
	u_int32_t       tcps_hc_bucketoverflow; /* hostcache per bucket limit hit */

	/* SACK related stats */
	u_int32_t       tcps_sack_recovery_episode; /* SACK recovery episodes */
	u_int32_t       tcps_sack_rexmits;          /* SACK rexmit segments   */
	u_int32_t       tcps_sack_rexmit_bytes;     /* SACK rexmit bytes      */
	u_int32_t       tcps_sack_rcv_blocks;       /* SACK blocks (options) received */
	u_int32_t       tcps_sack_send_blocks;      /* SACK blocks (options) sent     */
	u_int32_t       tcps_sack_sboverflow;       /* SACK sendblock overflow   */

	u_int32_t       tcps_bg_rcvtotal;       /* total background packets received */
	u_int32_t       tcps_rxtfindrop;        /* drop conn after retransmitting FIN */
	u_int32_t       tcps_fcholdpacket;      /* packets withheld because of flow control */

	u_int32_t       tcps_limited_txt;       /* Limited transmit used */
	u_int32_t       tcps_early_rexmt;       /* Early retransmit used */
	u_int32_t       tcps_sack_ackadv;       /* Cumulative ack advanced along with sack */

	/* Checksum related stats */
	u_int32_t       tcps_rcv_swcsum;        /* tcp swcksum (inbound), packets */
	u_int32_t       tcps_rcv_swcsum_bytes;  /* tcp swcksum (inbound), bytes */
	u_int32_t       tcps_rcv6_swcsum;       /* tcp6 swcksum (inbound), packets */
	u_int32_t       tcps_rcv6_swcsum_bytes; /* tcp6 swcksum (inbound), bytes */
	u_int32_t       tcps_snd_swcsum;        /* tcp swcksum (outbound), packets */
	u_int32_t       tcps_snd_swcsum_bytes;  /* tcp swcksum (outbound), bytes */
	u_int32_t       tcps_snd6_swcsum;       /* tcp6 swcksum (outbound), packets */
	u_int32_t       tcps_snd6_swcsum_bytes; /* tcp6 swcksum (outbound), bytes */
	u_int32_t       tcps_unused_1;
	u_int32_t       tcps_unused_2;
	u_int32_t       tcps_unused_3;

	/* MPTCP Related stats */
	u_int32_t       tcps_invalid_mpcap;     /* Invalid MPTCP capable opts */
	u_int32_t       tcps_invalid_joins;     /* Invalid MPTCP joins */
	u_int32_t       tcps_mpcap_fallback;    /* TCP fallback in primary */
	u_int32_t       tcps_join_fallback;     /* No MPTCP in secondary */
	u_int32_t       tcps_estab_fallback;    /* DSS option dropped */
	u_int32_t       tcps_invalid_opt;       /* Catchall error stat */
	u_int32_t       tcps_mp_outofwin;       /* Packet lies outside the
	                                         *  shared recv window */
	u_int32_t       tcps_mp_reducedwin;     /* Reduced subflow window */
	u_int32_t       tcps_mp_badcsum;        /* Bad DSS csum */
	u_int32_t       tcps_mp_oodata;         /* Out of order data */
	u_int32_t       tcps_mp_switches;       /* number of subflow switch */
	u_int32_t       tcps_mp_rcvtotal;       /* number of rcvd packets */
	u_int32_t       tcps_mp_rcvbytes;       /* number of bytes received */
	u_int32_t       tcps_mp_sndpacks;       /* number of data packs sent */
	u_int32_t       tcps_mp_sndbytes;       /* number of bytes sent */
	u_int32_t       tcps_join_rxmts;        /* join ack retransmits */
	u_int32_t       tcps_tailloss_rto;      /* RTO due to tail loss */
	u_int32_t       tcps_reordered_pkts;    /* packets reorderd */
	u_int32_t       tcps_recovered_pkts;    /* recovered after loss */
	u_int32_t       tcps_pto;               /* probe timeout */
	u_int32_t       tcps_rto_after_pto;     /* RTO after a probe */
	u_int32_t       tcps_tlp_recovery;      /* TLP induced fast recovery */
	u_int32_t       tcps_tlp_recoverlastpkt; /* TLP recoverd last pkt */
	u_int32_t       tcps_ecn_client_success; /* client-side connection negotiated ECN */
	u_int32_t       tcps_ecn_recv_ece;      /* ECE received, sent CWR */
	u_int32_t       tcps_ecn_sent_ece;      /* Sent ECE notification */
	u_int32_t       tcps_detect_reordering; /* Detect pkt reordering */
	u_int32_t       tcps_delay_recovery;    /* Delay fast recovery */
	u_int32_t       tcps_avoid_rxmt;        /* Retransmission was avoided */
	u_int32_t       tcps_unnecessary_rxmt;  /* Retransmission was not needed */
	u_int32_t       tcps_nostretchack;      /* disabled stretch ack algorithm on a connection */
	u_int32_t       tcps_rescue_rxmt;       /* SACK rescue retransmit */
	u_int32_t       tcps_pto_in_recovery;   /* rescue retransmit in fast recovery */
	u_int32_t       tcps_pmtudbh_reverted;  /* PMTU Blackhole detection, segment size reverted */

	/* DSACK related statistics */
	u_int32_t       tcps_dsack_disable;     /* DSACK disabled due to n/w duplication */
	u_int32_t       tcps_dsack_ackloss;     /* ignore DSACK due to ack loss */
	u_int32_t       tcps_dsack_badrexmt;    /* DSACK based bad rexmt recovery */
	u_int32_t       tcps_dsack_sent;        /* Sent DSACK notification */
	u_int32_t       tcps_dsack_recvd;       /* Received a valid DSACK option */
	u_int32_t       tcps_dsack_recvd_old;   /* Received an out of window DSACK option */

	/* MPTCP Subflow selection stats */
	u_int32_t       tcps_mp_sel_symtomsd;   /* By symptomsd */
	u_int32_t       tcps_mp_sel_rtt;        /* By RTT comparison */
	u_int32_t       tcps_mp_sel_rto;        /* By RTO comparison */
	u_int32_t       tcps_mp_sel_peer;       /* By peer's output pattern */
	u_int32_t       tcps_mp_num_probes;     /* Number of probes sent */
	u_int32_t       tcps_mp_verdowngrade;   /* MPTCP version downgrade */
	u_int32_t       tcps_drop_after_sleep;  /* drop after long AP sleep */
	u_int32_t       tcps_probe_if;          /* probe packets after interface availability */
	u_int32_t       tcps_probe_if_conflict; /* Can't send probe packets for interface */

	u_int32_t       tcps_ecn_client_setup;  /* Attempted ECN setup from client side */
	u_int32_t       tcps_ecn_server_setup;  /* Attempted ECN setup from server side */
	u_int32_t       tcps_ecn_server_success; /* server-side connection negotiated ECN */
	u_int32_t       tcps_ecn_lost_synack;   /* Lost SYN-ACK with ECN setup */
	u_int32_t       tcps_ecn_lost_syn;      /* Lost SYN with ECN setup */
	u_int32_t       tcps_ecn_not_supported; /* Server did not support ECN setup */
	u_int32_t       tcps_ecn_recv_ce;       /* Received CE from the network */
	u_int32_t       tcps_ecn_conn_recv_ce;  /* Number of connections received CE atleast once */
	u_int32_t       tcps_ecn_conn_recv_ece; /* Number of connections received ECE atleast once */
	u_int32_t       tcps_ecn_conn_plnoce;   /* Number of connections that received no CE and sufferred packet loss */
	u_int32_t       tcps_ecn_conn_pl_ce;    /* Number of connections that received CE and sufferred packet loss */
	u_int32_t       tcps_ecn_conn_nopl_ce;  /* Number of connections that received CE and sufferred no packet loss */
	u_int32_t       tcps_ecn_fallback_synloss; /* Number of times we did fall back due to SYN-Loss */
	u_int32_t       tcps_ecn_fallback_reorder; /* Number of times we fallback because we detected the PAWS-issue */
	u_int32_t       tcps_ecn_fallback_ce;   /* Number of times we fallback because we received too many CEs */

	/* TFO-related statistics */
	u_int32_t       tcps_tfo_syn_data_rcv;  /* Received a SYN+data with valid cookie */
	u_int32_t       tcps_tfo_cookie_req_rcv;/* Received a TFO cookie-request */
	u_int32_t       tcps_tfo_cookie_sent;   /* Offered a TFO-cookie to the client */
	u_int32_t       tcps_tfo_cookie_invalid;/* Received an invalid TFO-cookie */
	u_int32_t       tcps_tfo_cookie_req;    /* Cookie requested with the SYN */
	u_int32_t       tcps_tfo_cookie_rcv;    /* Cookie received in a SYN/ACK */
	u_int32_t       tcps_tfo_syn_data_sent; /* SYN+data+cookie sent */
	u_int32_t       tcps_tfo_syn_data_acked;/* SYN+data has been acknowledged */
	u_int32_t       tcps_tfo_syn_loss;      /* SYN+TFO has been lost and we fallback */
	u_int32_t       tcps_tfo_blackhole;     /* TFO got blackholed by a middlebox. */
	u_int32_t       tcps_tfo_cookie_wrong;  /* TFO-cookie we sent was wrong */
	u_int32_t       tcps_tfo_no_cookie_rcv; /* We asked for a cookie but didn't get one */
	u_int32_t       tcps_tfo_heuristics_disable; /* TFO got disabled due to heuristics */
	u_int32_t       tcps_tfo_sndblackhole;  /* TFO got blackholed in the sending direction */
	u_int32_t       tcps_mss_to_default;    /* Change MSS to default using link status report */
	u_int32_t       tcps_mss_to_medium;     /* Change MSS to medium using link status report */
	u_int32_t       tcps_mss_to_low;        /* Change MSS to low using link status report */
	u_int32_t       tcps_ecn_fallback_droprst; /* ECN fallback caused by connection drop due to RST */
	u_int32_t       tcps_ecn_fallback_droprxmt; /* ECN fallback due to drop after multiple retransmits */
	u_int32_t       tcps_ecn_fallback_synrst; /* ECN fallback due to rst after syn */

	u_int32_t       tcps_mptcp_rcvmemdrop;  /* MPTCP packets dropped for lack of memory */
	u_int32_t       tcps_mptcp_rcvduppack;  /* MPTCP duplicate-only packets received */
	u_int32_t       tcps_mptcp_rcvpackafterwin; /* MPTCP packets with data after window */

	/* TCP timer statistics */
	u_int32_t       tcps_timer_drift_le_1_ms;       /* Timer drift less or equal to 1 ms */
	u_int32_t       tcps_timer_drift_le_10_ms;      /* Timer drift less or equal to 10 ms */
	u_int32_t       tcps_timer_drift_le_20_ms;      /* Timer drift less or equal to 20 ms */
	u_int32_t       tcps_timer_drift_le_50_ms;      /* Timer drift less or equal to 50 ms */
	u_int32_t       tcps_timer_drift_le_100_ms;     /* Timer drift less or equal to 100 ms */
	u_int32_t       tcps_timer_drift_le_200_ms;     /* Timer drift less or equal to 200 ms */
	u_int32_t       tcps_timer_drift_le_500_ms;     /* Timer drift less or equal to 500 ms */
	u_int32_t       tcps_timer_drift_le_1000_ms;    /* Timer drift less or equal to 1000 ms */
	u_int32_t       tcps_timer_drift_gt_1000_ms;    /* Timer drift greater than 1000 ms */

	u_int32_t       tcps_mptcp_handover_attempt;    /* Total number of MPTCP-attempts using handover mode */
	u_int32_t       tcps_mptcp_interactive_attempt; /* Total number of MPTCP-attempts using interactive mode */
	u_int32_t       tcps_mptcp_aggregate_attempt;   /* Total number of MPTCP-attempts using aggregate mode */
	u_int32_t       tcps_mptcp_fp_handover_attempt; /* Same as previous three but only for first-party apps */
	u_int32_t       tcps_mptcp_fp_interactive_attempt;
	u_int32_t       tcps_mptcp_fp_aggregate_attempt;
	u_int32_t       tcps_mptcp_heuristic_fallback;  /* Total number of MPTCP-connections that fell back due to heuristics */
	u_int32_t       tcps_mptcp_fp_heuristic_fallback;       /* Same as previous but for first-party apps */
	u_int32_t       tcps_mptcp_handover_success_wifi;       /* Total number of successfull handover-mode connections that *started* on WiFi */
	u_int32_t       tcps_mptcp_handover_success_cell;       /* Total number of successfull handover-mode connections that *started* on Cell */
	u_int32_t       tcps_mptcp_interactive_success;         /* Total number of interactive-mode connections that negotiated MPTCP */
	u_int32_t       tcps_mptcp_aggregate_success;           /* Same as previous but for aggregate */
	u_int32_t       tcps_mptcp_fp_handover_success_wifi;    /* Same as previous four, but for first-party apps */
	u_int32_t       tcps_mptcp_fp_handover_success_cell;
	u_int32_t       tcps_mptcp_fp_interactive_success;
	u_int32_t       tcps_mptcp_fp_aggregate_success;
	u_int32_t       tcps_mptcp_handover_cell_from_wifi;     /* Total number of connections that use cell in handover-mode (coming from WiFi) */
	u_int32_t       tcps_mptcp_handover_wifi_from_cell;     /* Total number of connections that use WiFi in handover-mode (coming from cell) */
	u_int32_t       tcps_mptcp_interactive_cell_from_wifi;  /* Total number of connections that use cell in interactive mode (coming from WiFi) */
	u_int64_t       tcps_mptcp_handover_cell_bytes;         /* Total number of bytes sent on cell in handover-mode (on new subflows, ignoring initial one) */
	u_int64_t       tcps_mptcp_interactive_cell_bytes;      /* Same as previous but for interactive */
	u_int64_t       tcps_mptcp_aggregate_cell_bytes;
	u_int64_t       tcps_mptcp_handover_all_bytes;          /* Total number of bytes sent in handover */
	u_int64_t       tcps_mptcp_interactive_all_bytes;
	u_int64_t       tcps_mptcp_aggregate_all_bytes;
	u_int32_t       tcps_mptcp_back_to_wifi;        /* Total number of connections that succeed to move traffic away from cell (when starting on cell) */
	u_int32_t       tcps_mptcp_wifi_proxy;          /* Total number of new subflows that fell back to regular TCP on cell */
	u_int32_t       tcps_mptcp_cell_proxy;          /* Total number of new subflows that fell back to regular TCP on WiFi */

	/* TCP offload statistics */
	u_int32_t       tcps_ka_offload_drops;  /* Keep alive drops for timeout reported by firmware */

	u_int32_t       tcps_mptcp_triggered_cell;      /* Total number of times an MPTCP-connection triggered cell bringup */
};


struct tcpstat_local {
	u_int64_t badformat;
	u_int64_t unspecv6;
	u_int64_t synfin;
	u_int64_t badformatipsec;
	u_int64_t noconnnolist;
	u_int64_t noconnlist;
	u_int64_t listbadsyn;
	u_int64_t icmp6unreach;
	u_int64_t deprecate6;
	u_int64_t ooopacket;
	u_int64_t rstinsynrcv;
	u_int64_t dospacket;
	u_int64_t cleanup;
	u_int64_t synwindow;
};

#pragma pack(4)

/*
 * TCB structure exported to user-land via sysctl(3).
 * Evil hack: declare only if in_pcb.h and sys/socketvar.h have been
 * included.  Not all of our clients do.
 */

struct  xtcpcb {
	u_int32_t       xt_len;
#ifdef KERNEL_PRIVATE
	struct  inpcb_compat    xt_inp;
#else
	struct  inpcb   xt_inp;
#endif
#ifdef KERNEL_PRIVATE
	struct  otcpcb  xt_tp;
#else
	struct  tcpcb   xt_tp;
#endif
	struct  xsocket xt_socket;
	u_quad_t        xt_alignment_hack;
};

#if XNU_TARGET_OS_OSX || !(TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR)

struct  xtcpcb64 {
	u_int32_t               xt_len;
	struct xinpcb64         xt_inpcb;

	u_int64_t t_segq;
	int     t_dupacks;              /* consecutive dup acks recd */

	int t_timer[TCPT_NTIMERS_EXT];  /* tcp timers */

	int     t_state;                /* state of this connection */
	u_int   t_flags;

	int     t_force;                /* 1 if forcing out a byte */

	tcp_seq snd_una;                /* send unacknowledged */
	tcp_seq snd_max;                /* highest sequence number sent;
	                                 * used to recognize retransmits
	                                 */
	tcp_seq snd_nxt;                /* send next */
	tcp_seq snd_up;                 /* send urgent pointer */

	tcp_seq snd_wl1;                /* window update seg seq number */
	tcp_seq snd_wl2;                /* window update seg ack number */
	tcp_seq iss;                    /* initial send sequence number */
	tcp_seq irs;                    /* initial receive sequence number */

	tcp_seq rcv_nxt;                /* receive next */
	tcp_seq rcv_adv;                /* advertised window */
	u_int32_t rcv_wnd;              /* receive window */
	tcp_seq rcv_up;                 /* receive urgent pointer */

	u_int32_t snd_wnd;              /* send window */
	u_int32_t snd_cwnd;             /* congestion-controlled window */
	u_int32_t snd_ssthresh;         /* snd_cwnd size threshold for
	                                 * for slow start exponential to
	                                 * linear switch
	                                 */
	u_int   t_maxopd;               /* mss plus options */

	u_int32_t t_rcvtime;            /* time at which a packet was received */
	u_int32_t t_starttime;          /* time connection was established */
	int     t_rtttime;              /* round trip time */
	tcp_seq t_rtseq;                /* sequence number being timed */

	int     t_rxtcur;               /* current retransmit value (ticks) */
	u_int   t_maxseg;               /* maximum segment size */
	int     t_srtt;                 /* smoothed round-trip time */
	int     t_rttvar;               /* variance in round-trip time */

	int     t_rxtshift;             /* log(2) of rexmt exp. backoff */
	u_int   t_rttmin;               /* minimum rtt allowed */
	u_int32_t t_rttupdated;         /* number of times rtt sampled */
	u_int32_t max_sndwnd;           /* largest window peer has offered */

	int     t_softerror;            /* possible error not yet reported */
/* out-of-band data */
	char    t_oobflags;             /* have some */
	char    t_iobc;                 /* input character */
/* RFC 1323 variables */
	u_char  snd_scale;              /* window scaling for send window */
	u_char  rcv_scale;              /* window scaling for recv window */
	u_char  request_r_scale;        /* pending window scaling */
	u_char  requested_s_scale;
	u_int32_t ts_recent;            /* timestamp echo data */

	u_int32_t ts_recent_age;        /* when last updated */
	tcp_seq last_ack_sent;
/* RFC 1644 variables */
	tcp_cc  cc_send;                /* send connection count */
	tcp_cc  cc_recv;                /* receive connection count */
	tcp_seq snd_recover;            /* for use in fast recovery */
/* experimental */
	u_int32_t snd_cwnd_prev;        /* cwnd prior to retransmit */
	u_int32_t snd_ssthresh_prev;    /* ssthresh prior to retransmit */
	u_int32_t t_badrxtwin;          /* window for retransmit recovery */

	u_quad_t                xt_alignment_hack;
};

#endif /* XNU_TARGET_OS_OSX || !(TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR) */

#ifdef PRIVATE

struct  xtcpcb_n {
	u_int32_t               xt_len;
	u_int32_t                       xt_kind;                /* XSO_TCPCB */

	u_int64_t t_segq;
	int     t_dupacks;              /* consecutive dup acks recd */

	int t_timer[TCPT_NTIMERS_EXT];  /* tcp timers */

	int     t_state;                /* state of this connection */
	u_int   t_flags;

	int     t_force;                /* 1 if forcing out a byte */

	tcp_seq snd_una;                /* send unacknowledged */
	tcp_seq snd_max;                /* highest sequence number sent;
	                                 * used to recognize retransmits
	                                 */
	tcp_seq snd_nxt;                /* send next */
	tcp_seq snd_up;                 /* send urgent pointer */

	tcp_seq snd_wl1;                /* window update seg seq number */
	tcp_seq snd_wl2;                /* window update seg ack number */
	tcp_seq iss;                    /* initial send sequence number */
	tcp_seq irs;                    /* initial receive sequence number */

	tcp_seq rcv_nxt;                /* receive next */
	tcp_seq rcv_adv;                /* advertised window */
	u_int32_t rcv_wnd;              /* receive window */
	tcp_seq rcv_up;                 /* receive urgent pointer */

	u_int32_t snd_wnd;              /* send window */
	u_int32_t snd_cwnd;             /* congestion-controlled window */
	u_int32_t snd_ssthresh;         /* snd_cwnd size threshold for
	                                 * for slow start exponential to
	                                 * linear switch
	                                 */
	u_int   t_maxopd;               /* mss plus options */

	u_int32_t t_rcvtime;            /* time at which a packet was received */
	u_int32_t t_starttime;          /* time connection was established */
	int     t_rtttime;              /* round trip time */
	tcp_seq t_rtseq;                /* sequence number being timed */

	int     t_rxtcur;               /* current retransmit value (ticks) */
	u_int   t_maxseg;               /* maximum segment size */
	int     t_srtt;                 /* smoothed round-trip time */
	int     t_rttvar;               /* variance in round-trip time */

	int     t_rxtshift;             /* log(2) of rexmt exp. backoff */
	u_int   t_rttmin;               /* minimum rtt allowed */
	u_int32_t t_rttupdated;         /* number of times rtt sampled */
	u_int32_t max_sndwnd;           /* largest window peer has offered */

	int     t_softerror;            /* possible error not yet reported */
	/* out-of-band data */
	char    t_oobflags;             /* have some */
	char    t_iobc;                 /* input character */
	/* RFC 1323 variables */
	u_char  snd_scale;              /* window scaling for send window */
	u_char  rcv_scale;              /* window scaling for recv window */
	u_char  request_r_scale;        /* pending window scaling */
	u_char  requested_s_scale;
	u_int32_t ts_recent;            /* timestamp echo data */

	u_int32_t ts_recent_age;        /* when last updated */
	tcp_seq last_ack_sent;
	/* RFC 1644 variables */
	tcp_cc  cc_send;                /* send connection count */
	tcp_cc  cc_recv;                /* receive connection count */
	tcp_seq snd_recover;            /* for use in fast recovery */
	/* experimental */
	u_int32_t snd_cwnd_prev;        /* cwnd prior to retransmit */
	u_int32_t snd_ssthresh_prev;    /* ssthresh prior to retransmit */
};

/*
 * The rtt measured is in milliseconds as the timestamp granularity is
 * a millisecond. The smoothed round-trip time and estimated variance
 * are stored as fixed point numbers scaled by the values below.
 * For convenience, these scales are also used in smoothing the average
 * (smoothed = (1/scale)sample + ((scale-1)/scale)smoothed).
 * With these scales, srtt has 5 bits to the right of the binary point,
 * and thus an "ALPHA" of 0.875.  rttvar has 4 bits to the right of the
 * binary point, and is smoothed with an ALPHA of 0.75.
 */
#define TCP_RTT_SCALE           32      /* multiplier for srtt; 3 bits frac. */
#define TCP_RTT_SHIFT           5       /* shift for srtt; 5 bits frac. */
#define TCP_RTTVAR_SCALE        16      /* multiplier for rttvar; 4 bits */
#define TCP_RTTVAR_SHIFT        4       /* shift for rttvar; 4 bits */
#define TCP_DELTA_SHIFT         2       /* see tcp_input.c */


/*
 * TCP structure with information that gives insight into forward progress on an interface,
 * exported to user-land via sysctl(3).
 */
struct  xtcpprogress_indicators {
	u_int32_t       xp_numflows;            /* Total number of flows */
	u_int32_t       xp_conn_probe_fails;    /* Count of connection failures */
	u_int32_t       xp_read_probe_fails;    /* Count of read probe failures */
	u_int32_t       xp_write_probe_fails;   /* Count of write failures */
	u_int32_t       xp_recentflows;         /* Total of "recent" flows */
	u_int32_t       xp_recentflows_unacked; /* Total of "recent" flows with unacknowledged data */
	u_int64_t       xp_recentflows_rxbytes; /* Total of "recent" flows received bytes */
	u_int64_t       xp_recentflows_txbytes; /* Total of "recent" flows transmitted bytes */
	u_int64_t       xp_recentflows_rxooo;   /* Total of "recent" flows received out of order bytes */
	u_int64_t       xp_recentflows_rxdup;   /* Total of "recent" flows received duplicate bytes */
	u_int64_t       xp_recentflows_retx;    /* Total of "recent" flows retransmitted bytes */
	u_int64_t       xp_reserved1;           /* Expansion */
	u_int64_t       xp_reserved2;           /* Expansion */
	u_int64_t       xp_reserved3;           /* Expansion */
	u_int64_t       xp_reserved4;           /* Expansion */
};

struct tcpprogressreq {
	u_int64_t       ifindex;                /* Interface index for progress indicators */
	u_int64_t       recentflow_maxduration; /* In mach_absolute_time, max duration for flow to be counted as "recent" */
	u_int64_t       filter_flags;           /* Optional additional filtering, values are interface properties per ntstat.h */
	u_int64_t       xp_reserved2;           /* Expansion */
};

#endif /* PRIVATE */

#pragma pack()

/*
 * Names for TCP sysctl objects
 */
#define TCPCTL_DO_RFC1323       1       /* use RFC-1323 extensions */
#define TCPCTL_DO_RFC1644       2       /* use RFC-1644 extensions */
#define TCPCTL_MSSDFLT          3       /* MSS default */
#define TCPCTL_STATS            4       /* statistics (read-only) */
#define TCPCTL_RTTDFLT          5       /* default RTT estimate */
#define TCPCTL_KEEPIDLE         6       /* keepalive idle timer */
#define TCPCTL_KEEPINTVL        7       /* interval to send keepalives */
#define TCPCTL_SENDSPACE        8       /* send buffer space */
#define TCPCTL_RECVSPACE        9       /* receive buffer space */
#define TCPCTL_KEEPINIT         10      /* timeout for establishing syn */
#define TCPCTL_PCBLIST          11      /* list of all outstanding PCBs */
#define TCPCTL_DELACKTIME       12      /* time before sending delayed ACK */
#define TCPCTL_V6MSSDFLT        13      /* MSS default for IPv6 */
#define TCPCTL_MAXID            14

#ifdef BSD_KERNEL_PRIVATE
#include <sys/bitstring.h>

#define TCP_PKTLIST_CLEAR(tp) {                                         \
	(tp)->t_pktlist_head = (tp)->t_pktlist_tail = NULL;             \
	(tp)->t_lastchain = (tp)->t_pktlist_sentlen = 0;                \
}

extern int tcp_TCPTV_MIN;

#ifdef SYSCTL_DECL
SYSCTL_DECL(_net_inet_tcp);
#endif /* SYSCTL_DECL */

extern  struct inpcbhead tcb;           /* head of queue of active tcpcb's */
extern  struct inpcbinfo tcbinfo;
extern  struct tcpstat tcpstat; /* tcp statistics */
extern  int tcp_mssdflt;        /* XXX */
extern  int tcp_minmss;
#define TCP_FASTOPEN_SERVER 0x01
#define TCP_FASTOPEN_CLIENT 0x02

extern int tcp_tfo_halfcnt;
extern int tcp_tfo_backlog;
extern int tcp_fastopen;
extern int ss_fltsz_local;
extern int target_qdelay;
extern u_int32_t tcp_now;               /* for RFC 1323 timestamps */
extern struct timeval tcp_uptime;
extern lck_spin_t *tcp_uptime_lock;
extern int tcp_delack_enabled;
extern int maxseg_unacked;
extern int tcp_use_newreno;
extern struct zone *tcp_reass_zone;
extern struct zone *tcp_rxt_seg_zone;
extern int tcp_ecn_outbound;
extern int tcp_ecn_inbound;
extern uint32_t tcp_do_autorcvbuf;
extern uint32_t tcp_autorcvbuf_max;
extern int tcp_recv_bg;
extern int tcp_do_ack_compression;
/*
 * Dummy value used for when there is no flow and we want to ensure that compression
 * can happen.
 */
#define TCP_ACK_COMPRESSION_DUMMY 1

extern int tcp_do_better_lr;
extern int tcp_cubic_minor_fixes;
extern int tcp_cubic_rfc_compliant;
extern int tcp_flow_control_response;

struct protosw;
struct domain;

struct tcp_respond_args {
	unsigned int ifscope;
	unsigned int nocell:1,
	    noexpensive:1,
	    awdl_unrestricted:1,
	    intcoproc_allowed:1,
	    keep_alive:1,
	    noconstrained:1;
};

void     tcp_canceltimers(struct tcpcb *);
struct tcpcb *
tcp_close(struct tcpcb *);
void     tcp_ctlinput(int, struct sockaddr *, void *, struct ifnet *);
int      tcp_ctloutput(struct socket *, struct sockopt *);
struct tcpcb *
tcp_drop(struct tcpcb *, int);
void     tcp_drain(void);
void     tcp_getrt_rtt(struct tcpcb *tp, struct rtentry *rt);
void     tcp_init(struct protosw *, struct domain *);
void     tcp_input(struct mbuf *, int);
void     tcp_mss(struct tcpcb *, int, unsigned int);
int      tcp_mssopt(struct tcpcb *);
void     tcp_drop_syn_sent(struct inpcb *, int);
void     tcp_mtudisc(struct inpcb *, int);
struct tcpcb *
tcp_newtcpcb(struct inpcb *);
int      tcp_output(struct tcpcb *);
void     tcp_respond(struct tcpcb *, void *, struct tcphdr *, struct mbuf *,
    tcp_seq, tcp_seq, uint8_t, struct tcp_respond_args *);
struct rtentry *
tcp_rtlookup(struct inpcb *, unsigned int);
void     tcp_setpersist(struct tcpcb *);
void     tcp_gc(struct inpcbinfo *);
void     tcp_itimer(struct inpcbinfo *ipi);
void     tcp_check_timer_state(struct tcpcb *tp);
void     tcp_run_timerlist(void *arg1, void *arg2);
void     tcp_sched_timers(struct tcpcb *tp);

struct tcptemp *tcp_maketemplate(struct tcpcb *);
void     tcp_fillheaders(struct tcpcb *, void *, void *);
struct tcpcb *tcp_timers(struct tcpcb *, int);
void     tcp_trace(int, int, struct tcpcb *, void *, struct tcphdr *, int);

void tcp_fill_info(struct tcpcb *, struct tcp_info *);
void tcp_sack_doack(struct tcpcb *, struct tcpopt *, struct tcphdr *,
    u_int32_t *, uint32_t *);
extern boolean_t tcp_sack_process_dsack(struct tcpcb *, struct tcpopt *,
    struct tcphdr *);
int tcp_detect_bad_rexmt(struct tcpcb *, struct tcphdr *, struct tcpopt *,
    u_int32_t rxtime);
void     tcp_update_sack_list(struct tcpcb *tp, tcp_seq rcv_laststart, tcp_seq rcv_lastend);
void     tcp_clean_sackreport(struct tcpcb *tp);
void     tcp_sack_adjust(struct tcpcb *tp);
struct sackhole *tcp_sack_output(struct tcpcb *tp, int *sack_bytes_rexmt);
void     tcp_sack_partialack(struct tcpcb *, struct tcphdr *);
void     tcp_free_sackholes(struct tcpcb *tp);
void     tcp_sack_lost_rexmit(struct tcpcb *tp);
int32_t  tcp_sbspace(struct tcpcb *tp);
void     tcp_set_tso(struct tcpcb *tp, struct ifnet *ifp);
void     tcp_set_ecn(struct tcpcb *tp, struct ifnet *ifp);
int      tcp_flight_size(struct tcpcb *tp);
void     tcp_reset_stretch_ack(struct tcpcb *tp);
extern void tcp_get_ports_used(u_int32_t, int, u_int32_t, bitstr_t *);
uint32_t tcp_count_opportunistic(unsigned int ifindex, u_int32_t flags);
uint32_t tcp_find_anypcb_byaddr(struct ifaddr *ifa);
void tcp_set_max_rwinscale(struct tcpcb *tp, struct socket *so);
struct bwmeas* tcp_bwmeas_alloc(struct tcpcb *tp);
void tcp_bwmeas_free(struct tcpcb *tp);
extern int32_t timer_diff(uint32_t t1, uint32_t toff1, uint32_t t2, uint32_t toff2);

extern void tcp_set_background_cc(struct socket *);
extern void tcp_set_foreground_cc(struct socket *);
extern void tcp_set_recv_bg(struct socket *);
extern void tcp_clear_recv_bg(struct socket *);
extern boolean_t tcp_sack_byte_islost(struct tcpcb *tp);
#define IS_TCP_RECV_BG(_so)     \
	((_so)->so_flags1 & SOF1_TRAFFIC_MGT_TCP_RECVBG)

#if TRAFFIC_MGT
#define CLEAR_IAJ_STATE(_tp_) (_tp_)->iaj_rcv_ts = 0
void     reset_acc_iaj(struct tcpcb *tp);
#endif /* TRAFFIC_MGT */

int      tcp_lock(struct socket *, int, void *);
int      tcp_unlock(struct socket *, int, void *);
void     calculate_tcp_clock(void);

extern void tcp_keepalive_reset(struct tcpcb *);
extern uint32_t get_base_rtt(struct tcpcb *tp);

#ifdef _KERN_LOCKS_H_
lck_mtx_t *      tcp_getlock(struct socket *, int);
#else
void *   tcp_getlock(struct socket *, int);
#endif

extern  struct pr_usrreqs tcp_usrreqs;
extern  u_int32_t tcp_sendspace;
extern  u_int32_t tcp_recvspace;
tcp_seq tcp_new_isn(struct tcpcb *);

extern int tcp_input_checksum(int, struct mbuf *, struct tcphdr *, int, int);
extern void tcp_getconninfo(struct socket *, struct conninfo_tcp *);
extern void add_to_time_wait(struct tcpcb *, uint32_t delay);
extern void tcp_pmtud_revert_segment_size(struct tcpcb *tp);
extern void tcp_rxtseg_insert(struct tcpcb *, tcp_seq, tcp_seq);
extern struct tcp_rxt_seg *tcp_rxtseg_find(struct tcpcb *, tcp_seq, tcp_seq);
extern void tcp_rxtseg_set_spurious(struct tcpcb *tp, tcp_seq start, tcp_seq end);
extern void tcp_rxtseg_clean(struct tcpcb *);
extern boolean_t tcp_rxtseg_detect_bad_rexmt(struct tcpcb *, tcp_seq);
extern boolean_t tcp_rxtseg_dsack_for_tlp(struct tcpcb *);
extern u_int32_t tcp_rxtseg_total_size(struct tcpcb *tp);
extern void tcp_rexmt_save_state(struct tcpcb *tp);
extern void tcp_interface_send_probe(u_int16_t if_index_available);
extern void tcp_probe_connectivity(struct ifnet *ifp, u_int32_t enable);
extern void tcp_get_connectivity_status(struct tcpcb *,
    struct tcp_conn_status *);

extern void tcp_clear_keep_alive_offload(struct socket *so);
extern void tcp_fill_keepalive_offload_frames(struct ifnet *,
    struct ifnet_keepalive_offload_frame *, u_int32_t, size_t, u_int32_t *);
extern int tcp_notify_kao_timeout(ifnet_t ifp,
    struct ifnet_keepalive_offload_frame *frame);

extern boolean_t tfo_enabled(const struct tcpcb *tp);
extern void tcp_disable_tfo(struct tcpcb *tp);
extern void tcp_tfo_gen_cookie(struct inpcb *inp, u_char *out, size_t blk_size);
#define TCP_FASTOPEN_KEYLEN 16
extern int tcp_freeq(struct tcpcb *tp);
extern errno_t tcp_notify_ack_id_valid(struct tcpcb *, struct socket *, u_int32_t);
extern errno_t tcp_add_notify_ack_marker(struct tcpcb *, u_int32_t);
extern void tcp_notify_ack_free(struct tcpcb *);
extern void tcp_notify_acknowledgement(struct tcpcb *, struct socket *);
extern void tcp_get_notify_ack_count(struct tcpcb *,
    struct tcp_notify_ack_complete *);
extern void tcp_get_notify_ack_ids(struct tcpcb *tp,
    struct tcp_notify_ack_complete *);
extern void tcp_update_mss_locked(struct socket *, struct ifnet *);

extern int get_tcp_inp_list(struct inpcb **, int, inp_gen_t);
extern bool tcp_notify_ack_active(struct socket *so);

#if MPTCP
extern int mptcp_input_preproc(struct tcpcb *tp, struct mbuf *m,
    struct tcphdr *th, int drop_hdrlen);
extern uint16_t mptcp_output_csum(struct mbuf *m, uint64_t dss_val,
    uint32_t sseq, uint16_t dlen);
extern int mptcp_adj_mss(struct tcpcb *, boolean_t);
extern void mptcp_insert_rmap(struct tcpcb *tp, struct mbuf *m, struct tcphdr *th);
#endif

__private_extern__ void tcp_update_stats_per_flow(
	struct ifnet_stats_per_flow *, struct ifnet *);

#define TCP_ACK_STRATEGY_LEGACY 0
#define TCP_ACK_STRATEGY_MODERN 1

extern int tcp_ack_strategy;

#define tcp_add_fsw_flow(...)
#define tcp_del_fsw_flow(...)

#endif /* BSD_KERNEL_PRIVATE */

#endif /* _NETINET_TCP_VAR_H_ */