1*76404edcSAsim Jamshed #ifndef __TCP_IN_H_
2*76404edcSAsim Jamshed #define __TCP_IN_H_
3*76404edcSAsim Jamshed 
4*76404edcSAsim Jamshed #ifdef DARWIN
5*76404edcSAsim Jamshed #include <netinet/if_ether.h>
6*76404edcSAsim Jamshed #include <netinet/tcp.h>
7*76404edcSAsim Jamshed #include <netinet/udp.h>
8*76404edcSAsim Jamshed #else
9*76404edcSAsim Jamshed #include <linux/if_ether.h>
10*76404edcSAsim Jamshed #include <linux/tcp.h>
11*76404edcSAsim Jamshed #include <linux/udp.h>
12*76404edcSAsim Jamshed #endif
13*76404edcSAsim Jamshed #include <netinet/ip.h>
14*76404edcSAsim Jamshed 
15*76404edcSAsim Jamshed #include "mos_api.h"
16*76404edcSAsim Jamshed #include "mtcp.h"
17*76404edcSAsim Jamshed #include "fhash.h"
18*76404edcSAsim Jamshed 
19*76404edcSAsim Jamshed #define TCP_FLAG_FIN	0x01	// 0000 0001
20*76404edcSAsim Jamshed #define TCP_FLAG_SYN	0x02	// 0000 0010
21*76404edcSAsim Jamshed #define TCP_FLAG_RST	0x04	// 0000 0100
22*76404edcSAsim Jamshed #define TCP_FLAG_PSH	0x08	// 0000 1000
23*76404edcSAsim Jamshed #define TCP_FLAG_ACK	0x10	// 0001 0000
24*76404edcSAsim Jamshed #define TCP_FLAG_URG	0x20	// 0010 0000
25*76404edcSAsim Jamshed #define TCP_FLAG_SACK	0x40	// 0100 0000
26*76404edcSAsim Jamshed #define TCP_FLAG_WACK	0x80	// 1000 0000
27*76404edcSAsim Jamshed 
28*76404edcSAsim Jamshed #define TCP_OPT_FLAG_MSS			0x02	// 0000 0010
29*76404edcSAsim Jamshed #define TCP_OPT_FLAG_WSCALE			0x04	// 0000 0100
30*76404edcSAsim Jamshed #define TCP_OPT_FLAG_SACK_PERMIT	0x08	// 0000 1000
31*76404edcSAsim Jamshed #define TCP_OPT_FLAG_SACK			0x10	// 0001 0000
32*76404edcSAsim Jamshed #define TCP_OPT_FLAG_TIMESTAMP		0x20	// 0010 0000
33*76404edcSAsim Jamshed 
34*76404edcSAsim Jamshed #define TCP_OPT_MSS_LEN			4
35*76404edcSAsim Jamshed #define TCP_OPT_WSCALE_LEN		3
36*76404edcSAsim Jamshed #define TCP_OPT_SACK_PERMIT_LEN	2
37*76404edcSAsim Jamshed #define TCP_OPT_SACK_LEN		10
38*76404edcSAsim Jamshed #define TCP_OPT_TIMESTAMP_LEN	10
39*76404edcSAsim Jamshed 
40*76404edcSAsim Jamshed #define TCP_DEFAULT_MSS			1460
41*76404edcSAsim Jamshed #define TCP_DEFAULT_WSCALE		7
42*76404edcSAsim Jamshed #define TCP_INITIAL_WINDOW		14600	// initial window size
43*76404edcSAsim Jamshed 
44*76404edcSAsim Jamshed #define TCP_SEQ_LT(a,b) 		((int32_t)((a)-(b)) < 0)
45*76404edcSAsim Jamshed #define TCP_SEQ_LEQ(a,b)		((int32_t)((a)-(b)) <= 0)
46*76404edcSAsim Jamshed #define TCP_SEQ_GT(a,b) 		((int32_t)((a)-(b)) > 0)
47*76404edcSAsim Jamshed #define TCP_SEQ_GEQ(a,b)		((int32_t)((a)-(b)) >= 0)
48*76404edcSAsim Jamshed #define TCP_SEQ_BETWEEN(a,b,c)	(TCP_SEQ_GEQ(a,b) && TCP_SEQ_LEQ(a,c))
49*76404edcSAsim Jamshed 
50*76404edcSAsim Jamshed /* convert timeval to timestamp (precision: 10us) */
51*76404edcSAsim Jamshed #define HZ						1000
52*76404edcSAsim Jamshed #define TIME_TICK				(1000000/HZ)		// in us
53*76404edcSAsim Jamshed #define TIMEVAL_TO_TS(t)		(uint32_t)((t)->tv_sec * HZ + \
54*76404edcSAsim Jamshed 								((t)->tv_usec / TIME_TICK))
55*76404edcSAsim Jamshed 
56*76404edcSAsim Jamshed #define TS_TO_USEC(t)			((t) * TIME_TICK)
57*76404edcSAsim Jamshed #define TS_TO_MSEC(t)			(TS_TO_USEC(t) / 1000)
58*76404edcSAsim Jamshed 
59*76404edcSAsim Jamshed #define USEC_TO_TS(t)			((t) / TIME_TICK)
60*76404edcSAsim Jamshed #define MSEC_TO_TS(t)			(USEC_TO_TS((t) * 1000))
61*76404edcSAsim Jamshed 
62*76404edcSAsim Jamshed #define SEC_TO_USEC(t)			((t) * 1000000)
63*76404edcSAsim Jamshed #define SEC_TO_MSEC(t)			((t) * 1000)
64*76404edcSAsim Jamshed #define MSEC_TO_USEC(t)			((t) * 1000)
65*76404edcSAsim Jamshed #define USEC_TO_SEC(t)			((t) / 1000000)
66*76404edcSAsim Jamshed //#define TCP_TIMEWAIT			(MSEC_TO_USEC(5000) / TIME_TICK)	// 5s
67*76404edcSAsim Jamshed #define TCP_TIMEWAIT			0
68*76404edcSAsim Jamshed #define TCP_INITIAL_RTO			(MSEC_TO_USEC(500) / TIME_TICK)		// 500ms
69*76404edcSAsim Jamshed #define TCP_FIN_RTO				(MSEC_TO_USEC(500) / TIME_TICK)		// 500ms
70*76404edcSAsim Jamshed #define TCP_TIMEOUT				(MSEC_TO_USEC(30) / TIME_TICK)	// 30s
71*76404edcSAsim Jamshed 
72*76404edcSAsim Jamshed #define TCP_MAX_RTX				16
73*76404edcSAsim Jamshed #define TCP_MAX_SYN_RETRY		7
74*76404edcSAsim Jamshed #define TCP_MAX_BACKOFF			7
75*76404edcSAsim Jamshed 
76*76404edcSAsim Jamshed enum tcp_state
77*76404edcSAsim Jamshed {
78*76404edcSAsim Jamshed 	TCP_ST_CLOSED		= 0,
79*76404edcSAsim Jamshed 	TCP_ST_LISTEN		= 1,
80*76404edcSAsim Jamshed 	TCP_ST_SYN_SENT		= 2,
81*76404edcSAsim Jamshed 	TCP_ST_SYN_RCVD		= 3,
82*76404edcSAsim Jamshed 	TCP_ST_ESTABLISHED	= 4,
83*76404edcSAsim Jamshed 	TCP_ST_FIN_WAIT_1	= 5,
84*76404edcSAsim Jamshed 	TCP_ST_FIN_WAIT_2	= 6,
85*76404edcSAsim Jamshed 	TCP_ST_CLOSE_WAIT	= 7,
86*76404edcSAsim Jamshed 	TCP_ST_CLOSING		= 8,
87*76404edcSAsim Jamshed 	TCP_ST_LAST_ACK		= 9,
88*76404edcSAsim Jamshed 	TCP_ST_TIME_WAIT	= 10,
89*76404edcSAsim Jamshed 	/* 151020 dhkim: TCP_ST_CLOSED_RSVD is only for internal use to
90*76404edcSAsim Jamshed 	 * differentiate a finished connection and a connection before starting.
91*76404edcSAsim Jamshed 	 * This state will be presented as TCP_CLOSED for the user. */
92*76404edcSAsim Jamshed 	TCP_ST_CLOSED_RSVD      = 11,
93*76404edcSAsim Jamshed };
94*76404edcSAsim Jamshed 
95*76404edcSAsim Jamshed 
96*76404edcSAsim Jamshed enum tcp_option
97*76404edcSAsim Jamshed {
98*76404edcSAsim Jamshed 	TCP_OPT_END			= 0,
99*76404edcSAsim Jamshed 	TCP_OPT_NOP			= 1,
100*76404edcSAsim Jamshed 	TCP_OPT_MSS			= 2,
101*76404edcSAsim Jamshed 	TCP_OPT_WSCALE		= 3,
102*76404edcSAsim Jamshed 	TCP_OPT_SACK_PERMIT	= 4,
103*76404edcSAsim Jamshed 	TCP_OPT_SACK		= 5,
104*76404edcSAsim Jamshed 	TCP_OPT_TIMESTAMP	= 8
105*76404edcSAsim Jamshed };
106*76404edcSAsim Jamshed 
107*76404edcSAsim Jamshed enum tcp_close_reason
108*76404edcSAsim Jamshed {
109*76404edcSAsim Jamshed 	TCP_NOT_CLOSED		= 0,
110*76404edcSAsim Jamshed 	TCP_ACTIVE_CLOSE	= 1,
111*76404edcSAsim Jamshed 	TCP_PASSIVE_CLOSE	= 2,
112*76404edcSAsim Jamshed 	TCP_CONN_FAIL		= 3,
113*76404edcSAsim Jamshed 	TCP_CONN_LOST		= 4,
114*76404edcSAsim Jamshed 	TCP_RESET			= 5,
115*76404edcSAsim Jamshed 	TCP_NO_MEM			= 6,
116*76404edcSAsim Jamshed 	TCP_NOT_ACCEPTED	= 7,
117*76404edcSAsim Jamshed 	TCP_TIMEDOUT		= 8
118*76404edcSAsim Jamshed };
119*76404edcSAsim Jamshed 
120*76404edcSAsim Jamshed void
121*76404edcSAsim Jamshed ParseTCPOptions(tcp_stream *cur_stream,
122*76404edcSAsim Jamshed 		uint32_t cur_ts, uint8_t *tcpopt, int len);
123*76404edcSAsim Jamshed 
124*76404edcSAsim Jamshed extern inline int
125*76404edcSAsim Jamshed ProcessTCPUplink(mtcp_manager_t mtcp, uint32_t cur_ts, tcp_stream *cur_stream,
126*76404edcSAsim Jamshed 		const struct tcphdr *tcph, uint32_t seq, uint32_t ack_seq,
127*76404edcSAsim Jamshed 		uint8_t *payload, int payloadlen, uint32_t window);
128*76404edcSAsim Jamshed 
129*76404edcSAsim Jamshed void
130*76404edcSAsim Jamshed UpdateRecvTCPContext(mtcp_manager_t mtcp, struct tcp_stream *cur_stream,
131*76404edcSAsim Jamshed 		struct pkt_ctx *pctx);
132*76404edcSAsim Jamshed 
133*76404edcSAsim Jamshed void
134*76404edcSAsim Jamshed DoActionEndTCPPacket(mtcp_manager_t mtcp, struct tcp_stream *cur_stream,
135*76404edcSAsim Jamshed 		struct pkt_ctx *pctx);
136*76404edcSAsim Jamshed 
137*76404edcSAsim Jamshed uint16_t
138*76404edcSAsim Jamshed TCPCalcChecksum(uint16_t *buf, uint16_t len, uint32_t saddr, uint32_t daddr);
139*76404edcSAsim Jamshed 
140*76404edcSAsim Jamshed void
141*76404edcSAsim Jamshed UpdatePassiveRecvTCPContext(mtcp_manager_t mtcp, struct tcp_stream *cur_stream,
142*76404edcSAsim Jamshed 			    struct pkt_ctx *pctx);
143*76404edcSAsim Jamshed 
144*76404edcSAsim Jamshed extern inline void
145*76404edcSAsim Jamshed PreRecvTCPEventPrediction(mtcp_manager_t mtcp, struct pkt_ctx *pctx,
146*76404edcSAsim Jamshed 			  struct tcp_stream *recvside_stream);
147*76404edcSAsim Jamshed 
148*76404edcSAsim Jamshed #endif /* __TCP_IN_H_ */
149