Compare commits
40 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2429f79721 | ||
|
|
044626152c | ||
|
|
0d7643ceb1 | ||
|
|
0e581ebf6f | ||
|
|
2fcfa6a001 | ||
|
|
546dfb74d3 | ||
|
|
a02a5a19c7 | ||
|
|
09b67f7dc6 | ||
|
|
731584cbd3 | ||
|
|
25a994213f | ||
|
|
c4a9f4c97e | ||
|
|
a56d0d4d58 | ||
|
|
9f01265981 | ||
|
|
1e96d85f88 | ||
|
|
a668a6deff | ||
|
|
9ae47ffaa4 | ||
|
|
8d1c6f69ca | ||
|
|
4bcc36489b | ||
|
|
e9e2bf759a | ||
|
|
c6e3af8ac8 | ||
|
|
5ab2ac455d | ||
|
|
ddc3aff29b | ||
|
|
8f75d7c40c | ||
|
|
3c02e4fbc4 | ||
|
|
5b2b3a63ab | ||
|
|
b96e3d9364 | ||
|
|
f9636ce89c | ||
|
|
c1b7585cd5 | ||
|
|
6f350a33d5 | ||
|
|
b3efc1087a | ||
|
|
e57a99cf6a | ||
|
|
571de7556d | ||
|
|
2ffa39e7cb | ||
|
|
1aba513a05 | ||
|
|
5d0d1f105e | ||
|
|
cb95f86b08 | ||
|
|
7028aa3baa | ||
|
|
94314af51a | ||
|
|
b587a2d30f | ||
|
|
f2e482aa2e |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -39,7 +39,7 @@ Makefile
|
||||
cmake_install.cmake
|
||||
|
||||
# bin generated
|
||||
xfrp_client
|
||||
xfrpc
|
||||
xfrp_test_server
|
||||
bin
|
||||
.vscode
|
||||
|
||||
@@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 2.6)
|
||||
|
||||
project(xfrp C)
|
||||
|
||||
set(src_xfrp_client
|
||||
set(src_xfrpc
|
||||
main.c
|
||||
client.c
|
||||
config.c
|
||||
@@ -10,7 +10,7 @@ set(src_xfrp_client
|
||||
frame.c
|
||||
ini.c
|
||||
msg.c
|
||||
xfrp_client.c
|
||||
xfrpc.c
|
||||
debug.c
|
||||
zip.c
|
||||
commandline.c
|
||||
@@ -20,6 +20,9 @@ set(src_xfrp_client
|
||||
session.c
|
||||
common.c
|
||||
login.c
|
||||
proxy_tcp.c
|
||||
proxy_ftp.c
|
||||
proxy.c
|
||||
)
|
||||
|
||||
set(libs
|
||||
@@ -34,11 +37,11 @@ set(test_libs
|
||||
event
|
||||
)
|
||||
|
||||
ADD_DEFINITIONS(-Wall -g --std=gnu99 -Wmissing-declarations)
|
||||
ADD_DEFINITIONS(-Wall -g --std=gnu99)
|
||||
|
||||
add_executable(xfrp_client ${src_xfrp_client})
|
||||
target_link_libraries(xfrp_client ${libs})
|
||||
add_executable(xfrpc ${src_xfrpc})
|
||||
target_link_libraries(xfrpc ${libs})
|
||||
|
||||
install(TARGETS xfrp_client
|
||||
install(TARGETS xfrpc
|
||||
RUNTIME DESTINATION bin
|
||||
)
|
||||
|
||||
@@ -48,13 +48,13 @@ make
|
||||
Run in debug mode :
|
||||
|
||||
```shell
|
||||
xfrp_client -c frpc_mini.ini -f -d 7
|
||||
xfrpc -c frpc_mini.ini -f -d 7
|
||||
```
|
||||
|
||||
Run in release mode :
|
||||
|
||||
```shell
|
||||
xfrp_client -c frpc_mini.ini -d 0
|
||||
xfrpc -c frpc_mini.ini -d 0
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
94
client.c
94
client.c
@@ -52,8 +52,8 @@
|
||||
#include "const.h"
|
||||
#include "uthash.h"
|
||||
#include "zip.h"
|
||||
#include "msg.h"
|
||||
#include "common.h"
|
||||
#include "proxy.h"
|
||||
|
||||
#define MAX_OUTPUT (512*1024)
|
||||
|
||||
@@ -63,7 +63,8 @@ static void xfrp_event_cb(struct bufferevent *bev, short what, void *ctx);
|
||||
static void
|
||||
xfrp_read_cb(struct bufferevent *bev, void *ctx)
|
||||
{
|
||||
struct bufferevent *partner = ctx;
|
||||
struct proxy *p = (struct proxy *)ctx;
|
||||
struct bufferevent *partner = p?p->bev:NULL;
|
||||
struct evbuffer *src, *dst;
|
||||
size_t len;
|
||||
src = bufferevent_get_input(bev);
|
||||
@@ -74,13 +75,14 @@ xfrp_read_cb(struct bufferevent *bev, void *ctx)
|
||||
}
|
||||
dst = bufferevent_get_output(partner);
|
||||
evbuffer_add_buffer(dst, src);
|
||||
struct proxy *p_l = new_proxy_buf(bev);
|
||||
|
||||
if (evbuffer_get_length(dst) >= MAX_OUTPUT) {
|
||||
/* We're giving the other side data faster than it can
|
||||
* pass it on. Stop reading here until we have drained the
|
||||
* other side to MAX_OUTPUT/2 bytes. */
|
||||
bufferevent_setcb(partner, xfrp_read_cb, drained_writecb,
|
||||
xfrp_event_cb, bev);
|
||||
xfrp_event_cb, p_l);
|
||||
bufferevent_setwatermark(partner, EV_WRITE, MAX_OUTPUT/2,
|
||||
MAX_OUTPUT);
|
||||
bufferevent_disable(bev, EV_READ);
|
||||
@@ -90,11 +92,12 @@ xfrp_read_cb(struct bufferevent *bev, void *ctx)
|
||||
static void
|
||||
drained_writecb(struct bufferevent *bev, void *ctx)
|
||||
{
|
||||
struct bufferevent *partner = ctx;
|
||||
struct proxy *p = (struct proxy *)ctx;
|
||||
struct bufferevent *partner = p?p->bev:NULL;
|
||||
|
||||
/* We were choking the other side until we drained our outbuf a bit.
|
||||
* Now it seems drained. */
|
||||
bufferevent_setcb(bev, xfrp_read_cb, NULL, xfrp_event_cb, partner);
|
||||
bufferevent_setcb(bev, xfrp_read_cb, NULL, xfrp_event_cb, p);
|
||||
bufferevent_setwatermark(bev, EV_WRITE, 0, 0);
|
||||
if (partner)
|
||||
bufferevent_enable(partner, EV_READ);
|
||||
@@ -113,13 +116,14 @@ close_on_finished_writecb(struct bufferevent *bev, void *ctx)
|
||||
static void
|
||||
xfrp_event_cb(struct bufferevent *bev, short what, void *ctx)
|
||||
{
|
||||
struct bufferevent *partner = ctx;
|
||||
struct proxy *p = (struct proxy *)ctx;
|
||||
struct bufferevent *partner = p?p->bev:NULL;
|
||||
|
||||
if (what & (BEV_EVENT_EOF|BEV_EVENT_ERROR)) {
|
||||
debug(LOG_DEBUG, "working connection closed");
|
||||
debug(LOG_DEBUG, "working connection closed!");
|
||||
if (partner) {
|
||||
/* Flush all pending data */
|
||||
xfrp_read_cb(bev, ctx);
|
||||
xfrp_read_cb(bev, p);
|
||||
|
||||
if (evbuffer_get_length(bufferevent_get_output(partner))) {
|
||||
/* We still have to flush data from the other
|
||||
@@ -134,42 +138,41 @@ xfrp_event_cb(struct bufferevent *bev, short what, void *ctx)
|
||||
/* We have nothing left to say to the other
|
||||
* side; close it. */
|
||||
bufferevent_free(partner);
|
||||
free_proxy(p);
|
||||
}
|
||||
}
|
||||
bufferevent_free(bev);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
xfrp_decrypt_cb(struct bufferevent *bev, void *ctx)
|
||||
int is_ftp_proxy(const struct proxy_service *ps)
|
||||
{
|
||||
struct bufferevent *partner = ctx;
|
||||
struct evbuffer *src, *dst;
|
||||
src = bufferevent_get_input(bev);
|
||||
dst = bufferevent_get_output(partner);
|
||||
evbuffer_add_buffer(dst, src);
|
||||
}
|
||||
if (! ps || ! ps->proxy_type)
|
||||
return 0;
|
||||
|
||||
static void
|
||||
xfrp_encrypt_cb(struct bufferevent *bev, void *ctx)
|
||||
{
|
||||
struct bufferevent *partner = ctx;
|
||||
struct evbuffer *src, *dst;
|
||||
size_t len;
|
||||
src = bufferevent_get_input(bev);
|
||||
len = evbuffer_get_length(src);
|
||||
if (len > 0) {
|
||||
dst = bufferevent_get_output(partner);
|
||||
evbuffer_add_buffer(dst, src);
|
||||
}
|
||||
if (0 == strcmp(ps->proxy_type, "ftp") && ps->remote_data_port > 0)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// create frp tunnel for service
|
||||
void start_frp_tunnel(struct proxy_client *client)
|
||||
void start_xfrp_tunnel(struct proxy_client *client)
|
||||
{
|
||||
if (! client->ctl_bev) {
|
||||
debug(LOG_ERR, "proxy client control bev is invalid!");
|
||||
return;
|
||||
}
|
||||
|
||||
struct event_base *base = client->base;
|
||||
struct common_conf *c_conf = get_common_config();
|
||||
struct proxy_service *ps = client->ps;
|
||||
|
||||
if (! base) {
|
||||
debug(LOG_ERR, "service event base get failed");
|
||||
return;
|
||||
}
|
||||
|
||||
if (! ps) {
|
||||
debug(LOG_ERR, "service tunnel started failed, no proxy service resource.");
|
||||
return;
|
||||
@@ -189,21 +192,34 @@ void start_frp_tunnel(struct proxy_client *client)
|
||||
|
||||
debug(LOG_DEBUG, "proxy server [%s:%d] <---> client [%s:%d]",
|
||||
c_conf->server_addr,
|
||||
c_conf->server_port,
|
||||
ps->remote_port,
|
||||
ps->local_ip ? ps->local_ip:"::1",
|
||||
ps->local_port);
|
||||
|
||||
struct proxy *ctl_prox = new_proxy_buf(client->ctl_bev);
|
||||
struct proxy *local_prox = new_proxy_buf(client->local_proxy_bev);
|
||||
bufferevent_data_cb proxy_s2c_cb, proxy_c2s_cb;
|
||||
if (is_ftp_proxy(client->ps)) {
|
||||
proxy_c2s_cb = ftp_proxy_c2s_cb;
|
||||
proxy_s2c_cb = ftp_proxy_s2c_cb;
|
||||
ctl_prox->remote_data_port = client->ps->remote_data_port;
|
||||
ctl_prox->proxy_name = strdup(ps->proxy_name);
|
||||
} else {
|
||||
proxy_c2s_cb = tcp_proxy_c2s_cb;
|
||||
proxy_s2c_cb = tcp_proxy_s2c_cb;
|
||||
}
|
||||
|
||||
bufferevent_setcb(client->ctl_bev,
|
||||
xfrp_decrypt_cb,
|
||||
proxy_s2c_cb,
|
||||
NULL,
|
||||
xfrp_event_cb,
|
||||
client->local_proxy_bev);
|
||||
local_prox);
|
||||
|
||||
bufferevent_setcb(client->local_proxy_bev,
|
||||
xfrp_encrypt_cb,
|
||||
proxy_c2s_cb,
|
||||
NULL,
|
||||
xfrp_event_cb,
|
||||
client->ctl_bev);
|
||||
ctl_prox);
|
||||
|
||||
bufferevent_enable(client->ctl_bev, EV_READ|EV_WRITE);
|
||||
bufferevent_enable(client->local_proxy_bev, EV_READ|EV_WRITE);
|
||||
@@ -221,10 +237,7 @@ int send_client_data_tail(struct proxy_client *client)
|
||||
|
||||
void free_proxy_client(struct proxy_client *client)
|
||||
{
|
||||
if (client->name) free(client->name);
|
||||
if (client->local_ip) free(client->local_ip);
|
||||
if (client->custom_domains) free(client->custom_domains);
|
||||
if (client->locations) free(client->locations);
|
||||
|
||||
free_base_config(client->bconf);
|
||||
|
||||
@@ -251,4 +264,11 @@ struct proxy_service *get_proxy_service(const char *proxy_name)
|
||||
struct proxy_service *all_ps = get_all_proxy_services();
|
||||
HASH_FIND_STR(all_ps, proxy_name, ps);
|
||||
return ps;
|
||||
}
|
||||
|
||||
struct proxy_client *new_proxy_client()
|
||||
{
|
||||
struct proxy_client *client = calloc(1, sizeof(struct proxy_client));
|
||||
assert(client);
|
||||
return client;
|
||||
}
|
||||
17
client.h
17
client.h
@@ -43,22 +43,13 @@ struct proxy_client {
|
||||
struct bufferevent *ctl_bev;
|
||||
struct bufferevent *local_proxy_bev;
|
||||
struct event *ev_timeout;
|
||||
|
||||
|
||||
struct base_conf *bconf;
|
||||
char *name; // pointer to bconf->name
|
||||
char *local_ip;
|
||||
char *type;
|
||||
int local_port;
|
||||
int remote_port;
|
||||
int use_encryption;
|
||||
int use_compression;
|
||||
|
||||
char *custom_domains;
|
||||
char *subdomain;
|
||||
char *locations;
|
||||
char *host_header_rewrite;
|
||||
char *http_user;
|
||||
char *http_pwd;
|
||||
|
||||
//provate arguments
|
||||
UT_hash_handle hh;
|
||||
@@ -77,6 +68,7 @@ struct proxy_service {
|
||||
|
||||
char *local_ip;
|
||||
int remote_port;
|
||||
int remote_data_port;
|
||||
int local_port;
|
||||
|
||||
// http and https only
|
||||
@@ -96,7 +88,7 @@ struct proxy_service {
|
||||
// when xfrp client receive that request, it will start
|
||||
// frp tunnel
|
||||
// if client has data-tail(not NULL), client value will be changed
|
||||
void start_frp_tunnel(struct proxy_client *client);
|
||||
void start_xfrp_tunnel(struct proxy_client *client);
|
||||
|
||||
void del_proxy_client(struct proxy_client *client);
|
||||
|
||||
@@ -106,4 +98,7 @@ struct proxy_service *get_proxy_service(const char *proxy_name);
|
||||
|
||||
int send_client_data_tail(struct proxy_client *client);
|
||||
|
||||
int is_ftp_proxy(const struct proxy_service *ps);
|
||||
struct proxy_client *new_proxy_client();
|
||||
|
||||
#endif //_CLIENT_H_
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <syslog.h>
|
||||
#include <assert.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
@@ -146,8 +147,7 @@ parse_commandline(int argc, char **argv)
|
||||
case 'c':
|
||||
if (optarg) {
|
||||
confile = strdup(optarg); //never free it
|
||||
if (! confile)
|
||||
exit(0);
|
||||
assert(confile);
|
||||
|
||||
flag = 1;
|
||||
}
|
||||
|
||||
131
config.c
131
config.c
@@ -38,12 +38,14 @@
|
||||
#include "client.h"
|
||||
#include "debug.h"
|
||||
#include "msg.h"
|
||||
#include "utils.h"
|
||||
#include "version.h"
|
||||
|
||||
static struct common_conf *c_conf;
|
||||
static struct proxy_client *p_clients;
|
||||
static struct proxy_service *p_services;
|
||||
|
||||
static void new_ftp_data_proxy_service(struct proxy_service *ftp_ps);
|
||||
|
||||
struct common_conf *get_common_config()
|
||||
{
|
||||
@@ -67,11 +69,8 @@ void free_base_config(struct base_conf *bconf)
|
||||
{
|
||||
if (bconf->name) free(bconf->name);
|
||||
if (bconf->auth_token) free(bconf->auth_token);
|
||||
if (bconf->type) free(bconf->type);
|
||||
if (bconf->privilege_token) free(bconf->privilege_token);
|
||||
if (bconf->host_header_rewrite) free(bconf->host_header_rewrite);
|
||||
if (bconf->http_username) free(bconf->http_username);
|
||||
if (bconf->http_password) free(bconf->http_password);
|
||||
if (bconf->subdomain) free(bconf->subdomain);
|
||||
}
|
||||
|
||||
@@ -102,7 +101,8 @@ static const char *get_valid_type(const char *val)
|
||||
if (MATCH_VALUE("tcp") ||
|
||||
MATCH_VALUE("http") ||
|
||||
MATCH_VALUE("https") ||
|
||||
MATCH_VALUE("udp")) { // will add ftp support in here
|
||||
MATCH_VALUE("udp") ||
|
||||
MATCH_VALUE("ftp")) {
|
||||
|
||||
return val;
|
||||
}
|
||||
@@ -133,6 +133,21 @@ static void dump_proxy_service(const int index, struct proxy_service *ps)
|
||||
|
||||
if (NULL == ps->proxy_type) {
|
||||
ps->proxy_type = strdup("tcp");
|
||||
assert(ps->proxy_type);
|
||||
} else if (strcmp(ps->proxy_type, "ftp") == 0) {
|
||||
if (ps->remote_data_port <= 0) {
|
||||
debug(LOG_ERR,
|
||||
"Proxy [%s] error: remote_data_port must be exist when type is ftp",
|
||||
ps->proxy_name);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (!is_valid_ip_address((const char *)c_conf->server_addr)){
|
||||
debug(LOG_ERR, "now ftp proxy only support ip address in [server_addr]");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
new_ftp_data_proxy_service(ps);
|
||||
}
|
||||
|
||||
debug(LOG_DEBUG,
|
||||
@@ -157,7 +172,8 @@ static struct proxy_service *new_proxy_service(const char *name)
|
||||
{
|
||||
if (! name)
|
||||
return NULL;
|
||||
struct proxy_service *ps = calloc(sizeof(struct proxy_service), 1);
|
||||
|
||||
struct proxy_service *ps = (struct proxy_service *)calloc(sizeof(struct proxy_service), 1);
|
||||
assert(ps);
|
||||
assert(c_conf);
|
||||
|
||||
@@ -168,6 +184,7 @@ static struct proxy_service *new_proxy_service(const char *name)
|
||||
ps->use_encryption = 0;
|
||||
ps->local_port = -1;
|
||||
ps->remote_port = -1;
|
||||
ps->remote_data_port = -1;
|
||||
ps->use_compression = 0;
|
||||
ps->use_encryption = 0;
|
||||
|
||||
@@ -181,28 +198,53 @@ static struct proxy_service *new_proxy_service(const char *name)
|
||||
return ps;
|
||||
}
|
||||
|
||||
// create a new proxy service with suffix "_ftp_data_proxy"
|
||||
static void new_ftp_data_proxy_service(struct proxy_service *ftp_ps)
|
||||
{
|
||||
struct proxy_service *ps = NULL;
|
||||
char *ftp_data_proxy_name = get_ftp_data_proxy_name((const char *)ftp_ps->proxy_name);
|
||||
|
||||
HASH_FIND_STR(p_services, ftp_data_proxy_name, ps);
|
||||
if (!ps) {
|
||||
ps = new_proxy_service(ftp_data_proxy_name);
|
||||
if (! ps) {
|
||||
debug(LOG_ERR,
|
||||
"cannot create ftp data proxy service, it should not happenned!");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
ps->proxy_type = strdup("tcp");
|
||||
ps->remote_port = ftp_ps->remote_data_port;
|
||||
ps->local_ip = ftp_ps->local_ip;
|
||||
ps->local_port = 0; //will be init in working tunnel connectting
|
||||
|
||||
HASH_ADD_KEYPTR(hh, p_services, ps->proxy_name, strlen(ps->proxy_name), ps);
|
||||
}
|
||||
|
||||
free(ftp_data_proxy_name);
|
||||
}
|
||||
|
||||
static int
|
||||
proxy_service_handler(void *user, const char *sect, const char *nm, const char *value)
|
||||
{
|
||||
struct proxy_service *ps = NULL;
|
||||
|
||||
char *section = NULL;
|
||||
section = strdup(sect);
|
||||
assert(section);
|
||||
|
||||
if (strlen(sect) == 25) {//fix proxy name length = 25 bug, not find the reason
|
||||
section = calloc(1, 26);
|
||||
memset(section, '_', 26);
|
||||
memcpy(section, sect, 25);
|
||||
} else {
|
||||
section = strdup(sect);
|
||||
}
|
||||
|
||||
if (strcmp(section, "common") == 0)
|
||||
if (strcmp(section, "common") == 0) {
|
||||
SAFE_FREE(section);
|
||||
return 0;
|
||||
}
|
||||
|
||||
HASH_FIND_STR(p_services, section, ps);
|
||||
if (!ps) {
|
||||
ps = new_proxy_service(section);
|
||||
assert(ps);
|
||||
if (! ps) {
|
||||
debug(LOG_ERR, "cannot create proxy service, it should not happenned!");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
HASH_ADD_KEYPTR(hh, p_services, ps->proxy_name, strlen(ps->proxy_name), ps);
|
||||
}
|
||||
@@ -213,36 +255,47 @@ proxy_service_handler(void *user, const char *sect, const char *nm, const char *
|
||||
if (MATCH_NAME("type")) {
|
||||
if (! get_valid_type(value)) {
|
||||
debug(LOG_ERR, "proxy service type %s is not supportted", value);
|
||||
SAFE_FREE(section);
|
||||
exit(0);
|
||||
}
|
||||
ps->proxy_type = strdup(value);
|
||||
assert(ps->proxy_type);
|
||||
} else if (MATCH_NAME("local_ip")) {
|
||||
ps->local_ip = strdup(value);
|
||||
assert(ps->local_ip);
|
||||
} else if (MATCH_NAME("local_port")) {
|
||||
ps->local_port = atoi(value);
|
||||
} else if (MATCH_NAME("use_encryption")) {
|
||||
ps->use_encryption = is_true(value);
|
||||
} else if (MATCH_NAME("remote_port")) {
|
||||
ps->remote_port = atoi(value);
|
||||
} else if (MATCH_NAME("remote_data_port")) {
|
||||
ps->remote_data_port = atoi(value);
|
||||
} else if (MATCH_NAME("http_user")) {
|
||||
ps->http_user = strdup(value);
|
||||
assert(ps->http_user);
|
||||
} else if (MATCH_NAME("http_pwd")) {
|
||||
ps->http_pwd = strdup(value);
|
||||
assert(ps->http_pwd);
|
||||
} else if (MATCH_NAME("subdomain")) {
|
||||
ps->subdomain= strdup(value);
|
||||
ps->subdomain = strdup(value);
|
||||
assert(ps->http_pwd);
|
||||
} else if (MATCH_NAME("custom_domains")) {
|
||||
ps->custom_domains= strdup(value);
|
||||
ps->custom_domains = strdup(value);
|
||||
assert(ps->custom_domains);
|
||||
} else if (MATCH_NAME("locations")) {
|
||||
ps->locations= strdup(value);
|
||||
ps->locations = strdup(value);
|
||||
assert(ps->locations);
|
||||
} else if (MATCH_NAME("host_header_rewrite")) {
|
||||
ps->host_header_rewrite= strdup(value);
|
||||
ps->host_header_rewrite = strdup(value);
|
||||
assert(ps->host_header_rewrite);
|
||||
} else if (MATCH_NAME("use_encryption")) {
|
||||
ps->use_encryption = TO_BOOL(value);
|
||||
} else if (MATCH_NAME("use_compression")) {
|
||||
ps->use_compression = TO_BOOL(value);
|
||||
}
|
||||
|
||||
free(section);
|
||||
|
||||
SAFE_FREE(section);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -254,25 +307,31 @@ static int common_handler(void *user, const char *section, const char *name, con
|
||||
if (MATCH("common", "server_addr")) {
|
||||
SAFE_FREE(config->server_addr);
|
||||
config->server_addr = strdup(value);
|
||||
assert(config->server_addr);
|
||||
} else if (MATCH("common", "server_port")) {
|
||||
config->server_port = atoi(value);
|
||||
} else if (MATCH("common", "http_proxy")) {
|
||||
SAFE_FREE(config->http_proxy);
|
||||
config->http_proxy = strdup(value);
|
||||
assert(config->http_proxy);
|
||||
} else if (MATCH("common", "log_file")) {
|
||||
SAFE_FREE(config->log_file);
|
||||
config->log_file = strdup(value);
|
||||
assert(config->log_file);
|
||||
} else if (MATCH("common", "log_way")) {
|
||||
SAFE_FREE(config->log_way);
|
||||
config->log_way = strdup(value);
|
||||
assert(config->log_way);
|
||||
} else if (MATCH("common", "log_level")) {
|
||||
SAFE_FREE(config->log_level);
|
||||
config->log_level = strdup(value);
|
||||
assert(config->log_level);
|
||||
} else if (MATCH("common", "log_max_days")) {
|
||||
config->log_max_days = atoi(value);
|
||||
} else if (MATCH("common", "privilege_token")) {
|
||||
SAFE_FREE(config->privilege_token);
|
||||
config->privilege_token = strdup(value);
|
||||
assert(config->privilege_token);
|
||||
} else if (MATCH("common", "heartbeat_interval")) {
|
||||
config->heartbeat_interval = atoi(value);
|
||||
} else if (MATCH("common", "heartbeat_timeout")) {
|
||||
@@ -280,9 +339,11 @@ static int common_handler(void *user, const char *section, const char *name, con
|
||||
} else if (MATCH("common", "auth_token")) {
|
||||
SAFE_FREE(config->auth_token);
|
||||
config->auth_token = strdup(value);
|
||||
assert(config->auth_token);
|
||||
} else if (MATCH("common", "user")) {
|
||||
SAFE_FREE(config->user);
|
||||
config->user = strdup(value);
|
||||
assert(config->user);
|
||||
} else if (MATCH("common", "tcp_mux")) {
|
||||
config->tcp_mux = 0; // set tcp_mux to default: false
|
||||
}
|
||||
@@ -295,20 +356,42 @@ static void init_common_conf(struct common_conf *config)
|
||||
return;
|
||||
|
||||
config->server_addr = strdup("0.0.0.0");
|
||||
assert(config->server_addr);
|
||||
config->server_port = 7000;
|
||||
config->log_file = strdup("console");
|
||||
assert(config->log_file);
|
||||
config->log_way = strdup("console");
|
||||
assert(config->log_way);
|
||||
config->log_level = strdup("info");
|
||||
assert(config->log_level);
|
||||
config->log_max_days = 3;
|
||||
config->heartbeat_interval = 10;
|
||||
config->heartbeat_timeout = 30;
|
||||
config->heartbeat_interval = 30;
|
||||
config->heartbeat_timeout = 60;
|
||||
config->tcp_mux = 0;
|
||||
config->user = NULL;
|
||||
}
|
||||
|
||||
// it should be free after using
|
||||
// because of assert it will never return NULL
|
||||
char *get_ftp_data_proxy_name(const char *ftp_proxy_name)
|
||||
{
|
||||
char *ftp_tail_data_name = FTP_DATA_PROXY_SUFFIX;
|
||||
char *ftp_data_proxy_name = (char *)calloc(1,
|
||||
strlen(ftp_proxy_name)+strlen(ftp_tail_data_name)+1);
|
||||
assert(ftp_data_proxy_name);
|
||||
|
||||
snprintf(ftp_data_proxy_name,
|
||||
strlen(ftp_proxy_name) + strlen(ftp_tail_data_name) + 1,
|
||||
"%s%s",
|
||||
ftp_proxy_name,
|
||||
ftp_tail_data_name);
|
||||
|
||||
return ftp_data_proxy_name;
|
||||
}
|
||||
|
||||
void load_config(const char *confile)
|
||||
{
|
||||
c_conf = calloc(sizeof(struct common_conf), 1);
|
||||
c_conf = (struct common_conf *)calloc(sizeof(struct common_conf), 1);
|
||||
assert(c_conf);
|
||||
|
||||
init_common_conf(c_conf);
|
||||
|
||||
6
config.h
6
config.h
@@ -29,18 +29,17 @@
|
||||
#include "client.h"
|
||||
#include "common.h"
|
||||
|
||||
#define FTP_DATA_PROXY_SUFFIX "_ftp_data_proxy"
|
||||
|
||||
struct base_conf{
|
||||
char *name;
|
||||
char *auth_token;
|
||||
char *type;
|
||||
int use_encryption;
|
||||
int use_gzip;
|
||||
int privilege_mode;
|
||||
char *privilege_token;
|
||||
int pool_count;
|
||||
char *host_header_rewrite;
|
||||
char *http_username;
|
||||
char *http_password;
|
||||
char *subdomain;
|
||||
};
|
||||
|
||||
@@ -71,5 +70,6 @@ void free_base_config(struct base_conf *bconf);
|
||||
struct proxy_client *get_all_pc();
|
||||
|
||||
void load_config(const char *confile);
|
||||
char *get_ftp_data_proxy_name(const char *ftp_proxy_name);
|
||||
|
||||
#endif //_CONFIG_H_
|
||||
|
||||
185
control.c
185
control.c
@@ -35,7 +35,6 @@
|
||||
|
||||
#include <json-c/json.h>
|
||||
#include <syslog.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include <event2/bufferevent.h>
|
||||
#include <event2/buffer.h>
|
||||
@@ -91,16 +90,17 @@ static int client_connected(int is_connected)
|
||||
|
||||
static int set_client_work_start(struct proxy_client *client, int is_start_work)
|
||||
{
|
||||
if (is_start_work)
|
||||
if (is_start_work) {
|
||||
assert(client->ps);
|
||||
client->work_started = 1;
|
||||
else
|
||||
}else
|
||||
client->work_started = 0;
|
||||
|
||||
return client->work_started;
|
||||
}
|
||||
|
||||
static int is_client_work_started(struct proxy_client *client) {
|
||||
return client->work_started;
|
||||
return client->work_started && client->ps;
|
||||
}
|
||||
|
||||
static void client_start_event_cb(struct bufferevent *bev, short what, void *ctx)
|
||||
@@ -122,14 +122,13 @@ static void client_start_event_cb(struct bufferevent *bev, short what, void *ctx
|
||||
bufferevent_setcb(bev, recv_cb, NULL, client_start_event_cb, client);
|
||||
bufferevent_enable(bev, EV_READ|EV_WRITE);
|
||||
sync_new_work_connection(bev);
|
||||
debug(LOG_INFO, "proxy service connected");
|
||||
debug(LOG_INFO, "proxy service start");
|
||||
}
|
||||
}
|
||||
|
||||
static void new_client_connect()
|
||||
{
|
||||
struct proxy_client *client = calloc(1, sizeof(struct proxy_client)); //NEED FREE
|
||||
assert(client);
|
||||
struct proxy_client *client = new_proxy_client();
|
||||
struct common_conf *c_conf = get_common_config();
|
||||
assert(c_conf);
|
||||
client->base = main_ctl->connect_base;;
|
||||
@@ -200,74 +199,20 @@ static size_t request(struct bufferevent *bev, struct frame *f)
|
||||
goto REQ_END;
|
||||
}
|
||||
|
||||
// #define DEV_DEBUG 1
|
||||
#ifdef DEV_DEBUG
|
||||
/* debug showing */
|
||||
debug(LOG_DEBUG, "send request byte:");
|
||||
unsigned int i = 0;
|
||||
if (f->len) {
|
||||
printf("[");
|
||||
for(i = 0; i<f->len; i++) {
|
||||
printf("%u ", f->data[i]);
|
||||
}
|
||||
printf("]\n");
|
||||
}
|
||||
#endif // DEV_DEBUG
|
||||
|
||||
struct common_conf *c = get_common_config();
|
||||
if ( ! c)
|
||||
goto REQ_END;
|
||||
|
||||
int headersize = get_header_size();
|
||||
size_t len = (1<<16) + headersize;
|
||||
|
||||
memset(request_buf, 0, len);
|
||||
if (c->tcp_mux) {
|
||||
request_buf[VERI] = f->ver;
|
||||
request_buf[CMDI] = f->cmd;
|
||||
*((ushort *)(request_buf + 2)) = f->len;
|
||||
*((uint32_t *)(request_buf + 4)) = f->sid;
|
||||
|
||||
// insert data to request buffer
|
||||
if (f->data != NULL && f->len > 0) { //TODO: ENCODE when control
|
||||
memcpy(request_buf + DATAI, f->data, f->len);
|
||||
}
|
||||
write_len = (size_t) (headersize + f->len);
|
||||
|
||||
} else {
|
||||
memcpy(request_buf, f->data, f->len);
|
||||
write_len = (size_t)f->len;
|
||||
}
|
||||
|
||||
write_len = (size_t)f->len;
|
||||
if ( 0 == write_len)
|
||||
goto REQ_END;;
|
||||
|
||||
bufferevent_write(bout, request_buf, write_len);
|
||||
memset(request_buf, 0, len);
|
||||
bufferevent_write(bout, f->data, write_len);
|
||||
|
||||
REQ_END:
|
||||
return write_len;
|
||||
}
|
||||
|
||||
void control_request_free(struct control_request *req)
|
||||
{
|
||||
if (!req)
|
||||
return;
|
||||
|
||||
if (req->proxy_name) free(req->proxy_name);
|
||||
if (req->auth_key) free(req->auth_key);
|
||||
if (req->privilege_key) free(req->privilege_key);
|
||||
if (req->proxy_type) free(req->proxy_type);
|
||||
if (req->custom_domains) free(req->custom_domains);
|
||||
if (req->locations) free(req->locations);
|
||||
if (req->host_header_rewrite) free(req->host_header_rewrite);
|
||||
if (req->http_username) free(req->http_username);
|
||||
if (req->http_password) free(req->http_password);
|
||||
if (req->subdomain) free(req->subdomain);
|
||||
|
||||
free(req);
|
||||
}
|
||||
|
||||
static void base_control_ping(struct bufferevent *bev) {
|
||||
if ( ! is_client_connected())
|
||||
return;
|
||||
@@ -424,7 +369,7 @@ raw_message(struct message *msg, struct bufferevent *bev, struct proxy_client *c
|
||||
{
|
||||
if (client) {
|
||||
if (client->work_started) {
|
||||
debug(LOG_DEBUG, "raw client [%s] control message.", client->name);
|
||||
debug(LOG_DEBUG, "raw client [%s] control message.", client->ps->proxy_name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -490,14 +435,13 @@ raw_message(struct message *msg, struct bufferevent *bev, struct proxy_client *c
|
||||
}
|
||||
|
||||
client->ps = ps;
|
||||
client->name = ps->proxy_name;
|
||||
debug(LOG_INFO,
|
||||
"proxy service [%s] [%s:%d] start work connection.",
|
||||
sr->proxy_name,
|
||||
ps->local_ip,
|
||||
ps->local_port);
|
||||
|
||||
start_frp_tunnel(client);
|
||||
start_xfrp_tunnel(client);
|
||||
set_client_work_start(client, 1);
|
||||
break;
|
||||
case TypePong:
|
||||
@@ -513,7 +457,8 @@ static size_t data_handler(unsigned char *buf, ushort len, struct proxy_client *
|
||||
{
|
||||
struct bufferevent *bev = NULL;
|
||||
if (client) {
|
||||
debug(LOG_DEBUG, "client [name:%s] recved control data", client->name);
|
||||
debug(LOG_DEBUG, "client(%s): recved control data",
|
||||
is_client_work_started(client)?"work":"free");
|
||||
bev = client->ctl_bev;
|
||||
}
|
||||
unsigned char *ret_buf = NULL;
|
||||
@@ -671,7 +616,7 @@ static unsigned char
|
||||
if (is_client_work_started(client)) {
|
||||
debug(LOG_DEBUG,
|
||||
"client [%s] send all work data to proxy tunnel.",
|
||||
client->name);
|
||||
client->ps->proxy_name);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@@ -680,8 +625,6 @@ static unsigned char
|
||||
if (buf_len > split_lv) {
|
||||
if (! is_logged()) {
|
||||
if (buf[0] == 49) {
|
||||
debug(LOG_DEBUG, "mulity raw login-response...");
|
||||
|
||||
msg_size_t data_len_bigend;
|
||||
data_len_bigend = *(msg_size_t *)(buf + MSG_LEN_I);
|
||||
msg_size_t data_len = msg_ntoh(data_len_bigend);
|
||||
@@ -769,7 +712,6 @@ static void recv_cb(struct bufferevent *bev, void *ctx)
|
||||
if (read_n) {
|
||||
unsigned char *raw_buf_p = buf;
|
||||
for( ; raw_buf_p && read_n ; ) {
|
||||
|
||||
// #define CONN_DEBUG 1
|
||||
#ifdef CONN_DEBUG
|
||||
unsigned int i = 0;
|
||||
@@ -778,7 +720,7 @@ static void recv_cb(struct bufferevent *bev, void *ctx)
|
||||
for(i = 0; i<read_n && ((2 * i) < (read_n * 2 + 1)); i++) {
|
||||
snprintf(dbg_buf + 4*i, 5, "%3u ", (unsigned char)raw_buf_p[i]);
|
||||
}
|
||||
debug(LOG_DEBUG, "[%s]: RECV ctl byte:%s", client ? "client":"control", dbg_buf);
|
||||
debug(LOG_DEBUG, "[%s]: RECV ctl byte:%s", client?"client":"control", dbg_buf);
|
||||
SAFE_FREE(dbg_buf);
|
||||
#endif //CONN_DEBUG
|
||||
|
||||
@@ -820,7 +762,16 @@ static void open_connection_session(struct bufferevent *bev)
|
||||
static void connect_event_cb (struct bufferevent *bev, short what, void *ctx)
|
||||
{
|
||||
struct common_conf *c_conf = get_common_config();
|
||||
static int retry_times = 0;
|
||||
if (what & (BEV_EVENT_EOF|BEV_EVENT_ERROR)) {
|
||||
if (retry_times >= 10) {
|
||||
debug(LOG_INFO,
|
||||
"have retry connect to xfrp server for %d times, exit!",
|
||||
retry_times);
|
||||
|
||||
exit(0);
|
||||
}
|
||||
retry_times++;
|
||||
debug(LOG_ERR, "connect server [%s:%d] failed",
|
||||
c_conf->server_addr,
|
||||
c_conf->server_port);
|
||||
@@ -829,7 +780,8 @@ static void connect_event_cb (struct bufferevent *bev, short what, void *ctx)
|
||||
start_base_connect();
|
||||
close_main_control();
|
||||
} else if (what & BEV_EVENT_CONNECTED) {
|
||||
// recv frpc login-response message before recv othfer fprs messages,
|
||||
retry_times = 0;
|
||||
// recv login-response message before recving othfer fprs messages,
|
||||
bufferevent_setcb(bev, recv_cb, NULL, connect_event_cb, NULL);
|
||||
bufferevent_enable(bev, EV_READ|EV_WRITE|EV_PERSIST);
|
||||
|
||||
@@ -859,7 +811,10 @@ void start_base_connect()
|
||||
c_conf->server_addr,
|
||||
c_conf->server_port);
|
||||
if ( ! main_ctl->connect_bev) {
|
||||
debug(LOG_ERR, "Connect server [%s:%d] failed", c_conf->server_addr, c_conf->server_port);
|
||||
debug(LOG_ERR,
|
||||
"Connect server [%s:%d] failed",
|
||||
c_conf->server_addr,
|
||||
c_conf->server_port);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
@@ -936,32 +891,25 @@ void send_msg_frp_server(struct bufferevent *bev,
|
||||
req_msg.type = type;
|
||||
req_msg.data_len = msg_len;
|
||||
|
||||
if (msg) {
|
||||
req_msg.data_p = strdup(msg);
|
||||
}
|
||||
|
||||
unsigned char *puck_buf = NULL;
|
||||
size_t pack_buf_len = pack(&req_msg, &puck_buf);
|
||||
if ( ! pack_buf_len || ! puck_buf) {
|
||||
debug(LOG_ERR, "login buffer pack failed!");
|
||||
return;
|
||||
}
|
||||
|
||||
// #define SEND_MSG_DEBUG 1
|
||||
#ifdef SEND_MSG_DEBUG
|
||||
debug(LOG_DEBUG, "puck result:");
|
||||
size_t j = 0;
|
||||
for(j=0; j<pack_buf_len; j++) {
|
||||
printf("%d ", (unsigned char)puck_buf[j]);
|
||||
}
|
||||
printf("\n\n");
|
||||
#endif // SEND_MSG_DEBUG
|
||||
|
||||
char frame_type = 0;
|
||||
struct frame *f = NULL;
|
||||
f = new_frame(frame_type, sid); // frame_type not truely matter, it will reset by set_frame_cmd
|
||||
|
||||
// frame_type not truely matter, it will reset by set_frame_cmd
|
||||
f = new_frame(frame_type, sid);
|
||||
assert(f);
|
||||
|
||||
if (msg) {
|
||||
req_msg.data_p = strdup(msg);
|
||||
assert(req_msg.data_p);
|
||||
}
|
||||
|
||||
unsigned char *pack_buf = NULL;
|
||||
size_t pack_buf_len = pack(&req_msg, &pack_buf);
|
||||
if ( ! pack_buf_len || ! pack_buf) {
|
||||
debug(LOG_ERR, "send buffer pack failed!");
|
||||
goto S_M_F_END;
|
||||
}
|
||||
|
||||
#ifdef ENCRYPTO
|
||||
debug(LOG_DEBUG, "start encode message ...");
|
||||
unsigned char *encode_ret;
|
||||
@@ -970,7 +918,7 @@ void send_msg_frp_server(struct bufferevent *bev,
|
||||
struct frp_coder *encoder = get_main_encoder();
|
||||
|
||||
if (encoder) {
|
||||
size_t encode_ret_len = encrypt_data(puck_buf, pack_buf_len, encoder, &encode_ret);
|
||||
size_t encode_ret_len = encrypt_data(pack_buf, pack_buf_len, encoder, &encode_ret);
|
||||
debug(LOG_DEBUG, "encode len:[%lu]", encode_ret_len);
|
||||
|
||||
if (encode_ret_len > 0) {
|
||||
@@ -984,28 +932,32 @@ void send_msg_frp_server(struct bufferevent *bev,
|
||||
#endif //ENCRYPTO
|
||||
if (! f->data) {
|
||||
set_frame_len(f, (ushort) pack_buf_len);
|
||||
f->data = puck_buf;
|
||||
f->data = pack_buf;
|
||||
}
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case TypeLogin:
|
||||
case TypePong:
|
||||
case TypePing:
|
||||
case TypeNewProxy:
|
||||
if (get_common_config()->tcp_mux) {
|
||||
switch (type)
|
||||
{
|
||||
case TypeLogin:
|
||||
case TypePong:
|
||||
case TypePing:
|
||||
case TypeNewProxy:
|
||||
frame_type = cmdPSH;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
frame_type = cmdPSH;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
set_frame_cmd(f, frame_type);
|
||||
request(bout, f);
|
||||
|
||||
S_M_F_END:
|
||||
SAFE_FREE(req_msg.data_p);
|
||||
SAFE_FREE(puck_buf);
|
||||
f->data = NULL;
|
||||
SAFE_FREE(f->data);
|
||||
free_frame(f);
|
||||
}
|
||||
|
||||
@@ -1017,13 +969,18 @@ struct control *get_main_control()
|
||||
void start_login_frp_server(struct event_base *base)
|
||||
{
|
||||
struct common_conf *c_conf = get_common_config();
|
||||
struct bufferevent *bev = connect_server(base, c_conf->server_addr, c_conf->server_port);
|
||||
struct bufferevent *bev = connect_server(base,
|
||||
c_conf->server_addr,
|
||||
c_conf->server_port);
|
||||
if (!bev) {
|
||||
debug(LOG_DEBUG, "Connect server [%s:%d] failed", c_conf->server_addr, c_conf->server_port);
|
||||
debug(LOG_DEBUG,
|
||||
"Connect server [%s:%d] failed",
|
||||
c_conf->server_addr,
|
||||
c_conf->server_port);
|
||||
return;
|
||||
}
|
||||
|
||||
debug(LOG_INFO, "Xfrpc login: connect server [%s:%d] ......", c_conf->server_addr, c_conf->server_port);
|
||||
debug(LOG_INFO, "Xfrpc login: connect server [%s:%d] ...", c_conf->server_addr, c_conf->server_port);
|
||||
|
||||
bufferevent_enable(bev, EV_WRITE|EV_READ);
|
||||
bufferevent_setcb(bev, NULL, NULL, connect_event_cb, NULL);
|
||||
|
||||
@@ -70,6 +70,4 @@ void send_new_proxy(struct proxy_service *ps);
|
||||
struct bufferevent
|
||||
*connect_server(struct event_base *base, const char *name, const int port);
|
||||
|
||||
void control_request_free(struct control_request *req);
|
||||
|
||||
#endif //_CONTROL_H_
|
||||
2
crypto.c
2
crypto.c
@@ -31,8 +31,10 @@ struct frp_coder *new_coder(const char *privilege_token, const char *salt)
|
||||
assert(enc);
|
||||
|
||||
enc->privilege_token = privilege_token ? strdup(privilege_token):"\0";
|
||||
assert(enc->privilege_token);
|
||||
enc->key_len = block_size;
|
||||
enc->salt = strdup(salt);
|
||||
assert(enc->salt);
|
||||
enc->key = encrypt_key(enc->privilege_token, strlen(enc->privilege_token), enc->salt);
|
||||
enc->iv = calloc(block_size, 1);
|
||||
encrypt_iv(enc->iv, block_size);
|
||||
|
||||
3
frame.c
3
frame.c
@@ -20,6 +20,7 @@ struct frame *new_frame(char cmd, uint32_t sid) {
|
||||
f->cmd = cmd;
|
||||
f->sid = sid;
|
||||
f->len = 0;
|
||||
f->data = NULL;
|
||||
}
|
||||
|
||||
return f;
|
||||
@@ -34,7 +35,7 @@ struct frame *raw_frame(unsigned char *buf, const size_t buf_len)
|
||||
}
|
||||
char ver = buf[VERI];
|
||||
char cmd = buf[CMDI];
|
||||
uint32_t sid = *(uint32_t *)(buf + SIDI);
|
||||
uint32_t sid = htonl(*(uint32_t *)(buf + SIDI));
|
||||
|
||||
struct frame *f = new_frame(cmd, sid);
|
||||
f->ver = ver;
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
/usr/bin/xfrp_client
|
||||
/usr/bin/xfrpc
|
||||
/usr/bin/xfrp_test_server
|
||||
15
login.c
15
login.c
@@ -37,6 +37,7 @@ void init_login()
|
||||
{
|
||||
if (! c_login)
|
||||
c_login = calloc(sizeof(struct login), 1);
|
||||
|
||||
assert(c_login);
|
||||
|
||||
struct common_conf *c_conf = get_common_config();
|
||||
@@ -48,9 +49,12 @@ void init_login()
|
||||
}
|
||||
|
||||
c_login->version = strdup(PROTOCOL_VERESION);
|
||||
assert(c_login->version);
|
||||
c_login->hostname = NULL;
|
||||
c_login->os = strdup(uname_buf.sysname);
|
||||
c_login->os = strdup(uname_buf.sysname);
|
||||
assert(c_login->os);
|
||||
c_login->arch = strdup(uname_buf.machine);
|
||||
assert(c_login->arch);
|
||||
c_login->user = NULL;
|
||||
|
||||
c_login->timestamp = 0;
|
||||
@@ -64,11 +68,6 @@ void init_login()
|
||||
|
||||
int login_resp_check(struct login_resp *lr)
|
||||
{
|
||||
debug(LOG_DEBUG, "xfrp login response: run_id: [%s], version: [%s], error: [%s]",
|
||||
lr->run_id,
|
||||
lr->version,
|
||||
lr->error);
|
||||
|
||||
if (lr->run_id == NULL || strlen(lr->run_id) <= 1) {
|
||||
if (lr->error && strlen(lr->error) > 0) {
|
||||
debug(LOG_ERR, "login response error: %s", lr->error);
|
||||
@@ -77,9 +76,13 @@ int login_resp_check(struct login_resp *lr)
|
||||
c_login->logged = 0;
|
||||
} else {
|
||||
c_login->logged = 1;
|
||||
debug(LOG_DEBUG, "xfrp login response: run_id: [%s], version: [%s]",
|
||||
lr->run_id,
|
||||
lr->version);
|
||||
SAFE_FREE(c_login->run_id);
|
||||
|
||||
c_login->run_id = strdup(lr->run_id);
|
||||
assert(c_login->run_id);
|
||||
}
|
||||
|
||||
return c_login->logged;
|
||||
|
||||
4
main.c
4
main.c
@@ -24,7 +24,7 @@
|
||||
@author Copyright (C) 2016 Dengfeng Liu <liudengfeng@kunteng.org>
|
||||
*/
|
||||
|
||||
#include "xfrp_client.h"
|
||||
#include "xfrpc.h"
|
||||
#include "commandline.h"
|
||||
#include "login.h"
|
||||
|
||||
@@ -32,5 +32,5 @@ int main(int argc, char **argv)
|
||||
{
|
||||
parse_commandline(argc, argv);
|
||||
init_login();
|
||||
xfrp_client_loop();
|
||||
xfrpc_loop();
|
||||
}
|
||||
|
||||
46
msg.c
46
msg.c
@@ -41,6 +41,7 @@
|
||||
#include "debug.h"
|
||||
#include "common.h"
|
||||
#include "login.h"
|
||||
#include "client.h"
|
||||
|
||||
#define JSON_MARSHAL_TYPE(jobj,key,jtype,item) \
|
||||
json_object_object_add(jobj, key, json_object_new_##jtype((item)));
|
||||
@@ -75,6 +76,7 @@ static void fill_custom_domains(struct json_object *j_ctl_req, const char *custo
|
||||
struct json_object *jarray_cdomains = json_object_new_array();
|
||||
assert(jarray_cdomains);
|
||||
char *tmp = strdup(custom_domains);
|
||||
assert(tmp);
|
||||
char *tok = tmp, *end = tmp;
|
||||
while (tok != NULL) {
|
||||
strsep(&end, ",");
|
||||
@@ -133,6 +135,7 @@ size_t login_request_marshal(char **msg)
|
||||
struct common_conf *cf = get_common_config();
|
||||
char *auth_key = get_auth_key(cf->privilege_token, &lg->timestamp);
|
||||
lg->privilege_key = strdup(auth_key);
|
||||
assert(lg->privilege_key);
|
||||
|
||||
JSON_MARSHAL_TYPE(j_login_req, "version", string, lg->version);
|
||||
JSON_MARSHAL_TYPE(j_login_req, "hostname", string, SAFE_JSON_STRING(lg->hostname));
|
||||
@@ -150,6 +153,7 @@ size_t login_request_marshal(char **msg)
|
||||
if (tmp && strlen(tmp) > 0) {
|
||||
nret = strlen(tmp);
|
||||
*msg = strdup(tmp);
|
||||
assert(*msg);
|
||||
}
|
||||
json_object_put(j_login_req);
|
||||
SAFE_FREE(auth_key);
|
||||
@@ -170,6 +174,10 @@ int new_proxy_service_marshal(const struct proxy_service *np_req, char **msg)
|
||||
JSON_MARSHAL_TYPE(j_np_req, "use_compression", boolean, np_req->use_compression);
|
||||
JSON_MARSHAL_TYPE(j_np_req, "remote_port", int, np_req->remote_port);
|
||||
|
||||
if (is_ftp_proxy(np_req)) {
|
||||
JSON_MARSHAL_TYPE(j_np_req, "remote_data_port", int, np_req->remote_data_port);
|
||||
}
|
||||
|
||||
if (np_req->custom_domains) {
|
||||
fill_custom_domains(j_np_req, np_req->custom_domains);
|
||||
} else {
|
||||
@@ -193,6 +201,7 @@ int new_proxy_service_marshal(const struct proxy_service *np_req, char **msg)
|
||||
if (tmp && strlen(tmp) > 0) {
|
||||
nret = strlen(tmp);
|
||||
*msg = strdup(tmp);
|
||||
assert(*msg);
|
||||
}
|
||||
json_object_put(j_np_req);
|
||||
|
||||
@@ -212,6 +221,7 @@ int new_work_conn_marshal(const struct work_conn *work_c, char **msg)
|
||||
if (tmp && strlen(tmp) > 0) {
|
||||
nret = strlen(tmp);
|
||||
*msg = strdup(tmp);
|
||||
assert(*msg);
|
||||
}
|
||||
|
||||
json_object_put(j_new_work_conn);
|
||||
@@ -227,25 +237,25 @@ struct login_resp *login_resp_unmarshal(const char *jres)
|
||||
return NULL;
|
||||
|
||||
struct login_resp *lr = calloc(1, sizeof(struct login_resp));
|
||||
if (lr == NULL) {
|
||||
goto END_ERROR;
|
||||
}
|
||||
assert(lr);
|
||||
|
||||
struct json_object *l_version = NULL;
|
||||
if (! json_object_object_get_ex(j_lg_res, "version", &l_version))
|
||||
goto END_ERROR;
|
||||
lr->version = strdup(json_object_get_string(l_version));
|
||||
assert(lr->version);
|
||||
|
||||
struct json_object *l_run_id = NULL;
|
||||
if (! json_object_object_get_ex(j_lg_res, "run_id", &l_run_id))
|
||||
goto END_ERROR;
|
||||
lr->run_id = strdup(json_object_get_string(l_run_id));
|
||||
|
||||
assert(lr->run_id);
|
||||
|
||||
struct json_object *l_error = NULL;
|
||||
if(! json_object_object_get_ex(j_lg_res, "error", &l_error))
|
||||
goto END_ERROR;
|
||||
lr->error = strdup(json_object_get_string(l_error));
|
||||
assert(lr->error);
|
||||
|
||||
END_ERROR:
|
||||
json_object_put(j_lg_res);
|
||||
@@ -259,13 +269,14 @@ struct start_work_conn_resp *start_work_conn_resp_unmarshal(const char *resp_msg
|
||||
return NULL;
|
||||
|
||||
struct start_work_conn_resp *sr = calloc(1, sizeof(struct start_work_conn_resp));
|
||||
if (! sr)
|
||||
goto START_W_C_R_END;
|
||||
assert(sr);
|
||||
|
||||
struct json_object *pn = NULL;
|
||||
if(! json_object_object_get_ex(j_start_w_res, "proxy_name", &pn))
|
||||
goto START_W_C_R_END;
|
||||
|
||||
sr->proxy_name = strdup(json_object_get_string(pn));
|
||||
assert(sr->proxy_name);
|
||||
|
||||
START_W_C_R_END:
|
||||
json_object_put(j_start_w_res);
|
||||
@@ -278,9 +289,7 @@ struct control_response *control_response_unmarshal(const char *jres)
|
||||
if (is_error(j_ctl_res))
|
||||
return NULL;
|
||||
struct control_response *ctl_res = calloc(sizeof(struct control_response), 1);
|
||||
if (ctl_res == NULL) {
|
||||
goto END_ERROR;
|
||||
}
|
||||
assert(ctl_res);
|
||||
|
||||
struct json_object *jtype = NULL;
|
||||
if(! json_object_object_get_ex(j_ctl_res, "type", &jtype))
|
||||
@@ -293,9 +302,11 @@ struct control_response *control_response_unmarshal(const char *jres)
|
||||
ctl_res->code = json_object_get_int(jcode);
|
||||
|
||||
struct json_object *jmsg = NULL;
|
||||
if(json_object_object_get_ex(j_ctl_res, "msg", &jmsg))
|
||||
if(json_object_object_get_ex(j_ctl_res, "msg", &jmsg)) {
|
||||
ctl_res->msg = strdup(json_object_get_string(jmsg));
|
||||
|
||||
assert(ctl_res->msg);
|
||||
}
|
||||
|
||||
END_ERROR:
|
||||
json_object_put(j_ctl_res);
|
||||
return ctl_res;
|
||||
@@ -357,20 +368,13 @@ size_t pack(struct message *req_msg, unsigned char **ret_buf)
|
||||
else
|
||||
data_len_bigend = req_msg->data_len;
|
||||
|
||||
|
||||
size_t buf_len = TYPE_LEN + sizeof(data_len_bigend) + req_msg->data_len;
|
||||
*ret_buf = calloc(buf_len, 1);
|
||||
|
||||
if (*ret_buf == NULL) {
|
||||
return 0;
|
||||
}
|
||||
*ret_buf = calloc(1, buf_len);
|
||||
assert(*ret_buf);
|
||||
|
||||
*(*ret_buf + MSG_TYPE_I) = req_msg->type;
|
||||
*(msg_size_t *)(*ret_buf + MSG_LEN_I) = data_len_bigend;
|
||||
snprintf((char *)*ret_buf + TYPE_LEN + sizeof(data_len_bigend),
|
||||
req_msg->data_len + 1,
|
||||
"%s",
|
||||
req_msg->data_p);
|
||||
memcpy((char *)*ret_buf+TYPE_LEN+sizeof(data_len_bigend), req_msg->data_p, req_msg->data_len);
|
||||
|
||||
return buf_len;
|
||||
}
|
||||
24
msg.h
24
msg.h
@@ -61,29 +61,6 @@ struct general_response {
|
||||
char *msg;
|
||||
};
|
||||
|
||||
// messages between control connections of frpc and frps
|
||||
struct control_request {
|
||||
int type;
|
||||
char *proxy_name;
|
||||
char *auth_key;
|
||||
int use_encryption;
|
||||
int use_gzip;
|
||||
int pool_count;
|
||||
|
||||
int privilege_mode;
|
||||
char *privilege_key;
|
||||
char *proxy_type;
|
||||
int remote_port;
|
||||
char *custom_domains;
|
||||
char *locations;
|
||||
char *host_header_rewrite;
|
||||
char *http_username;
|
||||
char *http_password;
|
||||
char *subdomain;
|
||||
long timestamp;
|
||||
};
|
||||
|
||||
|
||||
struct control_response {
|
||||
int type;
|
||||
int code;
|
||||
@@ -114,7 +91,6 @@ size_t pack(struct message *req_msg, unsigned char **ret_buf);
|
||||
struct message *unpack(unsigned char *recv_msg, const ushort len);
|
||||
|
||||
// tranlate control request to json string
|
||||
int control_request_marshal(const struct control_request *req, char **msg);
|
||||
struct login_resp *login_resp_unmarshal(const char *jres);
|
||||
struct start_work_conn_resp *start_work_conn_resp_unmarshal(const char *resp_msg);
|
||||
|
||||
|
||||
36
proxy.c
Normal file
36
proxy.c
Normal file
@@ -0,0 +1,36 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <errno.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include <event2/bufferevent.h>
|
||||
#include <event2/buffer.h>
|
||||
#include <event2/listener.h>
|
||||
#include <event2/event.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "uthash.h"
|
||||
#include "common.h"
|
||||
#include "proxy.h"
|
||||
#include "config.h"
|
||||
|
||||
struct proxy *new_proxy_buf(struct bufferevent *bev)
|
||||
{
|
||||
struct proxy *p = (struct proxy *)calloc(1, sizeof(struct proxy));
|
||||
assert(p);
|
||||
p->bev = bev;
|
||||
p->remote_data_port = -1;
|
||||
p->proxy_name = NULL;
|
||||
return p;
|
||||
}
|
||||
|
||||
void free_proxy(struct proxy *p)
|
||||
{
|
||||
SAFE_FREE(p->proxy_name);
|
||||
SAFE_FREE(p);
|
||||
}
|
||||
37
proxy.h
Normal file
37
proxy.h
Normal file
@@ -0,0 +1,37 @@
|
||||
#ifndef _PROXY_H_
|
||||
#define _PROXY_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <event2/bufferevent.h>
|
||||
#include <event2/buffer.h>
|
||||
#include <event2/listener.h>
|
||||
#include <event2/util.h>
|
||||
#include <event2/event.h>
|
||||
|
||||
#include "client.h"
|
||||
#include "common.h"
|
||||
|
||||
#define IP_LEN 16
|
||||
|
||||
struct ftp_pasv {
|
||||
int code;
|
||||
char ftp_server_ip[IP_LEN];
|
||||
int ftp_server_port;
|
||||
};
|
||||
|
||||
struct proxy {
|
||||
struct bufferevent *bev;
|
||||
char *proxy_name;
|
||||
int remote_data_port; //used in ftp proxy
|
||||
};
|
||||
|
||||
void tcp_proxy_c2s_cb(struct bufferevent *bev, void *ctx);
|
||||
void tcp_proxy_s2c_cb(struct bufferevent *bev, void *ctx);
|
||||
void ftp_proxy_c2s_cb(struct bufferevent *bev, void *ctx);
|
||||
void ftp_proxy_s2c_cb(struct bufferevent *bev, void *ctx);
|
||||
struct proxy *new_proxy_buf(struct bufferevent *bev);
|
||||
void free_proxy(struct proxy *p);
|
||||
void set_ftp_data_proxy_tunnel(const char *ftp_proxy_name,
|
||||
struct ftp_pasv *local_fp,
|
||||
struct ftp_pasv *remote_fp);
|
||||
#endif //_PROXY_H_
|
||||
258
proxy_ftp.c
Normal file
258
proxy_ftp.c
Normal file
@@ -0,0 +1,258 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <errno.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include <event2/bufferevent.h>
|
||||
#include <event2/buffer.h>
|
||||
#include <event2/listener.h>
|
||||
#include <event2/event.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "uthash.h"
|
||||
#include "common.h"
|
||||
#include "proxy.h"
|
||||
#include "config.h"
|
||||
#include "client.h"
|
||||
|
||||
#define FTP_PRO_BUF 256
|
||||
#define FTP_PASV_PORT_BLOCK 256
|
||||
|
||||
static struct ftp_pasv *new_ftp_pasv();
|
||||
static void free_ftp_pasv(struct ftp_pasv *fp);
|
||||
static struct ftp_pasv * pasv_unpack(char *data);
|
||||
static size_t pasv_pack(struct ftp_pasv *fp, char **pack_p);
|
||||
|
||||
void set_ftp_data_proxy_tunnel(const char *ftp_proxy_name,
|
||||
struct ftp_pasv *local_fp,
|
||||
struct ftp_pasv *remote_fp)
|
||||
{
|
||||
struct proxy_service *ps = NULL;
|
||||
char *ftp_data_proxy_name = get_ftp_data_proxy_name(ftp_proxy_name);
|
||||
|
||||
struct proxy_service *p_services = get_all_proxy_services();
|
||||
HASH_FIND_STR(p_services, ftp_data_proxy_name, ps);
|
||||
if (!ps) {
|
||||
debug(LOG_ERR,
|
||||
"error: ftp data proxy not inserted in proxy-service queue, it should not happend!");
|
||||
goto FTP_DATA_PROXY_TUNNEL_END;
|
||||
}
|
||||
|
||||
ps->local_port = local_fp->ftp_server_port;
|
||||
ps->local_ip = strdup(local_fp->ftp_server_ip);
|
||||
assert(ps->local_ip);
|
||||
|
||||
ps->remote_port = remote_fp->ftp_server_port;
|
||||
|
||||
debug(LOG_DEBUG,
|
||||
"set ftp proxy DATA port [local:remote] = [%d:%d]",
|
||||
ps->local_port, ps->remote_port);
|
||||
|
||||
FTP_DATA_PROXY_TUNNEL_END:
|
||||
free(ftp_data_proxy_name);
|
||||
}
|
||||
|
||||
// read from client-working host port
|
||||
void ftp_proxy_c2s_cb(struct bufferevent *bev, void *ctx)
|
||||
{
|
||||
struct proxy *p = (struct proxy *)ctx;
|
||||
assert(p);
|
||||
struct bufferevent *partner = p->bev;
|
||||
|
||||
struct evbuffer *src, *dst;
|
||||
size_t len;
|
||||
src = bufferevent_get_input(bev);
|
||||
len = evbuffer_get_length(src);
|
||||
if (len < 0)
|
||||
return;
|
||||
|
||||
dst = bufferevent_get_output(partner);
|
||||
assert(dst);
|
||||
|
||||
unsigned char *buf = calloc(1, len);
|
||||
assert(buf);
|
||||
size_t read_n = 0;
|
||||
read_n = evbuffer_remove(src, buf, len);
|
||||
|
||||
// #define FTP_P_DEBUG 1
|
||||
#ifdef FTP_P_DEBUG
|
||||
char *dbg_buf = calloc(1, read_n * 7 + 1);
|
||||
assert(dbg_buf);
|
||||
unsigned int i = 0;
|
||||
for(i = 0; i<read_n && ((2 * i) < (read_n * 2 + 1)); i++) {
|
||||
snprintf(dbg_buf + 7*i, 8, "%3u[%c] ",
|
||||
(unsigned char)buf[i],
|
||||
(unsigned char)buf[i]);
|
||||
}
|
||||
debug(LOG_DEBUG, "FTP Client RECV ctl byte:%s", dbg_buf);
|
||||
debug(LOG_DEBUG, "FTP Client RECV ctl stri:%s", buf);
|
||||
SAFE_FREE(dbg_buf);
|
||||
#endif //FTP_P_DEBUG
|
||||
|
||||
struct ftp_pasv *local_fp = pasv_unpack((char *)buf);
|
||||
|
||||
if (local_fp) {
|
||||
struct common_conf *c_conf = get_common_config();
|
||||
struct ftp_pasv *r_fp = new_ftp_pasv();
|
||||
r_fp->code = local_fp->code;
|
||||
|
||||
strncpy(r_fp->ftp_server_ip, c_conf->server_addr, IP_LEN);
|
||||
r_fp->ftp_server_port = p->remote_data_port;
|
||||
|
||||
if (r_fp->ftp_server_port <= 0) {
|
||||
debug(LOG_ERR, "error: remote ftp data port is not init!");
|
||||
goto FTP_C2S_CB_END;
|
||||
}
|
||||
|
||||
char *pasv_msg = NULL;
|
||||
size_t pack_len = pasv_pack(r_fp, &pasv_msg);
|
||||
if ( ! pack_len){
|
||||
debug(LOG_ERR, "error: ftp proxy replace failed!");
|
||||
SAFE_FREE(pasv_msg);
|
||||
goto FTP_C2S_CB_END;
|
||||
}
|
||||
|
||||
set_ftp_data_proxy_tunnel(p->proxy_name, local_fp, r_fp);
|
||||
evbuffer_add(dst, pasv_msg, pack_len);
|
||||
SAFE_FREE(pasv_msg);
|
||||
} else {
|
||||
evbuffer_add(dst, buf, read_n);
|
||||
}
|
||||
|
||||
FTP_C2S_CB_END:
|
||||
SAFE_FREE(buf);
|
||||
free_ftp_pasv(local_fp);
|
||||
return;
|
||||
}
|
||||
|
||||
void ftp_proxy_s2c_cb(struct bufferevent *bev, void *ctx)
|
||||
{
|
||||
tcp_proxy_s2c_cb(bev, ctx);
|
||||
}
|
||||
|
||||
static struct ftp_pasv *pasv_unpack(char *data)
|
||||
{
|
||||
char cd_buf[4] = {0};
|
||||
snprintf(cd_buf, 4, "%s", data);
|
||||
int code = atoi(cd_buf);
|
||||
if (code != 227 && code != 211 && code != 229)
|
||||
return NULL;
|
||||
|
||||
struct ftp_pasv *fp = new_ftp_pasv();
|
||||
assert(fp);
|
||||
|
||||
fp->code = code;
|
||||
switch(fp->code) {
|
||||
case 227:
|
||||
{
|
||||
int i = 0, ip_i = 0, port_i = 0, ip_start = 0, comma_n = 0;
|
||||
char port[2][4] = { {0}, {0} };
|
||||
for (i=0; i<strlen(data) && ip_i<IP_LEN; i++) {
|
||||
if (data[i] == '(') {
|
||||
ip_start = 1;
|
||||
continue;
|
||||
}
|
||||
if (! ip_start)
|
||||
continue;
|
||||
|
||||
if (data[i] == ')')
|
||||
break;
|
||||
|
||||
if (data[i] == ','){
|
||||
comma_n++;
|
||||
port_i = 0;
|
||||
if (comma_n < 4){
|
||||
fp->ftp_server_ip[ip_i] = '.';
|
||||
ip_i++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (comma_n >= 4 && port_i < 4) {
|
||||
port[comma_n - 4][port_i] = data[i];
|
||||
port_i++;
|
||||
continue;
|
||||
}
|
||||
fp->ftp_server_ip[ip_i] = data[i];
|
||||
ip_i++;
|
||||
}
|
||||
|
||||
fp->ftp_server_port = atoi(port[0]) * FTP_PASV_PORT_BLOCK + atoi(port[1]);
|
||||
debug(LOG_DEBUG, "ftp pasv unpack:[%s:%d]", fp->ftp_server_ip, fp->ftp_server_port);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
free_ftp_pasv(fp);
|
||||
break;
|
||||
}
|
||||
|
||||
return fp;
|
||||
}
|
||||
|
||||
// the value returned need FREE after using
|
||||
static size_t pasv_pack(struct ftp_pasv *fp, char **pack_p)
|
||||
{
|
||||
*pack_p = (char *)calloc(1, FTP_PRO_BUF);
|
||||
assert(*pack_p);
|
||||
size_t pack_len = 0;
|
||||
|
||||
switch (fp->code){
|
||||
case 227:
|
||||
{
|
||||
char ftp_ip[IP_LEN] = {0};
|
||||
int i =0;
|
||||
for (i=0; i<strlen(fp->ftp_server_ip) && i < IP_LEN; i++) {
|
||||
if (fp->ftp_server_ip[i] == '.') {
|
||||
ftp_ip[i] = ',';
|
||||
continue;
|
||||
}
|
||||
|
||||
ftp_ip[i] = fp->ftp_server_ip[i];
|
||||
}
|
||||
snprintf(*pack_p,
|
||||
FTP_PRO_BUF,
|
||||
"227 Entering Passive Mode (%s,%d,%d).\n",
|
||||
ftp_ip,
|
||||
fp->ftp_server_port / FTP_PASV_PORT_BLOCK,
|
||||
fp->ftp_server_port % FTP_PASV_PORT_BLOCK);
|
||||
|
||||
pack_len = strlen(*pack_p);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
debug(LOG_DEBUG, "ftp pasv protocol data not supportted in pasv_pack");
|
||||
free(*pack_p);
|
||||
break;
|
||||
}
|
||||
|
||||
return pack_len;
|
||||
}
|
||||
|
||||
// need be free after using
|
||||
static struct ftp_pasv *new_ftp_pasv()
|
||||
{
|
||||
struct ftp_pasv *fp = (struct ftp_pasv *)calloc(1, sizeof(struct ftp_pasv));
|
||||
if (! fp)
|
||||
return NULL;
|
||||
|
||||
memset(fp->ftp_server_ip, 0, IP_LEN);
|
||||
fp->ftp_server_port = -1;
|
||||
fp->code = -1;
|
||||
|
||||
return fp;
|
||||
}
|
||||
|
||||
// can be used to free NULL pointer also
|
||||
static void free_ftp_pasv(struct ftp_pasv *fp)
|
||||
{
|
||||
if (!fp)
|
||||
return;
|
||||
|
||||
SAFE_FREE(fp);
|
||||
fp = NULL;
|
||||
}
|
||||
44
proxy_tcp.c
Normal file
44
proxy_tcp.c
Normal file
@@ -0,0 +1,44 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <errno.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include <event2/bufferevent.h>
|
||||
#include <event2/buffer.h>
|
||||
#include <event2/listener.h>
|
||||
#include <event2/event.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "uthash.h"
|
||||
#include "common.h"
|
||||
#include "proxy.h"
|
||||
|
||||
// read from client-working host port
|
||||
void tcp_proxy_c2s_cb(struct bufferevent *bev, void *ctx)
|
||||
{
|
||||
struct proxy *p = (struct proxy *)ctx;
|
||||
struct bufferevent *partner = p?p->bev:NULL;
|
||||
struct evbuffer *src, *dst;
|
||||
size_t len;
|
||||
src = bufferevent_get_input(bev);
|
||||
len = evbuffer_get_length(src);
|
||||
if (len > 0) {
|
||||
dst = bufferevent_get_output(partner);
|
||||
evbuffer_add_buffer(dst, src);
|
||||
}
|
||||
}
|
||||
|
||||
void tcp_proxy_s2c_cb(struct bufferevent *bev, void *ctx)
|
||||
{
|
||||
struct proxy *p = (struct proxy *)ctx;
|
||||
struct bufferevent *partner = p?p->bev:NULL;
|
||||
struct evbuffer *src, *dst;
|
||||
src = bufferevent_get_input(bev);
|
||||
dst = bufferevent_get_output(partner);
|
||||
evbuffer_add_buffer(dst, src);
|
||||
}
|
||||
9
utils.c
9
utils.c
@@ -20,3 +20,12 @@ void s_sleep(unsigned int s, unsigned int u)
|
||||
timeout.tv_usec = u;
|
||||
select(0, NULL, NULL, NULL, &timeout);
|
||||
}
|
||||
|
||||
// is_valid_ip_address:
|
||||
// return 0:ipaddress unlegal
|
||||
int is_valid_ip_address(const char *ip_address)
|
||||
{
|
||||
struct sockaddr_in sa;
|
||||
int result = inet_pton(AF_INET, ip_address, &(sa.sin_addr));
|
||||
return result;
|
||||
}
|
||||
4
utils.h
4
utils.h
@@ -3,4 +3,8 @@
|
||||
|
||||
void s_sleep(unsigned int s, unsigned int u);
|
||||
|
||||
// is_valid_ip_address:
|
||||
// return 0:ipaddress unlegal
|
||||
int is_valid_ip_address(const char *ip_address);
|
||||
|
||||
#endif //_UTILS_H_
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
* *
|
||||
\********************************************************************/
|
||||
|
||||
/** @file xfrp_client.c
|
||||
/** @file xfrpc.c
|
||||
@brief xfrp client
|
||||
@author Copyright (C) 2016 Dengfeng Liu <liudengfeng@kunteng.org>
|
||||
*/
|
||||
@@ -41,12 +41,12 @@
|
||||
#include "uthash.h"
|
||||
#include "control.h"
|
||||
#include "debug.h"
|
||||
#include "xfrp_client.h"
|
||||
#include "xfrpc.h"
|
||||
#include "crypto.h"
|
||||
#include "msg.h"
|
||||
#include "utils.h"
|
||||
|
||||
void xfrp_client_loop()
|
||||
void xfrpc_loop()
|
||||
{
|
||||
init_main_control();
|
||||
run_control();
|
||||
@@ -19,14 +19,14 @@
|
||||
* *
|
||||
\********************************************************************/
|
||||
|
||||
/** @file xfrp_client.h
|
||||
/** @file xfrpc.h
|
||||
@brief xfrp client header file
|
||||
@author Copyright (C) 2016 Dengfeng Liu <liudengfeng@kunteng.org>
|
||||
*/
|
||||
|
||||
#ifndef _XFRP_CLIENT_H_
|
||||
#define _XFRP_CLIENT_H_
|
||||
#ifndef _XFRPC_H_
|
||||
#define _XFRPC_H_
|
||||
|
||||
void xfrp_client_loop();
|
||||
void xfrpc_loop();
|
||||
|
||||
#endif //_XFRP_CLIENT_H_
|
||||
#endif //_XFRPC_H_
|
||||
Reference in New Issue
Block a user