Skip to content

Commit ca64905

Browse files
committed
fix: process unhandle tcp mux header
Signed-off-by: Dengfeng Liu <liudf0716@gmail.com>
1 parent 6b1f704 commit ca64905

File tree

7 files changed

+85
-44
lines changed

7 files changed

+85
-44
lines changed

client.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,11 @@ xfrp_proxy_event_cb(struct bufferevent *bev, short what, void *ctx)
7070
debug(LOG_DEBUG, "xfrpc proxy close connect server [%s:%d] stream_id %d: %s",
7171
client->ps->local_ip, client->ps->local_port,
7272
client->stream_id, strerror(errno));
73-
tcp_mux_send_win_update_rst(client->ctl_bev, client->stream_id);
74-
} else if (what & BEV_EVENT_CONNECTED) {
73+
tcp_mux_send_win_update_fin(client->ctl_bev, client->stream_id);
74+
client->stream_state = LOCAL_CLOSE;
75+
} else if (what & BEV_EVENT_CONNECTED) {
76+
debug(LOG_DEBUG, "client [%d] connected", client->stream_id);
77+
//client->stream_state = ESTABLISHED;
7578
if (client->data_tail_size > 0) {
7679
debug(LOG_DEBUG, "send client data ...");
7780
send_client_data_tail(client);
@@ -122,7 +125,7 @@ start_xfrp_tunnel(struct proxy_client *client)
122125
client->local_proxy_bev = connect_server(base, ps->local_ip, ps->local_port);
123126
if ( !client->local_proxy_bev ) {
124127
debug(LOG_ERR, "frpc tunnel connect local proxy port [%d] failed!", ps->local_port);
125-
bufferevent_free(client->ctl_bev);
128+
del_proxy_client(client);
126129
return;
127130
}
128131

@@ -183,7 +186,7 @@ void
183186
del_proxy_client(struct proxy_client *client)
184187
{
185188
if (!client || !all_pc ) {
186-
debug(LOG_INFO, "Error: all_pc or client is NULL");
189+
debug(LOG_INFO, "all_pc or client is NULL");
187190
return;
188191
}
189192

@@ -207,6 +210,7 @@ new_proxy_client()
207210
assert(client);
208211
client->stream_id = get_next_session_id();
209212
client->send_window = 128*1024;
213+
client->stream_state = INIT;
210214
HASH_ADD_INT(all_pc, stream_id, client);
211215

212216
return client;

client.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131

3232
#include "uthash.h"
3333
#include "common.h"
34+
#include "tcpmux.h"
3435

3536
struct event_base;
3637
struct base_conf;
@@ -46,6 +47,7 @@ struct proxy_client {
4647

4748
uint32_t stream_id;
4849
uint32_t send_window;
50+
enum tcp_mux_state stream_state;
4951
int connected;
5052
int work_started;
5153
struct proxy_service *ps;

control.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -526,7 +526,6 @@ connect_event_cb (struct bufferevent *bev, short what, void *ctx)
526526
strerror(errno));
527527
clear_main_control();
528528
start_base_connect();
529-
exit(0);
530529
} else if (what & BEV_EVENT_CONNECTED) {
531530
retry_times = 0;
532531

systemd/xfrpc.service

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# 1. put xfrpc and xfrpc.ini under /usr/local/xfrpc/
2+
# 2. put this file (xfrpc.service) at /etc/systemd/system
3+
# 3. run `sudo systemctl daemon-reload && sudo systemctl enable xfrpc && sudo systemctl start xfrpc`
4+
# Then we can manage xfrpc with `sudo service xfrpc {start|stop|restart|status}`
5+
6+
7+
[Unit]
8+
Description=frp c language client
9+
Wants=network-online.target
10+
After=network.target network-online.target
11+
12+
[Service]
13+
ExecStart=/usr/local/xfrpc/xfrpc -c /usr/local/xfrpc/xfrpc.ini -f -d 0
14+
15+
[Install]
16+
WantedBy=multi-user.target

tcpmux.c

Lines changed: 46 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@ flag_2_desc(enum tcp_mux_flag flag)
6666
if (flag == flag_desc[i].flag)
6767
return flag_desc[i].desc;
6868
}
69-
70-
return "unknown_flag";
69+
70+
return "unkown_flag";
7171
}
7272

7373
static int
@@ -79,15 +79,6 @@ valid_tcp_mux_type(uint8_t type)
7979
return 0;
8080
}
8181

