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