Skip to content

Commit

Permalink
fix: process unhandle tcp mux header
Browse files Browse the repository at this point in the history
Signed-off-by: Dengfeng Liu <[email protected]>
  • Loading branch information
liudf0716 committed May 31, 2022
1 parent 6b1f704 commit ca64905
Show file tree
Hide file tree
Showing 7 changed files with 85 additions and 44 deletions.
12 changes: 8 additions & 4 deletions client.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,11 @@ xfrp_proxy_event_cb(struct bufferevent *bev, short what, void *ctx)
debug(LOG_DEBUG, "xfrpc proxy close connect server [%s:%d] stream_id %d: %s",
client->ps->local_ip, client->ps->local_port,
client->stream_id, strerror(errno));
tcp_mux_send_win_update_rst(client->ctl_bev, client->stream_id);
} else if (what & BEV_EVENT_CONNECTED) {
tcp_mux_send_win_update_fin(client->ctl_bev, client->stream_id);
client->stream_state = LOCAL_CLOSE;
} else if (what & BEV_EVENT_CONNECTED) {
debug(LOG_DEBUG, "client [%d] connected", client->stream_id);
//client->stream_state = ESTABLISHED;
if (client->data_tail_size > 0) {
debug(LOG_DEBUG, "send client data ...");
send_client_data_tail(client);
Expand Down Expand Up @@ -122,7 +125,7 @@ start_xfrp_tunnel(struct proxy_client *client)
client->local_proxy_bev = connect_server(base, ps->local_ip, ps->local_port);
if ( !client->local_proxy_bev ) {
debug(LOG_ERR, "frpc tunnel connect local proxy port [%d] failed!", ps->local_port);
bufferevent_free(client->ctl_bev);
del_proxy_client(client);
return;
}

Expand Down Expand Up @@ -183,7 +186,7 @@ void
del_proxy_client(struct proxy_client *client)
{
if (!client || !all_pc ) {
debug(LOG_INFO, "Error: all_pc or client is NULL");
debug(LOG_INFO, "all_pc or client is NULL");
return;
}

Expand All @@ -207,6 +210,7 @@ new_proxy_client()
assert(client);
client->stream_id = get_next_session_id();
client->send_window = 128*1024;
client->stream_state = INIT;
HASH_ADD_INT(all_pc, stream_id, client);

return client;
Expand Down
2 changes: 2 additions & 0 deletions client.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@

#include "uthash.h"
#include "common.h"
#include "tcpmux.h"

struct event_base;
struct base_conf;
Expand All @@ -46,6 +47,7 @@ struct proxy_client {

uint32_t stream_id;
uint32_t send_window;
enum tcp_mux_state stream_state;
int connected;
int work_started;
struct proxy_service *ps;
Expand Down
1 change: 0 additions & 1 deletion control.c
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,6 @@ connect_event_cb (struct bufferevent *bev, short what, void *ctx)
strerror(errno));
clear_main_control();
start_base_connect();
exit(0);
} else if (what & BEV_EVENT_CONNECTED) {
retry_times = 0;

Expand Down
16 changes: 16 additions & 0 deletions systemd/xfrpc.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# 1. put xfrpc and xfrpc.ini under /usr/local/xfrpc/
# 2. put this file (xfrpc.service) at /etc/systemd/system
# 3. run `sudo systemctl daemon-reload && sudo systemctl enable xfrpc && sudo systemctl start xfrpc`
# Then we can manage xfrpc with `sudo service xfrpc {start|stop|restart|status}`


[Unit]
Description=frp c language client
Wants=network-online.target
After=network.target network-online.target

[Service]
ExecStart=/usr/local/xfrpc/xfrpc -c /usr/local/xfrpc/xfrpc.ini -f -d 0

[Install]
WantedBy=multi-user.target
71 changes: 46 additions & 25 deletions tcpmux.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ flag_2_desc(enum tcp_mux_flag flag)
if (flag == flag_desc[i].flag)
return flag_desc[i].desc;
}

return "unknown_flag";
return "unkown_flag";
}

static int
Expand All @@ -79,15 +79,6 @@ valid_tcp_mux_type(uint8_t type)
return 0;
}

static int
valid_tcp_mux_flag(uint16_t flag)
{
if (flag >= ZERO && flag <= RST)
return 1;

return 0;
}

