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