-
Notifications
You must be signed in to change notification settings - Fork 432
/
tcp_stream.h
231 lines (183 loc) · 5.87 KB
/
tcp_stream.h
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
#ifndef __TCP_STREAM_H_
#define __TCP_STREAM_H_
#include <netinet/ip.h>
#include <linux/tcp.h>
#include <sys/queue.h>
#include "mtcp.h"
struct rtm_stat
{
uint32_t tdp_ack_cnt;
uint32_t tdp_ack_bytes;
uint32_t ack_upd_cnt;
uint32_t ack_upd_bytes;
#if TCP_OPT_SACK_ENABLED
uint32_t sack_cnt;
uint32_t sack_bytes;
uint32_t tdp_sack_cnt;
uint32_t tdp_sack_bytes;
#endif /* TCP_OPT_SACK_ENABLED */
uint32_t rto_cnt;
uint32_t rto_bytes;
};
#if TCP_OPT_SACK_ENABLED
struct sack_entry
{
uint32_t left_edge;
uint32_t right_edge;
uint32_t expire;
};
#endif /* TCP_OPT_SACK_ENABLED */
struct tcp_recv_vars
{
/* receiver variables */
uint32_t rcv_wnd; /* receive window (unscaled) */
//uint32_t rcv_up; /* receive urgent pointer */
uint32_t irs; /* initial receiving sequence */
uint32_t snd_wl1; /* segment seq number for last window update */
uint32_t snd_wl2; /* segment ack number for last window update */
/* variables for fast retransmission */
uint8_t dup_acks; /* number of duplicated acks */
uint32_t last_ack_seq; /* highest ackd seq */
/* timestamps */
uint32_t ts_recent; /* recent peer timestamp */
uint32_t ts_lastack_rcvd; /* last ack rcvd time */
uint32_t ts_last_ts_upd; /* last peer ts update time */
uint32_t ts_tw_expire; // timestamp for timewait expire
/* RTT estimation variables */
uint32_t srtt; /* smoothed round trip time << 3 (scaled) */
uint32_t mdev; /* medium deviation */
uint32_t mdev_max; /* maximal mdev ffor the last rtt period */
uint32_t rttvar; /* smoothed mdev_max */
uint32_t rtt_seq; /* sequence number to update rttvar */
#if TCP_OPT_SACK_ENABLED /* currently not used */
#define MAX_SACK_ENTRY 8
struct sack_entry sack_table[MAX_SACK_ENTRY];
uint8_t sacks:3;
#endif /* TCP_OPT_SACK_ENABLED */
struct tcp_ring_buffer *rcvbuf;
#if USE_SPIN_LOCK
pthread_spinlock_t read_lock;
#else
pthread_mutex_t read_lock;
#endif
TAILQ_ENTRY(tcp_stream) he_link; /* hash table entry link */
#if BLOCKING_SUPPORT
TAILQ_ENTRY(tcp_stream) rcv_br_link;
pthread_cond_t read_cond;
#endif
};
struct tcp_send_vars
{
/* IP-level information */
uint16_t ip_id;
uint16_t mss; /* maximum segment size */
uint16_t eff_mss; /* effective segment size (excluding tcp option) */
uint8_t wscale_mine; /* my window scale (adertising window) */
uint8_t wscale_peer; /* peer's window scale (advertised window) */
int8_t nif_out; /* cached output network interface */
unsigned char *d_haddr; /* cached destination MAC address */
/* send sequence variables */
uint32_t snd_una; /* send unacknoledged */
uint32_t snd_wnd; /* send window (unscaled) */
uint32_t peer_wnd; /* client window size */
//uint32_t snd_up; /* send urgent pointer (not used) */
uint32_t iss; /* initial sending sequence */
uint32_t fss; /* final sending sequence */
/* retransmission timeout variables */
uint8_t nrtx; /* number of retransmission */
uint8_t max_nrtx; /* max number of retransmission */
uint32_t rto; /* retransmission timeout */
uint32_t ts_rto; /* timestamp for retransmission timeout */
/* congestion control variables */
uint32_t cwnd; /* congestion window */
uint32_t ssthresh; /* slow start threshold */
/* timestamp */
uint32_t ts_lastack_sent; /* last ack sent time */
uint8_t is_wack:1, /* is ack for window adertisement? */
ack_cnt:6; /* number of acks to send. max 64 */
uint8_t on_control_list;
uint8_t on_send_list;
uint8_t on_ack_list;
uint8_t on_sendq;
uint8_t on_ackq;
uint8_t on_closeq;
uint8_t on_resetq;
uint8_t on_closeq_int:1,
on_resetq_int:1,
is_fin_sent:1,
is_fin_ackd:1;
TAILQ_ENTRY(tcp_stream) control_link;
TAILQ_ENTRY(tcp_stream) send_link;
TAILQ_ENTRY(tcp_stream) ack_link;
TAILQ_ENTRY(tcp_stream) timer_link; /* timer link (rto list, tw list) */
TAILQ_ENTRY(tcp_stream) timeout_link; /* connection timeout link */
struct tcp_send_buffer *sndbuf;
#if USE_SPIN_LOCK
pthread_spinlock_t write_lock;
#else
pthread_mutex_t write_lock;
#endif
#if RTM_STAT
struct rtm_stat rstat; /* retransmission statistics */
#endif
#if BLOCKING_SUPPORT
TAILQ_ENTRY(tcp_stream) snd_br_link;
pthread_cond_t write_cond;
#endif
};
typedef struct tcp_stream
{
socket_map_t socket;
uint32_t id:24,
stream_type:8;
uint32_t saddr; /* in network order */
uint32_t daddr; /* in network order */
uint16_t sport; /* in network order */
uint16_t dport; /* in network order */
uint8_t state; /* tcp state */
uint8_t close_reason; /* close reason */
uint8_t on_hash_table;
uint8_t on_timewait_list;
uint8_t ht_idx;
uint8_t closed;
uint8_t is_bound_addr;
uint8_t need_wnd_adv;
int16_t on_rto_idx;
uint16_t on_timeout_list:1,
on_rcv_br_list:1,
on_snd_br_list:1,
saw_timestamp:1, /* whether peer sends timestamp */
sack_permit:1, /* whether peer permits SACK */
control_list_waiting:1,
have_reset:1;
uint32_t snd_nxt; /* send next */
uint32_t rcv_nxt; /* receive next */
struct tcp_recv_vars *rcvvar;
struct tcp_send_vars *sndvar;
uint32_t last_active_ts; /* ts_last_ack_sent or ts_last_ts_upd */
} tcp_stream;
inline char *
TCPStateToString(const tcp_stream *cur_stream);
unsigned int
HashFlow(const tcp_stream *flow);
int
EqualFlow(const tcp_stream *flow1, const tcp_stream *flow2);
inline int
AddEpollEvent(struct mtcp_epoll *ep,
int queue_type, socket_map_t socket, uint32_t event);
inline void
RaiseReadEvent(mtcp_manager_t mtcp, tcp_stream *stream);
inline void
RaiseWriteEvent(mtcp_manager_t mtcp, tcp_stream *stream);
inline void
RaiseCloseEvent(mtcp_manager_t mtcp, tcp_stream *stream);
inline void
RaiseErrorEvent(mtcp_manager_t mtcp, tcp_stream *stream);
tcp_stream *
CreateTCPStream(mtcp_manager_t mtcp, socket_map_t socket, int type,
uint32_t saddr, uint16_t sport, uint32_t daddr, uint16_t dport);
void
DestroyTCPStream(mtcp_manager_t mtcp, tcp_stream *stream);
void
DumpStream(mtcp_manager_t mtcp, tcp_stream *stream);
#endif /* __TCP_STREAM_H_ */