82-
static int
83-
valid_tcp_mux_flag(uint16_t flag)
84-
{
85-
if (flag >= ZERO && flag <= RST)
86-
return 1;
87-
88-
return 0;
89-
}
90-
9182
static int
9283
valid_tcp_mux_sid(uint32_t sid)
9384
{
@@ -140,8 +131,7 @@ parse_tcp_mux_proto(uint8_t *data, int len, uint32_t *flag, uint32_t *type, uint
140131

141132
struct tcp_mux_header *hdr = (struct tcp_mux_header *)data;
142133
if(hdr->version == proto_version &&
143-
valid_tcp_mux_type(hdr->type) &&
144-
valid_tcp_mux_flag(htons(hdr->flags))) {
134+
valid_tcp_mux_type(hdr->type)) {
145135
if (hdr->type == DATA && !valid_tcp_mux_sid(htonl(hdr->stream_id))) {
146136
debug(LOG_INFO, "!!!!!type is DATA but cant find stream_id : type [%s] flag [%s] stream_id[%d]",
147137
type_2_desc(hdr->type), flag_2_desc(htons(hdr->flags)), htonl(hdr->stream_id));
@@ -191,14 +181,14 @@ tcp_mux_send_win_update_ack(struct bufferevent *bout, uint32_t stream_id, uint32
191181
}
192182

193183
void
194-
tcp_mux_send_win_update_rst(struct bufferevent *bout, uint32_t stream_id)
184+
tcp_mux_send_win_update_fin(struct bufferevent *bout, uint32_t stream_id)
195185
{
196186
if (!tcp_mux_flag()) return;
197187

198188
struct tcp_mux_header tmux_hdr;
199189
memset(&tmux_hdr, 0, sizeof(tmux_hdr));
200-
tcp_mux_encode(WINDOW_UPDATE, RST, stream_id, 0, &tmux_hdr);
201-
debug(LOG_DEBUG, "tcp mux [%d] send wind update RST", stream_id);
190+
tcp_mux_encode(WINDOW_UPDATE, FIN, stream_id, 0, &tmux_hdr);
191+
debug(LOG_DEBUG, "tcp mux [%d] send wind update FIN", stream_id);
202192
bufferevent_write(bout, (uint8_t *)&tmux_hdr, sizeof(tmux_hdr));
203193
}
204194

@@ -266,7 +256,15 @@ handle_tcp_mux_frps_msg(uint8_t *buf, int ilen, void (*fn)(uint8_t *, int, void
266256
data += l_dlen;
267257
ilen -= l_dlen;
268258
l_dlen = 0;
269-
} else if ( ilen >= l_dlen) {
259+
continue;
260+
}
261+
262+
if (pc->stream_state != ESTABLISHED) {
263+
debug(LOG_INFO, "client [%d] state is [%d]", pc->stream_id, pc->stream_state);
264+
break;
265+
}
266+
267+
if ( ilen >= l_dlen) {
270268
assert(pc->local_proxy_bev);
271269
bufferevent_write(pc->local_proxy_bev, data, l_dlen);
272270
data += l_dlen;
@@ -306,12 +304,22 @@ handle_tcp_mux_frps_msg(uint8_t *buf, int ilen, void (*fn)(uint8_t *, int, void
306304
data += dlen;
307305
ilen -= dlen;
308306
l_dlen = 0;
309-
} else if ( ilen >= dlen){
307+
continue;
308+
}
309+
310+
if (pc->stream_state != ESTABLISHED) {
311+
debug(LOG_INFO, "client [%d] state is [%d]", pc->stream_id, pc->stream_state);
312+
break;
313+
}
314+
315+
if (ilen >= dlen){
316+
assert(pc->local_proxy_bev);
310317
bufferevent_write(pc->local_proxy_bev, data, dlen);
311318
data += dlen;
312319
ilen -= dlen;
313320
l_dlen = 0;
314321
} else {
322+
assert(pc->local_proxy_bev);
315323
bufferevent_write(pc->local_proxy_bev, data, ilen);
316324
l_dlen -= ilen;
317325
ilen = 0;
@@ -329,14 +337,27 @@ handle_tcp_mux_frps_msg(uint8_t *buf, int ilen, void (*fn)(uint8_t *, int, void
329337
}
330338
case WINDOW_UPDATE:
331339
{
332-
if (flag == RST) {
333-
del_proxy_client(pc);
334-
} else if (pc && dlen > 0){
335-
pc->send_window += dlen;
336-
bufferevent_enable(pc->local_proxy_bev, EV_READ|EV_WRITE);
337-
} else {
338-
debug(LOG_INFO, "window update no need process : flag %s dlen %d", flag_2_desc(flag), dlen);
340+
switch(flag) {
341+
case RST:
342+
case FIN:
343+
del_proxy_client(pc);
344+
break;
345+
case ZERO:
346+
case ACK:
347+
if (!pc)
348+
break;
349+
350+
if (dlen > 0) {
351+
pc->send_window += dlen;
352+
bufferevent_enable(pc->local_proxy_bev, EV_READ|EV_WRITE);
353+
}
354+
pc->stream_state = ESTABLISHED;
355+
break;
356+
default:
357+
debug(LOG_INFO, "window update no need process : flag %2x %s dlen %d stream_id %d",
358+
flag, flag_2_desc(flag), dlen, stream_id);
339359
}
360+
340361
break;
341362
}
342363
default:

tcpmux.h

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,17 @@ struct tcp_mux_type_desc {
4444
enum tcp_mux_flag {
4545
ZERO,
4646
SYN,
47-
ACK,
48-
FIN,
49-
RST,
47+
ACK = 1<<1,
48+
FIN = 1<<2,
49+
RST = 1<<3,
50+
};
51+
52+
struct __attribute__((__packed__)) tcp_mux_header {
53+
uint8_t version;
54+
uint8_t type;
55+
uint16_t flags;
56+
uint32_t stream_id;
57+
uint32_t length;
5058
};
5159

5260
struct tcp_mux_flag_desc {
@@ -65,20 +73,11 @@ enum tcp_mux_state {
6573
RESET
6674
};
6775

68-
69-
struct __attribute__((__packed__)) tcp_mux_header {
70-
uint8_t version;
71-
uint8_t type;
72-
uint16_t flags;
73-
uint32_t stream_id;
74-
uint32_t length;
75-
};
76-
7776
void tcp_mux_send_win_update_syn(struct bufferevent *bout, uint32_t stream_id);
7877

7978
void tcp_mux_send_win_update_ack(struct bufferevent *bout, uint32_t stream_id, uint32_t delta);
8079

81-
void tcp_mux_send_win_update_rst(struct bufferevent *bout, uint32_t stream_id);
80+
void tcp_mux_send_win_update_fin(struct bufferevent *bout, uint32_t stream_id);
8281

8382
void tcp_mux_send_data(struct bufferevent *bout, uint32_t stream_id, uint32_t length);
8483

version.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#ifndef _VERSION_H_
22
#define _VERSION_H_
33

4-
#define VERSION "1.05.556"
4+
#define VERSION "1.05.561"
55
#define PROTOCOL_VERESION "0.42.0"
66
#define CLIENT_V 1
77

0 commit comments

Comments
 (0)