This commit is contained in:
wangyu- 2017-09-24 03:14:08 -05:00
parent f096a510b5
commit fc05e7f080
8 changed files with 294 additions and 288 deletions

@ -7,26 +7,10 @@
#include "common.h"
#include "log.h"
#include "misc.h"
int about_to_exit=0;
raw_mode_t raw_mode=mode_faketcp;
unordered_map<int, const char*> raw_mode_tostring = {{mode_faketcp, "faketcp"}, {mode_udp, "udp"}, {mode_icmp, "icmp"}};
int socket_buf_size=1024*1024;
int force_socket_buf=0;
static int random_number_fd=-1;
string iptables_pattern="";
int iptables_rule_added=0;
int iptables_rule_keeped=0;
int iptables_rule_keep_index=0;
//int iptables_rule_no_clear=0;
program_mode_t program_mode=unset_mode;//0 unset; 1client 2server
u64_t get_current_time()
{
@ -58,167 +42,6 @@ char * my_ntoa(u32_t ip)
return inet_ntoa(a);
}
/*
int add_iptables_rule(const char * s)
{
iptables_pattern=s;
string rule="iptables -I INPUT ";
rule+=iptables_pattern;
rule+=" -j DROP";
char *output;
if(run_command(rule.c_str(),output)==0)
{
mylog(log_warn,"auto added iptables rule by: %s\n",rule.c_str());
}
else
{
mylog(log_fatal,"auto added iptables failed by: %s\n",rule.c_str());
//mylog(log_fatal,"reason : %s\n",strerror(errno));
myexit(-1);
}
iptables_rule_added=1;
return 0;
}*/
string chain[2];
string rule_keep[2];
string rule_keep_add[2];
string rule_keep_del[2];
u64_t keep_rule_last_time=0;
pthread_t keep_thread;
int keep_thread_running=0;
int iptables_gen_add(const char * s,u32_t const_id)
{
string dummy="";
iptables_pattern=s;
chain[0] =dummy+ "udp2rawDwrW_C";
rule_keep[0]=dummy+ iptables_pattern+" -j " +chain[0];
rule_keep_add[0]=dummy+"iptables -I INPUT "+rule_keep[0];
char *output;
run_command(dummy+"iptables -N "+chain[0],output,show_none);
run_command(dummy+"iptables -F "+chain[0],output);
run_command(dummy+"iptables -I "+chain[0] + " -j DROP",output);
rule_keep_del[0]=dummy+"iptables -D INPUT "+rule_keep[0];
run_command(rule_keep_del[0],output,show_none);
run_command(rule_keep_del[0],output,show_none);
if(run_command(rule_keep_add[0],output)!=0)
{
mylog(log_fatal,"auto added iptables failed by: %s\n",rule_keep_add[0].c_str());
myexit(-1);
}
return 0;
}
int iptables_rule_init(const char * s,u32_t const_id,int keep)
{
iptables_pattern=s;
iptables_rule_added=1;
iptables_rule_keeped=keep;
string dummy="";
char const_id_str[100];
sprintf(const_id_str, "%x", const_id);
chain[0] =dummy+ "udp2rawDwrW_"+const_id_str+"_C0";
chain[1] =dummy+ "udp2rawDwrW_"+const_id_str+"_C1";
rule_keep[0]=dummy+ iptables_pattern+" -j " +chain[0];
rule_keep[1]=dummy+ iptables_pattern+" -j " +chain[1];
rule_keep_add[0]=dummy+"iptables -I INPUT "+rule_keep[0];
rule_keep_add[1]=dummy+"iptables -I INPUT "+rule_keep[1];
rule_keep_del[0]=dummy+"iptables -D INPUT "+rule_keep[0];
rule_keep_del[1]=dummy+"iptables -D INPUT "+rule_keep[1];
keep_rule_last_time=get_current_time();
char *output;
for(int i=0;i<=iptables_rule_keeped;i++)
{
run_command(dummy+"iptables -N "+chain[i],output);
run_command(dummy+"iptables -F "+chain[i],output);
run_command(dummy+"iptables -I "+chain[i] + " -j DROP",output);
if(run_command(rule_keep_add[i],output)!=0)
{
mylog(log_fatal,"auto added iptables failed by: %s\n",rule_keep_add[i].c_str());
myexit(-1);
}
}
mylog(log_warn,"auto added iptables rules\n");
return 0;
}
int keep_iptables_rule() //magic to work on a machine without grep/iptables --check/-m commment
{
/*
if(iptables_rule_keeped==0) return 0;
uint64_t tmp_current_time=get_current_time();
if(tmp_current_time-keep_rule_last_time<=iptables_rule_keep_interval)
{
return 0;
}
else
{
keep_rule_last_time=tmp_current_time;
}*/
mylog(log_debug,"keep_iptables_rule begin %llu\n",get_current_time());
iptables_rule_keep_index+=1;
iptables_rule_keep_index%=2;
string dummy="";
char *output;
int i=iptables_rule_keep_index;
run_command(dummy + "iptables -N " + chain[i], output,show_none);
if (run_command(dummy + "iptables -F " + chain[i], output,show_none) != 0)
mylog(log_warn, "iptables -F failed %d\n",i);
if (run_command(dummy + "iptables -I " + chain[i] + " -j DROP",output,show_none) != 0)
mylog(log_warn, "iptables -I failed %d\n",i);
if (run_command(rule_keep_del[i], output,show_none) != 0)
mylog(log_warn, "rule_keep_del failed %d\n",i);
run_command(rule_keep_del[i], output,show_none); //do it twice,incase it fails for unknown random reason
if(run_command(rule_keep_add[i], output,show_log)!=0)
mylog(log_warn, "rule_keep_del failed %d\n",i);
mylog(log_debug,"keep_iptables_rule end %llu\n",get_current_time());
return 0;
}
int clear_iptables_rule()
{
char *output;
string dummy="";
if(!iptables_rule_added) return 0;
for(int i=0;i<=iptables_rule_keeped;i++ )
{
run_command(rule_keep_del[i],output);
run_command(dummy+"iptables -F "+chain[i],output);
run_command(dummy+"iptables -X "+chain[i],output);
}
return 0;
}
void init_random_number_fd()
{
@ -326,8 +149,7 @@ unsigned short csum(const unsigned short *ptr,int nbytes) {//works both for big
return(answer);
}
int set_buf_size(int fd)
int set_buf_size(int fd,int socket_buf_size,int force_socket_buf)
{
if(force_socket_buf)
{
@ -358,30 +180,6 @@ int set_buf_size(int fd)
return 0;
}
void myexit(int a)
{
if(enable_log_color)
printf("%s\n",RESET);
if(keep_thread_running)
{
if(pthread_cancel(keep_thread))
{
mylog(log_warn,"pthread_cancel failed\n");
}
else
{
mylog(log_info,"pthread_cancel success\n");
}
}
clear_iptables_rule();
exit(a);
}
void signal_handler(int sig)
{
about_to_exit=1;
// myexit(0);
}
int numbers_to_char(id_t id1,id_t id2,id_t id3,char * &data,int &len)
{
static char buf[buf_len];
@ -399,7 +197,6 @@ int numbers_to_char(id_t id1,id_t id2,id_t id3,char * &data,int &len)
return 0;
}
int char_to_numbers(const char * data,int len,id_t &id1,id_t &id2,id_t &id3)
{
if(len<int(sizeof(id_t)*3)) return -1;
@ -502,6 +299,26 @@ bool larger_than_u16(uint16_t a,uint16_t b)
}
}
}
void myexit(int a)
{
if(enable_log_color)
printf("%s\n",RESET);
if(keep_thread_running)
{
if(pthread_cancel(keep_thread))
{
mylog(log_warn,"pthread_cancel failed\n");
}
else
{
mylog(log_info,"pthread_cancel success\n");
}
}
clear_iptables_rule();
exit(a);
}
vector<string> string_to_vec(const char * s,const char * sp) {
vector<string> res;
string str=s;

@ -61,66 +61,6 @@ typedef long long i64_t;
typedef unsigned int u32_t;
typedef int i32_t;
const int max_data_len=1600;
const int buf_len=max_data_len+400;
const u32_t max_handshake_conn_num=10000;
const u32_t max_ready_conn_num=1000;
const u32_t anti_replay_window_size=4000;
const int max_conv_num=10000;
const u32_t client_handshake_timeout=5000;//unit ms
const u32_t client_retry_interval=1000;//ms
const u32_t server_handshake_timeout=client_handshake_timeout+5000;// this should be longer than clients. client retry initially ,server retry passtively
const int conv_clear_ratio=10; //conv grabage collecter check 1/10 of all conv one time
const int conn_clear_ratio=30;
const int conv_clear_min=1;
const int conn_clear_min=1;
const u32_t conv_clear_interval=3000;//ms
const u32_t conn_clear_interval=3000;//ms
const i32_t max_fail_time=0;//disable
const u32_t heartbeat_interval=1000;//ms
const u32_t timer_interval=400;//ms. this should be smaller than heartbeat_interval and retry interval;
const uint32_t conv_timeout=120000; //ms. 120 second
//const u32_t conv_timeout=30000; //for test
const u32_t client_conn_timeout=15000;//ms.
const u32_t client_conn_uplink_timeout=client_conn_timeout+2000;//ms
const uint32_t server_conn_timeout=conv_timeout+60000;//ms. this should be 60s+ longer than conv_timeout,so that conv_manager can destruct convs gradually,to avoid latency glicth
//const u32_t server_conn_timeout=conv_timeout+10000;//for test
const u32_t iptables_rule_keep_interval=15;//unit: second;
extern int about_to_exit;
extern pthread_t keep_thread;
extern int keep_thread_running;
enum raw_mode_t{mode_faketcp=0,mode_udp,mode_icmp,mode_end};
extern raw_mode_t raw_mode;
enum program_mode_t {unset_mode=0,client_mode,server_mode};
extern program_mode_t program_mode;
extern unordered_map<int, const char*> raw_mode_tostring ;
extern int socket_buf_size;
extern int force_socket_buf;
enum server_current_state_t {server_idle=0,server_handshake1,server_ready}; //server state machine
enum client_current_state_t {client_idle=0,client_tcp_handshake,client_handshake1,client_handshake2,client_ready};//client state machine
union current_state_t
{
server_current_state_t server_current_state;
client_current_state_t client_current_state;
};
typedef u32_t id_t;
typedef u64_t iv_t;
@ -129,6 +69,9 @@ typedef u64_t padding_t;
typedef u64_t anti_replay_seq_t;
const int max_data_len=1600;
const int buf_len=max_data_len+400;
u64_t get_current_time();
u64_t pack_u64(u32_t a,u32_t b);
@ -138,7 +81,6 @@ u32_t get_u64_l(u64_t a);
char * my_ntoa(u32_t ip);
void myexit(int a);
void init_random_number_fd();
u64_t get_true_random_number_64();
u32_t get_true_random_number();
@ -148,28 +90,20 @@ u64_t hton64(u64_t a);
bool larger_than_u16(uint16_t a,uint16_t b);
bool larger_than_u32(u32_t a,u32_t b);
void setnonblocking(int sock);
int set_buf_size(int fd);
unsigned short csum(const unsigned short *ptr,int nbytes);
void signal_handler(int sig);
int numbers_to_char(id_t id1,id_t id2,id_t id3,char * &data,int &len);
int char_to_numbers(const char * data,int len,id_t &id1,id_t &id2,id_t &id3);
int set_buf_size(int fd,int socket_buf_size,int force_socket_buf);
void myexit(int a);
int add_iptables_rule(const char *);
unsigned short csum(const unsigned short *ptr,int nbytes);
int clear_iptables_rule();
int iptables_gen_add(const char * s,u32_t const_id);
int iptables_rule_init(const char * s,u32_t const_id,int keep);
int keep_iptables_rule();
int numbers_to_char(id_t id1,id_t id2,id_t id3,char * &data,int &len);
int char_to_numbers(const char * data,int len,id_t &id1,id_t &id2,id_t &id3);
const int show_none=0;
const int show_command=0x1;
const int show_log=0x2;
const int show_all=show_command|show_log;
int run_command(string command,char * &output,int flag=show_all);
//int run_command_no_log(string command,char * &output);
int read_file(const char * file,string &output);

@ -1,11 +1,11 @@
#include "log.h"
#include "misc.h"
int log_level=log_info;
int enable_log_position=0;
int enable_log_color=1;
void log0(const char * file,const char * function,int line,int level,const char* str, ...) {
if(level>log_level) return ;

1
log.h

@ -5,6 +5,7 @@
#include "common.h"
using namespace std;

@ -8,6 +8,7 @@
int mtu_warn=1375;//if a packet larger than mtu warn is receviced,there will be a warning
int server_on_raw_recv_pre_ready(conn_info_t &conn_info,char * ip_port,u32_t tmp_oppsite_const_id);
int server_on_raw_recv_ready(conn_info_t &conn_info,char * ip_port,char type,char *data,int data_len);
int server_on_raw_recv_handshake1(conn_info_t &conn_info,char * ip_port,char * data, int data_len);
@ -809,7 +810,7 @@ int server_on_raw_recv_ready(conn_info_t &conn_info,char * ip_port,char type,cha
return -1;
}
setnonblocking(new_udp_fd);
set_buf_size(new_udp_fd);
set_buf_size(new_udp_fd,socket_buf_size,force_socket_buf);
mylog(log_debug, "[%s]created new udp_fd %d\n",ip_port, new_udp_fd);
int ret = connect(new_udp_fd, (struct sockaddr *) &remote_addr_in,
@ -1090,7 +1091,7 @@ int client_event_loop()
//g_packet_info.src_port=source_port;
udp_fd=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
set_buf_size(udp_fd);
set_buf_size(udp_fd,socket_buf_size,force_socket_buf);
int yes = 1;
//setsockopt(udp_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));

184
misc.cpp

@ -18,11 +18,8 @@ int local_port = -1, remote_port=-1,source_port=0;//similiar to local_ip remote
int force_source_ip=0; //if --source-ip is enabled
id_t const_id=0;//an id used for connection recovery,its generated randomly,it never change since its generated
int udp_fd=-1; //for client only. client use this fd to listen and handle udp connection
int bind_fd=-1; //bind only,never send or recv. its just a dummy fd for bind,so that other program wont occupy the same port
int epollfd=-1; //fd for epoll
@ -42,7 +39,21 @@ int debug_resend=0; // debug only
char key_string[1000]= "secret key";// -k option
string iptables_pattern="";
int iptables_rule_added=0;
int iptables_rule_keeped=0;
int iptables_rule_keep_index=0;
program_mode_t program_mode=unset_mode;//0 unset; 1client 2server
raw_mode_t raw_mode=mode_faketcp;
unordered_map<int, const char*> raw_mode_tostring = {{mode_faketcp, "faketcp"}, {mode_udp, "udp"}, {mode_icmp, "icmp"}};
int about_to_exit=0;
int socket_buf_size=1024*1024;
int force_socket_buf=0;
//char lower_level_arg[1000];
int process_lower_level_arg()//handle --lower-level option
@ -974,3 +985,170 @@ int handle_lower_level(raw_info_t &raw_info)//fill lower_level info,when --lower
/*
int add_iptables_rule(const char * s)
{
iptables_pattern=s;
string rule="iptables -I INPUT ";
rule+=iptables_pattern;
rule+=" -j DROP";
char *output;
if(run_command(rule.c_str(),output)==0)
{
mylog(log_warn,"auto added iptables rule by: %s\n",rule.c_str());
}
else
{
mylog(log_fatal,"auto added iptables failed by: %s\n",rule.c_str());
//mylog(log_fatal,"reason : %s\n",strerror(errno));
myexit(-1);
}
iptables_rule_added=1;
return 0;
}*/
string chain[2];
string rule_keep[2];
string rule_keep_add[2];
string rule_keep_del[2];
u64_t keep_rule_last_time=0;
pthread_t keep_thread;
int keep_thread_running=0;
int iptables_gen_add(const char * s,u32_t const_id)
{
string dummy="";
iptables_pattern=s;
chain[0] =dummy+ "udp2rawDwrW_C";
rule_keep[0]=dummy+ iptables_pattern+" -j " +chain[0];
rule_keep_add[0]=dummy+"iptables -I INPUT "+rule_keep[0];
char *output;
run_command(dummy+"iptables -N "+chain[0],output,show_none);
run_command(dummy+"iptables -F "+chain[0],output);
run_command(dummy+"iptables -I "+chain[0] + " -j DROP",output);
rule_keep_del[0]=dummy+"iptables -D INPUT "+rule_keep[0];
run_command(rule_keep_del[0],output,show_none);
run_command(rule_keep_del[0],output,show_none);
if(run_command(rule_keep_add[0],output)!=0)
{
mylog(log_fatal,"auto added iptables failed by: %s\n",rule_keep_add[0].c_str());
myexit(-1);
}
return 0;
}
int iptables_rule_init(const char * s,u32_t const_id,int keep)
{
iptables_pattern=s;
iptables_rule_added=1;
iptables_rule_keeped=keep;
string dummy="";
char const_id_str[100];
sprintf(const_id_str, "%x", const_id);
chain[0] =dummy+ "udp2rawDwrW_"+const_id_str+"_C0";
chain[1] =dummy+ "udp2rawDwrW_"+const_id_str+"_C1";
rule_keep[0]=dummy+ iptables_pattern+" -j " +chain[0];
rule_keep[1]=dummy+ iptables_pattern+" -j " +chain[1];
rule_keep_add[0]=dummy+"iptables -I INPUT "+rule_keep[0];
rule_keep_add[1]=dummy+"iptables -I INPUT "+rule_keep[1];
rule_keep_del[0]=dummy+"iptables -D INPUT "+rule_keep[0];
rule_keep_del[1]=dummy+"iptables -D INPUT "+rule_keep[1];
keep_rule_last_time=get_current_time();
char *output;
for(int i=0;i<=iptables_rule_keeped;i++)
{
run_command(dummy+"iptables -N "+chain[i],output);
run_command(dummy+"iptables -F "+chain[i],output);
run_command(dummy+"iptables -I "+chain[i] + " -j DROP",output);
if(run_command(rule_keep_add[i],output)!=0)
{
mylog(log_fatal,"auto added iptables failed by: %s\n",rule_keep_add[i].c_str());
myexit(-1);
}
}
mylog(log_warn,"auto added iptables rules\n");
return 0;
}
int keep_iptables_rule() //magic to work on a machine without grep/iptables --check/-m commment
{
/*
if(iptables_rule_keeped==0) return 0;
uint64_t tmp_current_time=get_current_time();
if(tmp_current_time-keep_rule_last_time<=iptables_rule_keep_interval)
{
return 0;
}
else
{
keep_rule_last_time=tmp_current_time;
}*/
mylog(log_debug,"keep_iptables_rule begin %llu\n",get_current_time());
iptables_rule_keep_index+=1;
iptables_rule_keep_index%=2;
string dummy="";
char *output;
int i=iptables_rule_keep_index;
run_command(dummy + "iptables -N " + chain[i], output,show_none);
if (run_command(dummy + "iptables -F " + chain[i], output,show_none) != 0)
mylog(log_warn, "iptables -F failed %d\n",i);
if (run_command(dummy + "iptables -I " + chain[i] + " -j DROP",output,show_none) != 0)
mylog(log_warn, "iptables -I failed %d\n",i);
if (run_command(rule_keep_del[i], output,show_none) != 0)
mylog(log_warn, "rule_keep_del failed %d\n",i);
run_command(rule_keep_del[i], output,show_none); //do it twice,incase it fails for unknown random reason
if(run_command(rule_keep_add[i], output,show_log)!=0)
mylog(log_warn, "rule_keep_del failed %d\n",i);
mylog(log_debug,"keep_iptables_rule end %llu\n",get_current_time());
return 0;
}
int clear_iptables_rule()
{
char *output;
string dummy="";
if(!iptables_rule_added) return 0;
for(int i=0;i<=iptables_rule_keeped;i++ )
{
run_command(rule_keep_del[i],output);
run_command(dummy+"iptables -F "+chain[i],output);
run_command(dummy+"iptables -X "+chain[i],output);
}
return 0;
}
void signal_handler(int sig)
{
about_to_exit=1;
// myexit(0);
}

80
misc.h

@ -13,17 +13,64 @@
#include "log.h"
#include "network.h"
const u32_t max_handshake_conn_num=10000;
const u32_t max_ready_conn_num=1000;
const u32_t anti_replay_window_size=4000;
const int max_conv_num=10000;
const u32_t client_handshake_timeout=5000;//unit ms
const u32_t client_retry_interval=1000;//ms
const u32_t server_handshake_timeout=client_handshake_timeout+5000;// this should be longer than clients. client retry initially ,server retry passtively
const int conv_clear_ratio=10; //conv grabage collecter check 1/10 of all conv one time
const int conn_clear_ratio=30;
const int conv_clear_min=1;
const int conn_clear_min=1;
const u32_t conv_clear_interval=3000;//ms
const u32_t conn_clear_interval=3000;//ms
const i32_t max_fail_time=0;//disable
const u32_t heartbeat_interval=1000;//ms
const u32_t timer_interval=400;//ms. this should be smaller than heartbeat_interval and retry interval;
const uint32_t conv_timeout=120000; //ms. 120 second
//const u32_t conv_timeout=30000; //for test
const u32_t client_conn_timeout=15000;//ms.
const u32_t client_conn_uplink_timeout=client_conn_timeout+2000;//ms
const uint32_t server_conn_timeout=conv_timeout+60000;//ms. this should be 60s+ longer than conv_timeout,so that conv_manager can destruct convs gradually,to avoid latency glicth
//const u32_t server_conn_timeout=conv_timeout+10000;//for test
const u32_t iptables_rule_keep_interval=15;//unit: second;
enum server_current_state_t {server_idle=0,server_handshake1,server_ready}; //server state machine
enum client_current_state_t {client_idle=0,client_tcp_handshake,client_handshake1,client_handshake2,client_ready};//client state machine
enum raw_mode_t{mode_faketcp=0,mode_udp,mode_icmp,mode_end};
enum program_mode_t {unset_mode=0,client_mode,server_mode};
union current_state_t
{
server_current_state_t server_current_state;
client_current_state_t client_current_state;
};
extern char local_ip[100], remote_ip[100],source_ip[100];//local_ip is for -l option,remote_ip for -r option,source for --source-ip
extern u32_t local_ip_uint32,remote_ip_uint32,source_ip_uint32;//convert from last line.
extern int local_port , remote_port,source_port;//similiar to local_ip remote_ip,buf for port.source_port=0 indicates --source-port is not enabled
extern int force_source_ip; //if --source-ip is enabled
extern id_t const_id;//an id used for connection recovery,its generated randomly,it never change since its generated
extern int udp_fd; //for client only. client use this fd to listen and handle udp connection
extern int bind_fd; //bind only,never send or recv. its just a dummy fd for bind,so that other program wont occupy the same port
extern int epollfd; //fd for epoll
@ -43,6 +90,21 @@ extern int debug_resend; // debug only
extern char key_string[1000];// -k option
extern raw_mode_t raw_mode;
extern program_mode_t program_mode;
extern unordered_map<int, const char*> raw_mode_tostring ;
extern int about_to_exit;
extern int socket_buf_size;
extern int force_socket_buf;
extern pthread_t keep_thread;
extern int keep_thread_running;
int process_lower_level_arg();
void print_help();
void iptables_rule();
@ -52,4 +114,16 @@ int set_timer(int epollfd,int &timer_fd);
int set_timer_server(int epollfd,int &timer_fd);
int handle_lower_level(raw_info_t &raw_info);
int add_iptables_rule(const char *);
int clear_iptables_rule();
int iptables_gen_add(const char * s,u32_t const_id);
int iptables_rule_init(const char * s,u32_t const_id,int keep);
int keep_iptables_rule();
void signal_handler(int sig);
#endif /* MISC_H_ */

@ -7,6 +7,7 @@
#include "common.h"
#include "network.h"
#include "log.h"
#include "misc.h"
int raw_recv_fd=-1;
int raw_send_fd=-1;