-
Notifications
You must be signed in to change notification settings - Fork 95
/
Copy pathtcpmux.h
320 lines (277 loc) · 8.27 KB
/
tcpmux.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
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
// SPDX-License-Identifier: GPL-3.0-only
/*
* Copyright (c) 2023 Dengfeng Liu <liudf0716@gmail.com>
*/
#ifndef XFRPC_TCPMUX_H
#define XFRPC_TCPMUX_H
#include "uthash.h"
#include <stdint.h>
#define MAX_STREAM_WINDOW_SIZE (256 * 1024)
#define RBUF_SIZE (32 * 1024)
#define WBUF_SIZE (32 * 1024)
struct ring_buffer {
uint32_t cur;
uint32_t end;
uint32_t sz;
uint8_t data[RBUF_SIZE];
};
enum go_away_type {
NORMAL,
PROTO_ERR,
INTERNAL_ERR,
};
enum tcp_mux_type {
DATA,
WINDOW_UPDATE,
PING,
GO_AWAY,
};
struct tcp_mux_type_desc {
enum tcp_mux_type type;
char *desc;
};
enum tcp_mux_flag {
ZERO,
SYN,
ACK = 1 << 1,
FIN = 1 << 2,
RST = 1 << 3,
};
struct __attribute__((__packed__)) tcp_mux_header {
uint8_t version;
uint8_t type;
uint16_t flags;
uint32_t stream_id;
uint32_t length;
};
struct tcp_mux_flag_desc {
enum tcp_mux_flag flag;
char *desc;
};
enum tcp_mux_state {
INIT = 0,
SYN_SEND,
SYN_RECEIVED,
ESTABLISHED,
LOCAL_CLOSE,
REMOTE_CLOSE,
CLOSED,
RESET
};
struct tmux_stream {
uint32_t id;
uint32_t recv_window;
uint32_t send_window;
enum tcp_mux_state state;
struct ring_buffer tx_ring;
struct ring_buffer rx_ring;
// private arguments
UT_hash_handle hh;
};
typedef void (*handle_data_fn_t)(uint8_t *, int, void *);
/**
* @brief Initializes TCP MUX stream.
*
* @param stream Pointer to the tmux_stream structure.
* @param id Stream ID of the TCP MUX message.
* @param state State of the TCP MUX message.
*/
void init_tmux_stream(struct tmux_stream *stream, uint32_t id,
enum tcp_mux_state state);
/**
* @brief Validates a TCP MUX protocol.
*
* @param tmux_hdr Pointer to the TCP MUX header.
* @return Status of the operation.
*/
int validate_tcp_mux_protocol(struct tcp_mux_header *tmux_hdr);
/**
* @brief Sends window update message.
*
* @param bout The bufferevent to send the window update message.
* @param stream Pointer to the tmux_stream structure.
* @param length Length of the window update message.
*/
void send_window_update(struct bufferevent *bout, struct tmux_stream *stream,
uint32_t length);
/**
* @brief Sends a TCP MUX window update message with SYN flag.
*
* @param bout The bufferevent to send the window update message.
* @param stream_id Stream ID of the TCP MUX message.
*/
void tcp_mux_send_win_update_syn(struct bufferevent *bout, uint32_t stream_id);
/**
* @brief Sends a TCP MUX window update message with ACK flag.
*
* @param bout The bufferevent to send the window update message.
* @param stream_id Stream ID of the TCP MUX message.
* @param delta Delta of the TCP MUX message.
*/
void tcp_mux_send_win_update_ack(struct bufferevent *bout, uint32_t stream_id,
uint32_t delta);
/**
* @brief Sends a TCP MUX window update message with FIN flag.
*
* @param bout The bufferevent to send the window update message.
* @param stream_id Stream ID of the TCP MUX message.
*/
void tcp_mux_send_win_update_fin(struct bufferevent *bout, uint32_t stream_id);
/**
* @brief Sends a TCP MUX window update message with RST flag.
*
* @param bout The bufferevent to send the window update message.
* @param stream_id Stream ID of the TCP MUX message.
*/
void tcp_mux_send_win_update_rst(struct bufferevent *bout, uint32_t stream_id);
/**
* @brief Sends a TCP MUX data message.
*
* @param bout The bufferevent to send the data message.
* @param flags Flags of the TCP MUX message.
* @param stream_id Stream ID of the TCP MUX message.
* @param length Length of the TCP MUX message.
*/
void tcp_mux_send_data(struct bufferevent *bout, uint16_t flags,
uint32_t stream_id, uint32_t length);
/**
* @brief Sends a TCP MUX ping message.
*
* @param bout The bufferevent to send the ping message.
* @param ping_id The ping ID to send.
*/
void tcp_mux_send_ping(struct bufferevent *bout, uint32_t ping_id);
/**
* @brief get the next session ID.
*/
uint32_t get_next_session_id();
/**
* @brief Encodes a TCP MUX header.
*
* @param type Type of the TCP MUX message.
* @param flags Flags of the TCP MUX message.
* @param stream_id Stream ID of the TCP MUX message.
* @param length Length of the TCP MUX message.
* @param tmux_hdr Pointer to the TCP MUX header.
*/
void tcp_mux_encode(enum tcp_mux_type type, enum tcp_mux_flag flags,
uint32_t stream_id, uint32_t length,
struct tcp_mux_header *tmux_hdr);
/**
* @brief Handles a TCP MUX data stream.
*
* @param tmux_hdr Pointer to the TCP MUX header.
* @param fn Function pointer to handle the data.
* @return Status of the operation.
*/
int handle_tcp_mux_stream(struct tcp_mux_header *tmux_hdr, handle_data_fn_t fn);
/**
* @brief Handles a TCP MUX ping message.
*
* @param tmux_hdr Pointer to the TCP MUX header.
*/
void handle_tcp_mux_ping(struct tcp_mux_header *tmux_hdr);
/**
* @brief Handles a TCP MUX go away message.
*
* @param tmux_hdr Pointer to the TCP MUX header.
*/
void handle_tcp_mux_go_away(struct tcp_mux_header *tmux_hdr);
/**
* @brief Writes data to a tmux stream.
*
* @param bev The bufferevent to write data to.
* @param data Pointer to the data buffer to write.
* @param length Length of the data to write.
* @param stream Pointer to the tmux_stream structure.
* @return Number of bytes written.
*/
uint32_t tmux_stream_write(struct bufferevent *bev, uint8_t *data,
uint32_t length, struct tmux_stream *stream);
/**
* @brief Reads data from a tmux stream.
*
* @param bev The bufferevent to read data from.
* @param stream Pointer to the tmux_stream structure.
* @param len Maximum number of bytes to read.
* @return Number of bytes read.
*/
uint32_t tmux_stream_read(struct bufferevent *bev, struct tmux_stream *stream,
uint32_t len);
/**
* @brief Resets the session ID counter.
*/
void reset_session_id();
/**
* @brief Retrieves the current tmux stream.
*
* @return Pointer to the current tmux_stream.
*/
struct tmux_stream *get_cur_stream();
/**
* @brief Sets the current tmux stream.
*
* @param stream Pointer to the tmux_stream to set as current.
*/
void set_cur_stream(struct tmux_stream *stream);
/**
* @brief Adds a tmux stream to the stream list.
*
* @param stream Pointer to the tmux_stream to add.
*/
void add_stream(struct tmux_stream *stream);
/**
* @brief Deletes a tmux stream by its ID.
*
* @param stream_id ID of the tmux_stream to delete.
*/
void del_stream(uint32_t stream_id);
/**
* @brief Clears all tmux streams from the stream list.
*/
void clear_stream();
/**
* @brief Retrieves a tmux stream by its ID.
*
* @param id ID of the tmux_stream to retrieve.
* @return Pointer to the tmux_stream if found, NULL otherwise.
*/
struct tmux_stream *get_stream_by_id(uint32_t id);
/**
* @brief Closes a tmux stream.
*
* @param bev The bufferevent associated with the stream.
* @param stream Pointer to the tmux_stream to close.
* @return 0 on success, negative value on error.
*/
int tmux_stream_close(struct bufferevent *bout, struct tmux_stream *stream);
/**
* @brief Pops data from the receive ring buffer.
*
* @param ring Pointer to the ring_buffer structure.
* @param data Buffer to store the popped data.
* @param len Maximum number of bytes to pop.
* @return Number of bytes popped.
*/
int rx_ring_buffer_pop(struct ring_buffer *ring, uint8_t *data, uint32_t len);
/**
* @brief Reads data from a bufferevent into the receive ring buffer.
*
* @param bev The bufferevent to read data from.
* @param ring Pointer to the ring_buffer to store data.
* @param len Maximum number of bytes to read.
* @return Number of bytes read.
*/
uint32_t rx_ring_buffer_read(struct bufferevent *bev, struct ring_buffer *ring,
uint32_t len);
/**
* @brief Writes data from the transmit ring buffer to a bufferevent.
*
* @param bev The bufferevent to write data to.
* @param ring Pointer to the ring_buffer containing data to send.
* @param len Maximum number of bytes to write.
* @return Number of bytes written.
*/
uint32_t tx_ring_buffer_write(struct bufferevent *bev, struct ring_buffer *ring,
uint32_t len);
#endif