static int
valid_tcp_mux_sid(uint32_t sid)
{
Expand Down Expand Up @@ -140,8 +131,7 @@ parse_tcp_mux_proto(uint8_t *data, int len, uint32_t *flag, uint32_t *type, uint

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

void
tcp_mux_send_win_update_rst(struct bufferevent *bout, uint32_t stream_id)
tcp_mux_send_win_update_fin(struct bufferevent *bout, uint32_t stream_id)
{
if (!tcp_mux_flag()) return;

struct tcp_mux_header tmux_hdr;
memset(&tmux_hdr, 0, sizeof(tmux_hdr));
tcp_mux_encode(WINDOW_UPDATE, RST, stream_id, 0, &tmux_hdr);
debug(LOG_DEBUG, "tcp mux [%d] send wind update RST", stream_id);
tcp_mux_encode(WINDOW_UPDATE, FIN, stream_id, 0, &tmux_hdr);
debug(LOG_DEBUG, "tcp mux [%d] send wind update FIN", stream_id);
bufferevent_write(bout, (uint8_t *)&tmux_hdr, sizeof(tmux_hdr));
}

Expand Down Expand Up @@ -266,7 +256,15 @@ handle_tcp_mux_frps_msg(uint8_t *buf, int ilen, void (*fn)(uint8_t *, int, void
data += l_dlen;
ilen -= l_dlen;
l_dlen = 0;
} else if ( ilen >= l_dlen) {
continue;
}

if (pc->stream_state != ESTABLISHED) {
debug(LOG_INFO, "client [%d] state is [%d]", pc->stream_id, pc->stream_state);
break;
}

if ( ilen >= l_dlen) {
assert(pc->local_proxy_bev);
bufferevent_write(pc->local_proxy_bev, data, l_dlen);
data += l_dlen;
Expand Down Expand Up @@ -306,12 +304,22 @@ handle_tcp_mux_frps_msg(uint8_t *buf, int ilen, void (*fn)(uint8_t *, int, void
data += dlen;
ilen -= dlen;
l_dlen = 0;
} else if ( ilen >= dlen){
continue;
}

if (pc->stream_state != ESTABLISHED) {
debug(LOG_INFO, "client [%d] state is [%d]", pc->stream_id, pc->stream_state);
break;
}

if (ilen >= dlen){
assert(pc->local_proxy_bev);
bufferevent_write(pc->local_proxy_bev, data, dlen);
data += dlen;
ilen -= dlen;
l_dlen = 0;
} else {
assert(pc->local_proxy_bev);
bufferevent_write(pc->local_proxy_bev, data, ilen);
l_dlen -= ilen;
ilen = 0;
Expand All @@ -329,14 +337,27 @@ handle_tcp_mux_frps_msg(uint8_t *buf, int ilen, void (*fn)(uint8_t *, int, void
}
case WINDOW_UPDATE:
{
if (flag == RST) {
del_proxy_client(pc);
} else if (pc && dlen > 0){
pc->send_window += dlen;
bufferevent_enable(pc->local_proxy_bev, EV_READ|EV_WRITE);
} else {
debug(LOG_INFO, "window update no need process : flag %s dlen %d", flag_2_desc(flag), dlen);
switch(flag) {
case RST:
case FIN:
del_proxy_client(pc);
break;
case ZERO:
case ACK:
if (!pc)
break;

if (dlen > 0) {
pc->send_window += dlen;
bufferevent_enable(pc->local_proxy_bev, EV_READ|EV_WRITE);
}
pc->stream_state = ESTABLISHED;
break;
default:
debug(LOG_INFO, "window update no need process : flag %2x %s dlen %d stream_id %d",
flag, flag_2_desc(flag), dlen, stream_id);
}

break;
}
default:
Expand Down
25 changes: 12 additions & 13 deletions tcpmux.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,17 @@ struct tcp_mux_type_desc {
enum tcp_mux_flag {
ZERO,
SYN,
ACK,
FIN,
RST,
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 {
Expand All @@ -65,20 +73,11 @@ enum tcp_mux_state {
RESET
};


struct __attribute__((__packed__)) tcp_mux_header {
uint8_t version;
uint8_t type;
uint16_t flags;
uint32_t stream_id;
uint32_t length;
};

void tcp_mux_send_win_update_syn(struct bufferevent *bout, uint32_t stream_id);

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

void tcp_mux_send_win_update_rst(struct bufferevent *bout, uint32_t stream_id);
void tcp_mux_send_win_update_fin(struct bufferevent *bout, uint32_t stream_id);

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

Expand Down
2 changes: 1 addition & 1 deletion version.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#ifndef _VERSION_H_
#define _VERSION_H_

#define VERSION "1.05.556"
#define VERSION "1.05.561"
#define PROTOCOL_VERESION "0.42.0"
#define CLIENT_V 1

Expand Down

0 comments on commit ca64905

Please sign in to comment.