1 /*-
2  * Copyright (c) 1982, 1986, 1993, 1994, 1995
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 4. Neither the name of the University nor the names of its contributors
14  *    may be used to endorse or promote products derived from this software
15  *    without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  *	@(#)tcp_var.h	8.4 (Berkeley) 5/24/95
30  * $FreeBSD$
31  */
32 
33 #ifndef TCPLP_NETINET_TCP_VAR_H_
34 #define TCPLP_NETINET_TCP_VAR_H_
35 
36 /* For memmove(). */
37 #include <string.h>
38 
39 /* Dependencies on OpenThread. */
40 #include <openthread/ip6.h>
41 #include <openthread/message.h>
42 
43 /* Dependencies on TCPlp buffering libraries. */
44 #include "../lib/bitmap.h"
45 #include "../lib/cbuf.h"
46 #include "../lib/lbuf.h"
47 
48 #include "cc.h"
49 #include "tcp.h"
50 #include "types.h"
51 #include "ip6.h"
52 
53 #define TCP_RFC7413
54 
55 /* Implement byte-order-specific functions using OpenThread. */
56 uint16_t tcplp_sys_hostswap16(uint16_t hostport);
57 uint32_t tcplp_sys_hostswap32(uint32_t hostport);
58 
59 /*
60  * It seems that these are defined as macros in Mac OS X, which is why we need
61  * the #ifndef checks. Simply redefining them as functions would break the
62  * build.
63  */
64 
65 #ifndef htons
htons(uint16_t hostport)66 static inline uint16_t htons(uint16_t hostport) {
67 	return tcplp_sys_hostswap16(hostport);
68 }
69 #endif
70 
71 #ifndef ntohs
ntohs(uint16_t hostport)72 static inline uint16_t ntohs(uint16_t hostport) {
73 	return tcplp_sys_hostswap16(hostport);
74 }
75 #endif
76 
77 #ifndef htonl
htonl(uint32_t hostport)78 static inline uint32_t htonl(uint32_t hostport) {
79 	return tcplp_sys_hostswap32(hostport);
80 }
81 #endif
82 
83 #ifndef ntohl
ntohl(uint32_t hostport)84 static inline uint32_t ntohl(uint32_t hostport) {
85 	return tcplp_sys_hostswap32(hostport);
86 }
87 #endif
88 
89 // From ip_compat.h
90 #ifndef bcopy
91 #define	bcopy(a,b,c)	memmove(b,a,c)
92 #endif
93 
94 #ifndef bzero
95 #define bzero(a,b)	memset(a,0x00,b)
96 #endif
97 
98 struct sackblk {
99 	tcp_seq start;		/* start seq no. of sack block */
100 	tcp_seq end;		/* end seq no. */
101 };
102 
103 struct sackhole {
104 	tcp_seq start;		/* start seq no. of hole */
105 	tcp_seq end;		/* end seq no. */
106 	tcp_seq rxmit;		/* next seq. no in hole to be retransmitted */
107 
108 	/*
109 	 * samkumar: I'm using this instead of the TAILQ_ENTRY macro to avoid
110 	 * including sys/queue.h from this file. It's undesirable to include
111 	 * sys/queue.h from this file because this file is part of the external
112 	 * interface to TCPlp, and sys/queue.h pollutes the global namespace.
113 	 * The original code that uses TAILQ_ENTRY is in a comment below.
114 	 */
115 	struct {
116 		struct sackhole *tqe_next;	/* next element */
117 		struct sackhole **tqe_prev;	/* address of previous next element */
118 	} scblink;	/* scoreboard linkage */
119 	// TAILQ_ENTRY(sackhole) scblink;	/* scoreboard linkage */
120 };
121 
122 struct sackhint {
123 	struct sackhole	*nexthole;
124 	int		sack_bytes_rexmit;
125 	tcp_seq		last_sack_ack;	/* Most recent/largest sacked ack */
126 };
127 
128 struct tcptemp {
129 	uint8_t	tt_ipgen[40]; /* the size must be of max ip header, now IPv6 */
130 	struct	tcphdr tt_t;
131 };
132 
133 #define tcp6cb		tcpcb  /* for KAME src sync over BSD*'s */
134 
135 /* Abridged TCB for passive sockets. */
136 struct tcpcb_listen {
137     int t_state;     /* Always CLOSED or LISTEN. */
138     otInstance* instance;
139 	struct in6_addr laddr;
140     uint16_t lport;
141 };
142 
143 #define TCB_CANTRCVMORE 0x20
144 #define TCB_CANTSENDMORE 0x40
145 
146 #define TCB_PASSIVE 0x80
147 
148 #define tpcantrcvmore(tp) (tp)->miscflags |= TCB_CANTRCVMORE
149 #define tpcantsendmore(tp) (tp)->miscflags |= TCB_CANTSENDMORE
150 #define tpiscantrcv(tp) (((tp)->miscflags & TCB_CANTRCVMORE) != 0)
151 #define tpiscantsend(tp) (((tp)->miscflags & TCB_CANTSENDMORE) != 0)
152 #define tpmarktimeractive(tp, timer) (tp)->miscflags |= timer
153 #define tpistimeractive(tp, timer) (((tp)->miscflags & timer) != 0)
154 #define tpcleartimeractive(tp, timer) (tp)->miscflags &= ~timer
155 #define tpmarkpassiveopen(tp) (tp)->miscflags |= TCB_PASSIVE
156 #define tpispassiveopen(tp) (((tp)->miscflags & TCB_PASSIVE) != 0)
157 
158 #define REASSBMP_SIZE(tp) BITS_TO_BYTES((tp)->recvbuf.size)
159 
160 /* These estimates are used to allocate sackholes (see tcp_sack.c). */
161 #define AVG_SACKHOLES 2 // per TCB
162 #define MAX_SACKHOLES 5 // per TCB
163 #define SACKHOLE_POOL_SIZE MAX_SACKHOLES
164 #define SACKHOLE_BMP_SIZE BITS_TO_BYTES(SACKHOLE_POOL_SIZE)
165 
166 struct tcplp_signals;
167 
168 /*
169  * Tcp control block, one per tcp; fields:
170  * Organized for 16 byte cacheline efficiency.
171  */
172 /*
173  * samkumar: I added some fields for TCPlp to the beginning of this structure,
174  * replaced the fields for buffering and timers, and deleted unused fields to
175  * save memory. I've left some of the deleted fields in, as comments, for
176  * clarity. At times, I reduced the configurability of the implementation
177  * (e.g., by removing the ability to set keepalive parameters) in order to
178  * reduce the size of this structure.
179  */
180 struct tcpcb {
181 	/*
182 	 * samkumar: Extra fields that I added. TCPlp doesn't have a struct inpcb,
183 	 * so some of the fields I added represent data that would normally be
184 	 * stored in the inpcb.
185 	 */
186 	otInstance *instance;
187 
188 	struct tcpcb_listen* accepted_from;
189 
190 	struct lbufhead sendbuf;
191 	struct cbufhead recvbuf;
192 	uint8_t* reassbmp;
193 	int32_t reass_fin_index;
194 
195 	struct in6_addr laddr; // local IP address
196 	struct in6_addr faddr; // foreign IP address
197 
198 	uint16_t lport; // local port, network byte order
199 	uint16_t fport; // foreign port, network byte order
200 	uint8_t miscflags;
201 
202 	/* samkumar: This field was there previously. */
203 	uint8_t	t_state;		/* state of this connection */
204 
205 	/* Pool of SACK holes (on per-connection basis, for OpenThread port). */
206 	struct sackhole sackhole_pool[SACKHOLE_POOL_SIZE];
207 	uint8_t sackhole_bmp[SACKHOLE_BMP_SIZE];
208 
209 #if 0
210 	struct	tsegqe_head t_segq;	/* segment reassembly queue */
211 	void	*t_pspare[2];		/* new reassembly queue */
212 	int	t_segqlen;		/* segment reassembly queue length */
213 #endif
214 
215 	int32_t	t_dupacks;		/* consecutive dup acks recd */
216 
217 #if 0
218 	struct tcp_timer *t_timers;	/* All the TCP timers in one struct */
219 
220 	struct	inpcb *t_inpcb;		/* back pointer to internet pcb */
221 #endif
222 
223 	uint16_t	tw_last_win; // samkumar: Taken from struct tcptw
224 
225 	uint32_t	t_flags;
226 
227 //	struct	vnet *t_vnet;		/* back pointer to parent vnet */
228 
229 	tcp_seq	snd_una;		/* sent but unacknowledged */
230 	tcp_seq	snd_max;		/* highest sequence number sent;
231 					 * used to recognize retransmits
232 					 */
233 	tcp_seq	snd_nxt;		/* send next */
234 	tcp_seq	snd_up;			/* send urgent pointer */
235 
236 	tcp_seq	snd_wl1;		/* window update seg seq number */
237 	tcp_seq	snd_wl2;		/* window update seg ack number */
238 	tcp_seq	iss;			/* initial send sequence number */
239 	tcp_seq	irs;			/* initial receive sequence number */
240 
241 	tcp_seq	rcv_nxt;		/* receive next */
242 	tcp_seq	rcv_adv;		/* advertised window */
243 	tcp_seq	rcv_up;			/* receive urgent pointer */
244 	uint64_t	rcv_wnd;		/* receive window */
245 
246 	uint64_t	snd_wnd;		/* send window */
247 	uint64_t	snd_cwnd;		/* congestion-controlled window */
248 //	uint64_t	snd_spare1;		/* unused */
249 	uint64_t	snd_ssthresh;		/* snd_cwnd size threshold for
250 					 * for slow start exponential to
251 					 * linear switch
252 					 */
253 //	uint64_t	snd_spare2;		/* unused */
254 	tcp_seq	snd_recover;		/* for use in NewReno Fast Recovery */
255 
256 	uint32_t	t_maxopd;		/* mss plus options */
257 
258 	uint32_t	t_rcvtime;		/* inactivity time */
259 	uint32_t	t_starttime;		/* time connection was established */
260 	uint32_t	t_rtttime;		/* RTT measurement start time */
261 	tcp_seq	t_rtseq;		/* sequence number being timed */
262 
263 //	uint32_t	t_bw_spare1;		/* unused */
264 //	tcp_seq	t_bw_spare2;		/* unused */
265 
266 	int32_t	t_rxtcur;		/* current retransmit value (ticks) */
267 	uint32_t	t_maxseg;		/* maximum segment size */
268 	int32_t	t_srtt;			/* smoothed round-trip time */
269 	int32_t	t_rttvar;		/* variance in round-trip time */
270 
271 	int32_t	t_rxtshift;		/* log(2) of rexmt exp. backoff */
272 	uint32_t	t_rttmin;		/* minimum rtt allowed */
273 	uint32_t	t_rttbest;		/* best rtt we've seen */
274 
275 	int32_t	t_softerror;		/* possible error not yet reported */
276 
277 	uint64_t	t_rttupdated;		/* number of times rtt sampled */
278 	uint64_t	max_sndwnd;		/* largest window peer has offered */
279 /* out-of-band data */
280 //	char	t_oobflags;		/* have some */
281 //	char	t_iobc;			/* input character */
282 
283 	tcp_seq	last_ack_sent;
284 /* experimental */
285 	tcp_seq	snd_recover_prev;	/* snd_recover prior to retransmit */
286 	uint64_t	snd_cwnd_prev;		/* cwnd prior to retransmit */
287 	uint64_t	snd_ssthresh_prev;	/* ssthresh prior to retransmit */
288 //	int	t_sndzerowin;		/* zero-window updates sent */
289 	uint32_t	t_badrxtwin;		/* window for retransmit recovery */
290 	uint8_t	snd_limited;		/* segments limited transmitted */
291 
292 /* RFC 1323 variables */
293 /*
294  * samkumar: Moved "RFC 1323 variables" after "experimental" to reduce
295  * compiler-inserted padding.
296  */
297 	uint8_t	snd_scale;		/* window scaling for send window */
298 	uint8_t	rcv_scale;		/* window scaling for recv window */
299 	uint8_t	request_r_scale;	/* pending window scaling */
300 	u_int32_t  ts_recent;		/* timestamp echo data */
301 	uint32_t	ts_recent_age;		/* when last updated */
302 	u_int32_t  ts_offset;		/* our timestamp offset */
303 
304 /* SACK related state */
305 	int32_t	snd_numholes;		/* number of holes seen by sender */
306 	/*
307 	 * samkumar: I replaced the TAILQ_HEAD macro invocation (commented out
308 	 * below) with the code it stands for, to avoid having to #include
309 	 * sys/queue.h in this file. See the comment above in struct sackhole for
310 	 * more info.
311 	 */
312 	struct sackhole_head {
313 		struct sackhole *tqh_first;	/* first element */
314 		struct sackhole **tqh_last;	/* addr of last next element */
315 	} snd_holes;
316 	// TAILQ_HEAD(sackhole_head, sackhole) snd_holes;
317 					/* SACK scoreboard (sorted) */
318 	tcp_seq	snd_fack;		/* last seq number(+1) sack'd by rcv'r*/
319 	int32_t	rcv_numsacks;		/* # distinct sack blks present */
320 	struct sackblk sackblks[MAX_SACK_BLKS]; /* seq nos. of sack blocks */
321 	tcp_seq sack_newdata;		/* New data xmitted in this recovery
322 					   episode starts at this seq number */
323 	struct sackhint	sackhint;	/* SACK scoreboard hint */
324 
325 	int32_t	t_rttlow;		/* smallest observed RTT */
326 #if 0
327 	u_int32_t	rfbuf_ts;	/* recv buffer autoscaling timestamp */
328 	int	rfbuf_cnt;		/* recv buffer autoscaling byte count */
329 	struct toedev	*tod;		/* toedev handling this connection */
330 #endif
331 //	int	t_sndrexmitpack;	/* retransmit packets sent */
332 //	int	t_rcvoopack;		/* out-of-order packets received */
333 //	void	*t_toe;			/* TOE pcb pointer */
334 	int32_t	t_bytes_acked;		/* # bytes acked during current RTT */
335 //	struct cc_algo	*cc_algo;	/* congestion control algorithm */
336 	struct cc_var	ccv[1];		/* congestion control specific vars */
337 #if 0
338 	struct osd	*osd;		/* storage for Khelp module data */
339 #endif
340 #if 0 // Just use the default values for the KEEP constants (see tcp_timer.h)
341 	uint32_t	t_keepinit;		/* time to establish connection */
342 	uint32_t	t_keepidle;		/* time before keepalive probes begin */
343 	uint32_t	t_keepintvl;		/* interval between keepalives */
344 	uint32_t	t_keepcnt;		/* number of keepalives before close */
345 #endif
346 #if 0 // Don't support TCP Segment Offloading
347 	uint32_t	t_tsomax;		/* TSO total burst length limit in bytes */
348 	uint32_t	t_tsomaxsegcount;	/* TSO maximum segment count */
349 	uint32_t	t_tsomaxsegsize;	/* TSO maximum segment size in bytes */
350 #endif
351 //	uint32_t	t_pmtud_saved_maxopd;	/* pre-blackhole MSS */
352 	uint32_t	t_flags2;		/* More tcpcb flags storage */
353 
354 //	uint32_t t_ispare[8];		/* 5 UTO, 3 TBD */
355 //	void	*t_pspare2[4];		/* 1 TCP_SIGNATURE, 3 TBD */
356 
357     /* samkumar: TFO fields from FreeBSD 12.0. */
358 	uint64_t t_tfo_client_cookie_len; /* TCP Fast Open client cookie length */
359 //	unsigned int *t_tfo_pending;	/* TCP Fast Open server pending counter */
360 	union {
361 		uint8_t client[TCP_FASTOPEN_MAX_COOKIE_LEN];
362 		uint64_t server;
363 	} t_tfo_cookie;			/* TCP Fast Open cookie to send */
364 #if 0
365 #if defined(_KERNEL) && defined(TCPPCAP)
366 	struct mbufq t_inpkts;		/* List of saved input packets. */
367 	struct mbufq t_outpkts;		/* List of saved output packets. */
368 #ifdef _LP64
369 	uint64_t _pad[0];		/* all used! */
370 #else
371 	uint64_t _pad[2];		/* 2 are available */
372 #endif /* _LP64 */
373 #else
374 	uint64_t _pad[6];
375 #endif /* defined(_KERNEL) && defined(TCPPCAP) */
376 #endif
377 };
378 
379 /* Defined in tcp_subr.c. */
380 void initialize_tcb(struct tcpcb* tp);
381 
382 /* Copied from the "dead" portions below. */
383 
384 void	 tcp_init(void);
385 void	 tcp_state_change(struct tcpcb *, int);
386 tcp_seq tcp_new_isn(struct tcpcb *);
387 struct tcpcb *tcp_close(struct tcpcb *);
388 struct tcpcb *tcp_drop(struct tcpcb *, int);
389 void
390 tcp_respond(struct tcpcb *tp, otInstance* instance, struct ip6_hdr* ip6gen, struct tcphdr *thgen,
391     tcp_seq ack, tcp_seq seq, int flags);
392 void	 tcp_setpersist(struct tcpcb *);
393 void	cc_cong_signal(struct tcpcb *tp, struct tcphdr *th, uint32_t type);
394 
395 /* Added, since there is no header file for tcp_usrreq.c. */
396 int tcp6_usr_connect(struct tcpcb* tp, struct sockaddr_in6* sinp6);
397 int tcp_usr_send(struct tcpcb* tp, int moretocome, struct otLinkedBuffer* data, size_t extendby, struct sockaddr_in6* nam);
398 int tcp_usr_rcvd(struct tcpcb* tp);
399 int tcp_usr_shutdown(struct tcpcb* tp);
400 void tcp_usr_abort(struct tcpcb* tp);
401 
402 /*
403  * Flags and utility macros for the t_flags field.
404  */
405 #define	TF_ACKNOW	0x000001	/* ack peer immediately */
406 #define	TF_DELACK	0x000002	/* ack, but try to delay it */
407 #define	TF_NODELAY	0x000004	/* don't delay packets to coalesce */
408 #define	TF_NOOPT	0x000008	/* don't use tcp options */
409 #define	TF_SENTFIN	0x000010	/* have sent FIN */
410 #define	TF_REQ_SCALE	0x000020	/* have/will request window scaling */
411 #define	TF_RCVD_SCALE	0x000040	/* other side has requested scaling */
412 #define	TF_REQ_TSTMP	0x000080	/* have/will request timestamps */
413 #define	TF_RCVD_TSTMP	0x000100	/* a timestamp was received in SYN */
414 #define	TF_SACK_PERMIT	0x000200	/* other side said I could SACK */
415 #define	TF_NEEDSYN	0x000400	/* send SYN (implicit state) */
416 #define	TF_NEEDFIN	0x000800	/* send FIN (implicit state) */
417 #define	TF_NOPUSH	0x001000	/* don't push */
418 #define	TF_PREVVALID	0x002000	/* saved values for bad rxmit valid */
419 #define	TF_MORETOCOME	0x010000	/* More data to be appended to sock */
420 #define	TF_LQ_OVERFLOW	0x020000	/* listen queue overflow */
421 #define	TF_LASTIDLE	0x040000	/* connection was previously idle */
422 #define	TF_RXWIN0SENT	0x080000	/* sent a receiver win 0 in response */
423 #define	TF_FASTRECOVERY	0x100000	/* in NewReno Fast Recovery */
424 #define	TF_WASFRECOVERY	0x200000	/* was in NewReno Fast Recovery */
425 #define	TF_SIGNATURE	0x400000	/* require MD5 digests (RFC2385) */
426 #define	TF_FORCEDATA	0x800000	/* force out a byte */
427 #define	TF_TSO		0x1000000	/* TSO enabled on this connection */
428 #define	TF_TOE		0x2000000	/* this connection is offloaded */
429 #define	TF_ECN_PERMIT	0x4000000	/* connection ECN-ready */
430 #define	TF_ECN_SND_CWR	0x8000000	/* ECN CWR in queue */
431 #define	TF_ECN_SND_ECE	0x10000000	/* ECN ECE in queue */
432 #define	TF_CONGRECOVERY	0x20000000	/* congestion recovery mode */
433 #define	TF_WASCRECOVERY	0x40000000	/* was in congestion recovery */
434 #define	TF_FASTOPEN	0x80000000	/* TCP Fast Open indication */
435 
436 #define	IN_FASTRECOVERY(t_flags)	(t_flags & TF_FASTRECOVERY)
437 #define	ENTER_FASTRECOVERY(t_flags)	t_flags |= TF_FASTRECOVERY
438 #define	EXIT_FASTRECOVERY(t_flags)	t_flags &= ~TF_FASTRECOVERY
439 
440 #define	IN_CONGRECOVERY(t_flags)	(t_flags & TF_CONGRECOVERY)
441 #define	ENTER_CONGRECOVERY(t_flags)	t_flags |= TF_CONGRECOVERY
442 #define	EXIT_CONGRECOVERY(t_flags)	t_flags &= ~TF_CONGRECOVERY
443 
444 #define	IN_RECOVERY(t_flags) (t_flags & (TF_CONGRECOVERY | TF_FASTRECOVERY))
445 #define	ENTER_RECOVERY(t_flags) t_flags |= (TF_CONGRECOVERY | TF_FASTRECOVERY)
446 #define	EXIT_RECOVERY(t_flags) t_flags &= ~(TF_CONGRECOVERY | TF_FASTRECOVERY)
447 
448 #ifndef TCP_RFC7413
449 #define	IS_FASTOPEN(t_flags)		(false)
450 #else
451 #define	IS_FASTOPEN(t_flags)		(t_flags & TF_FASTOPEN)
452 #endif
453 
454 #define	BYTES_THIS_ACK(tp, th)	(th->th_ack - tp->snd_una)
455 
456 /*
457  * Flags for the t_oobflags field.
458  */
459 #define	TCPOOB_HAVEDATA	0x01
460 #define	TCPOOB_HADDATA	0x02
461 
462 #ifdef TCP_SIGNATURE
463 /*
464  * Defines which are needed by the xform_tcp module and tcp_[in|out]put
465  * for SADB verification and lookup.
466  */
467 #define	TCP_SIGLEN	16	/* length of computed digest in bytes */
468 #define	TCP_KEYLEN_MIN	1	/* minimum length of TCP-MD5 key */
469 #define	TCP_KEYLEN_MAX	80	/* maximum length of TCP-MD5 key */
470 /*
471  * Only a single SA per host may be specified at this time. An SPI is
472  * needed in order for the KEY_ALLOCSA() lookup to work.
473  */
474 #define	TCP_SIG_SPI	0x1000
475 #endif /* TCP_SIGNATURE */
476 
477 /*
478  * Flags for PLPMTU handling, t_flags2
479  */
480 #define	TF2_PLPMTU_BLACKHOLE	0x00000001 /* Possible PLPMTUD Black Hole. */
481 #define	TF2_PLPMTU_PMTUD	0x00000002 /* Allowed to attempt PLPMTUD. */
482 #define	TF2_PLPMTU_MAXSEGSNT	0x00000004 /* Last seg sent was full seg. */
483 
484 /*
485  * Structure to hold TCP options that are only used during segment
486  * processing (in tcp_input), but not held in the tcpcb.
487  * It's basically used to reduce the number of parameters
488  * to tcp_dooptions and tcp_addoptions.
489  * The binary order of the to_flags is relevant for packing of the
490  * options in tcp_addoptions.
491  */
492 struct tcpopt {
493 	u_int64_t	to_flags;	/* which options are present */
494 #define	TOF_MSS		0x0001		/* maximum segment size */
495 #define	TOF_SCALE	0x0002		/* window scaling */
496 #define	TOF_SACKPERM	0x0004		/* SACK permitted */
497 #define	TOF_TS		0x0010		/* timestamp */
498 #define	TOF_SIGNATURE	0x0040		/* TCP-MD5 signature option (RFC2385) */
499 #define	TOF_SACK	0x0080		/* Peer sent SACK option */
500 #define	TOF_FASTOPEN	0x0100		/* TCP Fast Open (TFO) cookie */
501 #define	TOF_MAXOPT	0x0200
502 	u_int32_t	to_tsval;	/* new timestamp */
503 	u_int32_t	to_tsecr;	/* reflected timestamp */
504 	uint8_t		*to_sacks;	/* pointer to the first SACK blocks */
505 	uint8_t		*to_signature;	/* pointer to the TCP-MD5 signature */
506 	u_int8_t	*to_tfo_cookie; /* pointer to the TFO cookie */
507 	u_int16_t	to_mss;		/* maximum segment size */
508 	u_int8_t	to_wscale;	/* window scaling */
509 	u_int8_t	to_nsacks;	/* number of SACK blocks */
510 	u_int8_t	to_tfo_len;	/* TFO cookie length */
511 	u_int32_t	to_spare;	/* UTO */
512 };
513 
514 /*
515  * Flags for tcp_dooptions.
516  */
517 #define	TO_SYN		0x01		/* parse SYN-only options */
518 
519 struct hc_metrics_lite {	/* must stay in sync with hc_metrics */
520 	uint64_t	rmx_mtu;	/* MTU for this path */
521 	uint64_t	rmx_ssthresh;	/* outbound gateway buffer limit */
522 	uint64_t	rmx_rtt;	/* estimated round trip time */
523 	uint64_t	rmx_rttvar;	/* estimated rtt variance */
524 	uint64_t	rmx_bandwidth;	/* estimated bandwidth */
525 	uint64_t	rmx_cwnd;	/* congestion window */
526 	uint64_t	rmx_sendpipe;   /* outbound delay-bandwidth product */
527 	uint64_t	rmx_recvpipe;   /* inbound delay-bandwidth product */
528 };
529 
530 /*
531  * Used by tcp_maxmtu() to communicate interface specific features
532  * and limits at the time of connection setup.
533  */
534 struct tcp_ifcap {
535 	int	ifcap;
536 	uint32_t	tsomax;
537 	uint32_t	tsomaxsegcount;
538 	uint32_t	tsomaxsegsize;
539 };
540 
541 void	 tcp_mss(struct tcpcb *, int);
542 void	 tcp_mss_update(struct tcpcb *, int, int, struct hc_metrics_lite *,
543 	    struct tcp_ifcap *);
544 
545 /*
546  * The smoothed round-trip time and estimated variance
547  * are stored as fixed point numbers scaled by the values below.
548  * For convenience, these scales are also used in smoothing the average
549  * (smoothed = (1/scale)sample + ((scale-1)/scale)smoothed).
550  * With these scales, srtt has 3 bits to the right of the binary point,
551  * and thus an "ALPHA" of 0.875.  rttvar has 2 bits to the right of the
552  * binary point, and is smoothed with an ALPHA of 0.75.
553  */
554 #define	TCP_RTT_SCALE		32	/* multiplier for srtt; 3 bits frac. */
555 #define	TCP_RTT_SHIFT		5	/* shift for srtt; 3 bits frac. */
556 #define	TCP_RTTVAR_SCALE	16	/* multiplier for rttvar; 2 bits */
557 #define	TCP_RTTVAR_SHIFT	4	/* shift for rttvar; 2 bits */
558 #define	TCP_DELTA_SHIFT		2	/* see tcp_input.c */
559 
560 /* My definition of the max macro */
561 #define max(x, y) ((x) > (y) ? (x) : (y))
562 
563 /*
564  * The initial retransmission should happen at rtt + 4 * rttvar.
565  * Because of the way we do the smoothing, srtt and rttvar
566  * will each average +1/2 tick of bias.  When we compute
567  * the retransmit timer, we want 1/2 tick of rounding and
568  * 1 extra tick because of +-1/2 tick uncertainty in the
569  * firing of the timer.  The bias will give us exactly the
570  * 1.5 tick we need.  But, because the bias is
571  * statistical, we have to test that we don't drop below
572  * the minimum feasible timer (which is 2 ticks).
573  * This version of the macro adapted from a paper by Lawrence
574  * Brakmo and Larry Peterson which outlines a problem caused
575  * by insufficient precision in the original implementation,
576  * which results in inappropriately large RTO values for very
577  * fast networks.
578  */
579 #define	TCP_REXMTVAL(tp) \
580 	max((tp)->t_rttmin, (((tp)->t_srtt >> (TCP_RTT_SHIFT - TCP_DELTA_SHIFT))  \
581 	  + (tp)->t_rttvar) >> TCP_DELTA_SHIFT)
582 
583 /* Copied from below. */
584 static inline void
tcp_fields_to_host(struct tcphdr * th)585 tcp_fields_to_host(struct tcphdr *th)
586 {
587 
588 	th->th_seq = ntohl(th->th_seq);
589 	th->th_ack = ntohl(th->th_ack);
590 	th->th_win = ntohs(th->th_win);
591 	th->th_urp = ntohs(th->th_urp);
592 }
593 
594 void	 tcp_twstart(struct tcpcb*);
595 void	 tcp_twclose(struct tcpcb*, int);
596 int	 tcp_twcheck(struct tcpcb*, struct tcphdr *, int);
597 void tcp_dropwithreset(struct ip6_hdr* ip6, struct tcphdr *th, struct tcpcb *tp, otInstance* instance,
598     int tlen, int rstreason);
599 int tcp_input(struct ip6_hdr* ip6, struct tcphdr* th, otMessage* msg, struct tcpcb* tp, struct tcpcb_listen* tpl,
600           struct tcplp_signals* sig);
601 int	 tcp_output(struct tcpcb *);
602 void tcpip_maketemplate(struct tcpcb *, struct tcptemp*);
603 void	 tcpip_fillheaders(struct tcpcb *, otMessageInfo *, void *);
604 uint64_t	 tcp_maxmtu6(struct tcpcb*, struct tcp_ifcap *);
605 int	 tcp_addoptions(struct tcpopt *, uint8_t *);
606 int	 tcp_mssopt(struct tcpcb*);
607 int	 tcp_reass(struct tcpcb *, struct tcphdr *, int *, otMessage *, off_t, struct tcplp_signals*);
608 void tcp_sack_init(struct tcpcb *); // Sam: new function that I added
609 void	 tcp_sack_doack(struct tcpcb *, struct tcpopt *, tcp_seq);
610 void	 tcp_update_sack_list(struct tcpcb *tp, tcp_seq rcv_laststart, tcp_seq rcv_lastend);
611 void	 tcp_clean_sackreport(struct tcpcb *tp);
612 void	 tcp_sack_adjust(struct tcpcb *tp);
613 struct sackhole *tcp_sack_output(struct tcpcb *tp, int *sack_bytes_rexmt);
614 void	 tcp_sack_partialack(struct tcpcb *, struct tcphdr *);
615 void	 tcp_free_sackholes(struct tcpcb *tp);
616 
617 #define	tcps_rcvmemdrop	tcps_rcvreassfull	/* compat */0
618 
619 /*
620  * Identifiers for TCP sysctl nodes
621  */
622 #define	TCPCTL_DO_RFC1323	1	/* use RFC-1323 extensions */
623 #define	TCPCTL_MSSDFLT		3	/* MSS default */
624 #define TCPCTL_STATS		4	/* statistics (read-only) */
625 #define	TCPCTL_RTTDFLT		5	/* default RTT estimate */
626 #define	TCPCTL_KEEPIDLE		6	/* keepalive idle timer */
627 #define	TCPCTL_KEEPINTVL	7	/* interval to send keepalives */
628 #define	TCPCTL_SENDSPACE	8	/* send buffer space */
629 #define	TCPCTL_RECVSPACE	9	/* receive buffer space */
630 #define	TCPCTL_KEEPINIT		10	/* timeout for establishing syn */
631 #define	TCPCTL_PCBLIST		11	/* list of all outstanding PCBs */
632 #define	TCPCTL_DELACKTIME	12	/* time before sending delayed ACK */
633 #define	TCPCTL_V6MSSDFLT	13	/* MSS default for IPv6 */
634 #define	TCPCTL_SACK		14	/* Selective Acknowledgement,rfc 2018 */
635 #define	TCPCTL_DROP		15	/* drop tcp connection */
636 
637 #endif /* _NETINET_TCP_VAR_H_ */
638