diff --git a/common.cpp b/common.cpp index e86f3bb..e5fb834 100644 --- a/common.cpp +++ b/common.cpp @@ -16,7 +16,14 @@ raw_mode_t raw_mode=mode_faketcp; unordered_map raw_mode_tostring = {{mode_faketcp, "faketcp"}, {mode_udp, "udp"}, {mode_icmp, "icmp"}}; int socket_buf_size=1024*1024; static int random_number_fd=-1; -char iptables_rule[200]=""; +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() @@ -50,42 +57,160 @@ char * my_ntoa(u32_t ip) } -int add_iptables_rule(char * s) +/* +int add_iptables_rule(const char * s) { - strcpy(iptables_rule,s); - char buf[300]="iptables -I "; - strcat(buf,s); + + iptables_pattern=s; + + string rule="iptables -I INPUT "; + rule+=iptables_pattern; + rule+=" -j DROP"; + char *output; - if(run_command(buf,output)==0) + if(run_command(rule.c_str(),output)==0) { - mylog(log_warn,"auto added iptables rule by: %s\n",buf); + mylog(log_warn,"auto added iptables rule by: %s\n",rule.c_str()); } else { - mylog(log_fatal,"auto added iptables failed by: %s\n",buf); + 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_created=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); + } + } + 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() { - if(iptables_rule[0]!=0) - { - char buf[300]="iptables -D "; - strcat(buf,iptables_rule); - char *output; - if(run_command(buf,output)==0) - { - mylog(log_warn,"iptables rule cleared by: %s \n",buf); - } - else - { - mylog(log_error,"clear iptables failed by: %s\n",buf); - //mylog(log_error,"reason : %s\n",strerror(errno)); - } + 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; } @@ -216,8 +341,19 @@ int set_buf_size(int fd) void myexit(int a) { if(enable_log_color) - printf("%s\n",RESET); - clear_iptables_rule(); + printf("%s\n",RESET); + if(keep_thread_created) + { + 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) @@ -369,13 +505,28 @@ int read_file(const char * file,char * &output) } return 0; } -int run_command(const char * command,char * &output) { +int run_command(string command0,char * &output,int flag) { FILE *in; - mylog(log_debug,"run_command %s\n",command); + + + if((flag&show_log)==0) command0+=" 2>&1 "; + + const char * command=command0.c_str(); + + int level= (flag&show_log)?log_warn:log_debug; + + if(flag&show_command) + { + mylog(log_info,"run_command %s\n",command); + } + else + { + mylog(log_debug,"run_command %s\n",command); + } static char buf[1024*1024+100]; buf[sizeof(buf)-1]=0; if(!(in = popen(command, "r"))){ - mylog(log_error,"command %s popen failed,errno %s\n",command,strerror(errno)); + mylog(level,"command %s popen failed,errno %s\n",command,strerror(errno)); return -1; } @@ -383,7 +534,7 @@ int run_command(const char * command,char * &output) { if(len==1024*1024) { buf[0]=0; - mylog(log_error,"too long,buf not larger enough\n"); + mylog(level,"too long,buf not larger enough\n"); return -2; } else @@ -393,8 +544,8 @@ int run_command(const char * command,char * &output) { int ret; if(( ret=ferror(in) )) { - mylog(log_error,"command %s fread failed,ferror return value %d \n",command,ret); - return -2; + mylog(level,"command %s fread failed,ferror return value %d \n",command,ret); + return -3; } //if(output!=0) output=buf; @@ -404,11 +555,55 @@ int run_command(const char * command,char * &output) { if(ret!=0||ret2!=0) { - mylog(log_error,"commnad %s ,pclose returned %d ,WEXITSTATUS %d,errnor :%s \n",command,ret,ret2,strerror(errno)); - return -3; + mylog(level,"commnad %s ,pclose returned %d ,WEXITSTATUS %d,errnor :%s \n",command,ret,ret2,strerror(errno)); + return -4; } return 0; } +/* +int run_command_no_log(string command0,char * &output) { + FILE *in; + command0+=" 2>&1 "; + const char * command=command0.c_str(); + mylog(log_debug,"run_command_no_log %s\n",command); + static char buf[1024*1024+100]; + buf[sizeof(buf)-1]=0; + if(!(in = popen(command, "r"))){ + mylog(log_debug,"command %s popen failed,errno %s\n",command,strerror(errno)); + return -1; + } + int len =fread(buf, 1024*1024, 1, in); + if(len==1024*1024) + { + buf[0]=0; + mylog(log_debug,"too long,buf not larger enough\n"); + return -2; + } + else + { + buf[len]=0; + } + int ret; + if(( ret=ferror(in) )) + { + mylog(log_debug,"command %s fread failed,ferror return value %d \n",command,ret); + return -3; + } + //if(output!=0) + output=buf; + ret= pclose(in); + + int ret2=WEXITSTATUS(ret); + + if(ret!=0||ret2!=0) + { + mylog(log_debug,"commnad %s ,pclose returned %d ,WEXITSTATUS %d,errnor :%s \n",command,ret,ret2,strerror(errno)); + return -4; + } + + return 0; + +}*/ diff --git a/common.h b/common.h index 8df9937..b99f5c3 100644 --- a/common.h +++ b/common.h @@ -44,7 +44,7 @@ #include #include #include - +#include #include #include @@ -95,7 +95,11 @@ const u32_t client_conn_uplink_timeout=client_conn_timeout+2000; //const uint32_t server_conn_timeout=conv_timeout+60000;//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=4000; + extern int about_to_exit; +extern pthread_t keep_thread; +extern int keep_thread_created; enum raw_mode_t{mode_faketcp=0,mode_udp,mode_icmp,mode_end}; extern raw_mode_t raw_mode; @@ -141,14 +145,25 @@ int char_to_numbers(const char * data,int len,id_t &id1,id_t &id2,id_t &id3); void myexit(int a); -int add_iptables_rule(char *); +int add_iptables_rule(const char *); int clear_iptables_rule(); -int run_command(const char * command,char * &output); +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(); + +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,char * &output); vector string_to_vec(const char * s,const char * sp); vector< vector > string_to_vec2(const char * s); +//extern string iptables_pattern; + #endif /* COMMON_H_ */ diff --git a/main.cpp b/main.cpp index c3aa595..25f83f4 100755 --- a/main.cpp +++ b/main.cpp @@ -32,8 +32,12 @@ int fail_time_counter=0; int epoll_trigger_counter=0; int debug_flag=0; + +int simple_rule=0; +int keep_rule=0; int auto_add_iptables_rule=0; int generate_iptables_rule=0; +int generate_iptables_rule_add=0; int debug_resend=0; int disable_anti_replay=0; @@ -966,6 +970,7 @@ int set_timer_server(int epollfd,int &timer_fd) int get_src_adress(u32_t &ip); int client_on_timer(conn_info_t &conn_info) //for client { + //keep_iptables_rule(); packet_info_t &send_info=conn_info.raw_info.send_info; packet_info_t &recv_info=conn_info.raw_info.recv_info; raw_info_t &raw_info=conn_info.raw_info; @@ -976,6 +981,9 @@ int client_on_timer(conn_info_t &conn_info) //for client mylog(log_trace,"\n",send_info.ts_ack); + + + if(conn_info.state.client_current_state==client_idle) { fail_time_counter++; @@ -1202,6 +1210,7 @@ int client_on_timer(conn_info_t &conn_info) //for client } int server_on_timer_multi(conn_info_t &conn_info,char * ip_port) { + //keep_iptables_rule(); mylog(log_trace,"server timer!\n"); raw_info_t &raw_info=conn_info.raw_info; @@ -2456,8 +2465,11 @@ void process_arg(int argc, char *argv[]) {"disable-anti-replay", no_argument, 0, 1}, {"auto-rule", no_argument, 0, 'a'}, {"gen-rule", no_argument, 0, 'g'}, + {"gen-add", no_argument, 0, 1}, {"debug", no_argument, 0, 1}, {"clear", no_argument, 0, 1}, + {"simple-rule", no_argument, 0, 1}, + {"keep-rule", no_argument, 0, 1}, {"lower-level", required_argument, 0, 1}, {"sock-buf", required_argument, 0, 1}, {"seq-mode", required_argument, 0, 1}, @@ -2585,11 +2597,12 @@ void process_arg(int argc, char *argv[]) { char *output; //int ret =system("iptables-save |grep udp2raw_dWRwMnJhdw|sed -n 's/^-A/iptables -D/p'|sh"); - int ret =run_command("iptables -S|sed -n '/udp2raw_dWRwMnJhdw/p'|sed -n 's/^-A/iptables -D/p'|sh",output); + int ret =run_command("iptables -S|sed -n '/udp2rawDwrW/p'|sed -n 's/^-A/iptables -D/p'|sh",output); + int ret2 =run_command("iptables -S|sed -n '/udp2rawDwrW/p'|sed -n 's/^-N/iptables -X/p'|sh",output); //system("iptables-save |grep udp2raw_dWRwMnJhdw|sed 's/^-A/iptables -D/'|sh"); //system("iptables-save|grep -v udp2raw_dWRwMnJhdw|iptables-restore"); - mylog(log_info,"tried to clear all iptables rule created previously,return value %d\n",ret); + mylog(log_info,"tried to clear all iptables rule created previously,return value %d %d\n",ret,ret2); myexit(-1); } else if(strcmp(long_options[option_index].name,"source-ip")==0) @@ -2662,6 +2675,18 @@ void process_arg(int argc, char *argv[]) { process_lower_level(); } + else if(strcmp(long_options[option_index].name,"simple-rule")==0) + { + simple_rule=1; + } + else if(strcmp(long_options[option_index].name,"keep-rule")==0) + { + keep_rule=1; + } + else if(strcmp(long_options[option_index].name,"gen-add")==0) + { + generate_iptables_rule_add=1; + } else if(strcmp(long_options[option_index].name,"disable-color")==0) { //enable_log_color=0; @@ -2757,86 +2782,141 @@ void process_arg(int argc, char *argv[]) log_bare(log_info,"\n"); } + +void *run_keep(void *none) +{ + + while(1) + { + sleep(5); + keep_iptables_rule(); + /*if(about_to_exit) + break;*/ + } + return NULL; + +} void iptables_rule() { - char rule[200]; + if(auto_add_iptables_rule&&generate_iptables_rule) + { + mylog(log_warn," -g overrides -a\n"); + auto_add_iptables_rule=0; + //myexit(-1); + } + if(generate_iptables_rule_add&&generate_iptables_rule) + { + mylog(log_warn," --gen-add overrides -g\n"); + generate_iptables_rule=0; + //myexit(-1); + } + + if(keep_rule&&auto_add_iptables_rule==0) + { + auto_add_iptables_rule=1; + mylog(log_warn," --keep_rule implys -a\n"); + generate_iptables_rule=0; + //myexit(-1); + } + char tmp_pattern[200]; + string pattern=""; + if(program_mode==client_mode) { if(raw_mode==mode_faketcp) { - sprintf(rule,"INPUT -s %s/32 -p tcp -m tcp --sport %d -j DROP",remote_ip,remote_port); - //mylog(log_warn,"make sure you have run once: iptables -A INPUT -s %s/32 -p tcp -m tcp --sport %d -j DROP\n",remote_address,remote_port); + sprintf(tmp_pattern,"-s %s/32 -p tcp -m tcp --sport %d",remote_ip,remote_port); } if(raw_mode==mode_udp) { - sprintf(rule,"INPUT -s %s/32 -p udp -m udp --sport %d -j DROP",remote_ip,remote_port); - //mylog(log_warn,"make sure you have run once: iptables -A INPUT -s %s/32 -p udp -m udp --sport %d -j DROP\n",remote_address,remote_port); + sprintf(tmp_pattern,"-s %s/32 -p udp -m udp --sport %d",remote_ip,remote_port); } if(raw_mode==mode_icmp) { - sprintf(rule,"INPUT -s %s/32 -p icmp -j DROP",remote_ip); - //mylog(log_warn,"make sure you have run once: iptables -A INPUT -s %s/32 -p icmp -j DROP\n",remote_address); + sprintf(tmp_pattern,"-s %s/32 -p icmp",remote_ip); } + pattern=tmp_pattern; } if(program_mode==server_mode) { if(raw_mode==mode_faketcp) { - sprintf(rule,"INPUT -p tcp -m tcp --dport %d -j DROP",local_port); - //mylog(log_warn,"make sure you have run once: iptables -A INPUT -p tcp -m tcp --dport %d -j DROP\n",local_port); + sprintf(tmp_pattern,"-p tcp -m tcp --dport %d",local_port); } if(raw_mode==mode_udp) { - sprintf(rule,"INPUT -p udp -m udp --dport %d -j DROP",local_port); - //mylog(log_warn,"make sure you have run once: iptables -A INPUT -p udp -m udp --udp %d -j DROP\n",local_port); + sprintf(tmp_pattern,"-p udp -m udp --dport %d",local_port); } if(raw_mode==mode_icmp) { if(local_ip_uint32==0) { - sprintf(rule,"INPUT -p icmp -j DROP"); - //mylog(log_warn,"make sure you have run once: iptables -A INPUT -p icmp -j DROP\n"); + sprintf(tmp_pattern,"-p icmp"); } else { - sprintf(rule,"INPUT -d %s/32 -p icmp -j DROP",local_ip); - //mylog(log_warn,"make sure you have run once: iptables -A INPUT -d %s/32 -p icmp -j DROP\n",local_address); + sprintf(tmp_pattern,"-d %s/32 -p icmp",local_ip); } } + pattern=tmp_pattern; + } +/* + if(!simple_rule) + { + pattern += " -m comment --comment udp2rawDwrW_"; + + char const_id_str[100]; + sprintf(const_id_str, "%x_", const_id); + + pattern += const_id_str; + + time_t timer; + char buffer[26]; + struct tm* tm_info; + + time(&timer); + tm_info = localtime(&timer); + + strftime(buffer, 26, "%Y-%m-%d-%H:%M:%S", tm_info); + + pattern += buffer; + + + }*/ + + if(auto_add_iptables_rule) + { + iptables_rule_init(pattern.c_str(),const_id,keep_rule); + if(keep_rule) + { + if(pthread_create(&keep_thread, NULL, run_keep, 0)) { + + mylog(log_fatal, "Error creating thread\n"); + myexit(-1); + } + keep_thread_created=1; + } } if(generate_iptables_rule) { + string rule="iptables -I "; + rule+=pattern; + rule+=" -j DROP"; + printf("generated iptables rule:\n"); - printf("iptables -I %s\n",rule); - myexit(-1); + printf("%s\n",rule.c_str()); + myexit(0); } - else if(auto_add_iptables_rule) + if(generate_iptables_rule_add) { - strcat(rule," -m comment --comment udp2raw_dWRwMnJhdw_"); - - char const_id_str[100]; - sprintf(const_id_str,"%x_",const_id); - - strcat(rule,const_id_str); - - time_t timer; - char buffer[26]; - struct tm* tm_info; - - time(&timer); - tm_info = localtime(&timer); - - strftime(buffer, 26, "%Y-%m-%d-%H:%M:%S", tm_info); - - strcat(rule,buffer); - add_iptables_rule(rule); - } - else - { - mylog(log_warn,"make sure you have run once: iptables -I %s\n",rule); + iptables_gen_add(pattern.c_str(),const_id); + myexit(0); } + + } + int main(int argc, char *argv[]) { //auto a=string_to_vec("a b c d "); diff --git a/makefile b/makefile index 4c73977..dc65a4a 100755 --- a/makefile +++ b/makefile @@ -5,11 +5,11 @@ cc_bcm2708=/home/wangyu/raspberry/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabi cc_arm=/home/wangyu/Desktop/arm-2014.05/bin/arm-none-linux-gnueabi-g++ FLAGS= -std=c++11 -Wall -Wextra -Wno-unused-variable -Wno-unused-parameter -Wno-missing-field-initializers -SOURCES=main.cpp lib/aes.c lib/md5.c encrypt.cpp log.cpp network.cpp common.cpp +SOURCES=main.cpp lib/aes.c lib/md5.c encrypt.cpp log.cpp network.cpp common.cpp -lrt -lpthread SOURCES_AES_ACC=$(filter-out lib/aes.c,$(SOURCES)) $(wildcard lib/aes_acc/aes*.c) NAME=udp2raw -TAR=${NAME}_binaries.tar.gz ${NAME}_amd64 ${NAME}_x86 ${NAME}_x86_asm_aes ${NAME}_ar71xx ${NAME}_bcm2708 ${NAME}_arm ${NAME}_amd64_hw_aes ${NAME}_arm_asm_aes +TAR=${NAME}_binaries.tar.gz ${NAME}_amd64 ${NAME}_x86 ${NAME}_x86_asm_aes ${NAME}_ar71xx ${NAME}_bcm2708 ${NAME}_arm ${NAME}_amd64_hw_aes ${NAME}_arm_asm_aes ${NAME}_ar71xx_asm_aes all: rm -f ${NAME} @@ -52,10 +52,10 @@ cross2: cross3: ${cc_cross} -o ${NAME}_cross -I. ${SOURCES} ${FLAGS} -lrt -static -O3 -release: amd64 x86 ar71xx bcm2708 arm amd64_hw_aes arm_asm_aes x86_asm_aes +release: amd64 x86 ar71xx bcm2708 arm amd64_hw_aes arm_asm_aes x86_asm_aes ar71xx_asm_aes tar -zcvf ${TAR} clean: rm -f ${TAR} - rm -f udp2raw udp2raw_cross + rm -f udp2raw udp2raw_cross udp2raw_cmake