From 0e77b0d5ab8f6bfa22fc0b0dc5bbbb4e5e78db5e Mon Sep 17 00:00:00 2001 From: wangyu- Date: Sat, 23 Sep 2017 02:40:23 -0500 Subject: [PATCH] refactor --- common.h | 9 + connection.cpp | 457 ++++++++++++++++++++++++++++++++++++++++++ connection.h | 145 ++++++++++++++ main.cpp | 527 +------------------------------------------------ makefile | 2 +- 5 files changed, 615 insertions(+), 525 deletions(-) create mode 100644 connection.cpp create mode 100644 connection.h diff --git a/common.h b/common.h index e7ddfec..314caa8 100644 --- a/common.h +++ b/common.h @@ -109,6 +109,15 @@ extern unordered_map 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; diff --git a/connection.cpp b/connection.cpp new file mode 100644 index 0000000..8870288 --- /dev/null +++ b/connection.cpp @@ -0,0 +1,457 @@ +/* + * connection.cpp + * + * Created on: Sep 23, 2017 + * Author: root + */ + +#include "connection.h" + + + +int disable_anti_replay=0;//if anti_replay windows is diabled + +const int disable_conv_clear=0;//a udp connection in the multiplexer is called conversation in this program,conv for short. + +const int disable_conn_clear=0;//a raw connection is called conn. + + + anti_replay_seq_t anti_replay_t::get_new_seq_for_send() + { + return anti_replay_seq++; + } + anti_replay_t::anti_replay_t() + { + max_packet_received=0; + anti_replay_seq=get_true_random_number_64()/10;//random first seq + //memset(window,0,sizeof(window)); //not necessary + } + void anti_replay_t::re_init() + { + max_packet_received=0; + //memset(window,0,sizeof(window)); + } + + int anti_replay_t::is_vaild(u64_t seq) + { + if(disable_anti_replay) return 1; + //if(disabled) return 0; + + if(seq==max_packet_received) return 0; + else if(seq>max_packet_received) + { + if(seq-max_packet_received>=anti_replay_window_size) + { + memset(window,0,sizeof(window)); + window[seq%anti_replay_window_size]=1; + } + else + { + for (u64_t i=max_packet_received+1;i=anti_replay_window_size) return 0; + else + { + if (window[seq%anti_replay_window_size]==1) return 0; + else + { + window[seq%anti_replay_window_size]=1; + return 1; + } + } + } + + + return 0; //for complier check + } + + +void server_clear_function(u64_t u64); + +conv_manager_t::conv_manager_t() + { + clear_it=conv_last_active_time.begin(); + long long last_clear_time=0; + //clear_function=0; + } +conv_manager_t::~conv_manager_t() + { + clear(); + } + int conv_manager_t::get_size() + { + return conv_to_u64.size(); + } + void conv_manager_t::reserve() + { + u64_to_conv.reserve(10007); + conv_to_u64.reserve(10007); + conv_last_active_time.reserve(10007); + } + void conv_manager_t::clear() + { + if(disable_conv_clear) return ; + + if(program_mode==server_mode) + { + for(it=conv_to_u64.begin();it!=conv_to_u64.end();it++) + { + //int fd=int((it->second<<32u)>>32u); + server_clear_function( it->second); + } + } + u64_to_conv.clear(); + conv_to_u64.clear(); + conv_last_active_time.clear(); + + clear_it=conv_last_active_time.begin(); + + } + u32_t conv_manager_t::get_new_conv() + { + u32_t conv=get_true_random_number_nz(); + while(conv_to_u64.find(conv)!=conv_to_u64.end()) + { + conv=get_true_random_number_nz(); + } + return conv; + } + int conv_manager_t::is_conv_used(u32_t conv) + { + return conv_to_u64.find(conv)!=conv_to_u64.end(); + } + int conv_manager_t::is_u64_used(u64_t u64) + { + return u64_to_conv.find(u64)!=u64_to_conv.end(); + } + u32_t conv_manager_t::find_conv_by_u64(u64_t u64) + { + return u64_to_conv[u64]; + } + u64_t conv_manager_t::find_u64_by_conv(u32_t conv) + { + return conv_to_u64[conv]; + } + int conv_manager_t::update_active_time(u32_t conv) + { + return conv_last_active_time[conv]=get_current_time(); + } + int conv_manager_t::insert_conv(u32_t conv,u64_t u64) + { + u64_to_conv[u64]=conv; + conv_to_u64[conv]=u64; + conv_last_active_time[conv]=get_current_time(); + return 0; + } + int conv_manager_t::erase_conv(u32_t conv) + { + if(disable_conv_clear) return 0; + u64_t u64=conv_to_u64[conv]; + if(program_mode==server_mode) + { + server_clear_function(u64); + } + conv_to_u64.erase(conv); + u64_to_conv.erase(u64); + conv_last_active_time.erase(conv); + return 0; + } + int conv_manager_t::clear_inactive(char * ip_port) + { + if(get_current_time()-last_clear_time>conv_clear_interval) + { + last_clear_time=get_current_time(); + return clear_inactive0(ip_port); + } + return 0; + } + int conv_manager_t::clear_inactive0(char * ip_port) + { + if(disable_conv_clear) return 0; + + + //map::iterator it; + int cnt=0; + it=clear_it; + int size=conv_last_active_time.size(); + int num_to_clean=size/conv_clear_ratio+conv_clear_min; //clear 1/10 each time,to avoid latency glitch + + num_to_clean=min(num_to_clean,size); + + u64_t current_time=get_current_time(); + for(;;) + { + if(cnt>=num_to_clean) break; + if(conv_last_active_time.begin()==conv_last_active_time.end()) break; + + if(it==conv_last_active_time.end()) + { + it=conv_last_active_time.begin(); + } + + if( current_time -it->second >conv_timeout ) + { + //mylog(log_info,"inactive conv %u cleared \n",it->first); + old_it=it; + it++; + u32_t conv= old_it->first; + erase_conv(old_it->first); + if(ip_port==0) + { + mylog(log_info,"conv %x cleared\n",conv); + } + else + { + mylog(log_info,"[%s]conv %x cleared\n",ip_port,conv); + } + } + else + { + it++; + } + cnt++; + } + return 0; + } + + + void conn_info_t::recover(const conn_info_t &conn_info) + { + raw_info=conn_info.raw_info; + last_state_time=conn_info.last_state_time; + last_hb_recv_time=conn_info.last_hb_recv_time; + last_hb_sent_time=conn_info.last_hb_sent_time; + my_id=conn_info.my_id; + oppsite_id=conn_info.oppsite_id; + blob->anti_replay.re_init(); + + my_roller=0;//no need to set,but for easier debug,set it to zero + oppsite_roller=0;//same as above + last_oppsite_roller_time=0; + } + + void conn_info_t::re_init() + { + //send_packet_info.protocol=g_packet_info_send.protocol; + if(program_mode==server_mode) + state.server_current_state=server_idle; + else + state.client_current_state=client_idle; + last_state_time=0; + oppsite_const_id=0; + + timer_fd=0; + + my_roller=0; + oppsite_roller=0; + last_oppsite_roller_time=0; + } + conn_info_t::conn_info_t() + { + blob=0; + re_init(); + } + void conn_info_t::prepare() + { + blob=new blob_t; + + } + conn_info_t::conn_info_t(const conn_info_t&b) + { + //mylog(log_error,"called!!!!!!!!!!!!!\n"); + *this=b; + if(blob!=0) + { + blob=new blob_t(*b.blob); + } + } + conn_info_t& conn_info_t::operator=(const conn_info_t& b) + { + mylog(log_fatal,"not allowed\n"); + myexit(-1); + return *this; + } + conn_info_t::~conn_info_t() + { + if(program_mode==server_mode) + { + if(state.server_current_state==server_ready) + { + assert(blob!=0); + assert(oppsite_const_id!=0); + //assert(conn_manager.const_id_mp.find(oppsite_const_id)!=conn_manager.const_id_mp.end()); // conn_manager 's deconstuction function erases it + } + else + { + assert(blob==0); + assert(oppsite_const_id==0); + } + } + //if(oppsite_const_id!=0) //do this at conn_manager 's deconstuction function + //conn_manager.const_id_mp.erase(oppsite_const_id); + if(blob!=0) + delete blob; + + //send_packet_info.protocol=g_packet_info_send.protocol; + } + + + conn_manager_t::conn_manager_t() + { + ready_num=0; + mp.reserve(10007); + clear_it=mp.begin(); + timer_fd_mp.reserve(10007); + const_id_mp.reserve(10007); + udp_fd_mp.reserve(100007); + last_clear_time=0; + //current_ready_ip=0; + // current_ready_port=0; + } + int conn_manager_t::exist(u32_t ip,uint16_t port) + { + u64_t u64=0; + u64=ip; + u64<<=32u; + u64|=port; + if(mp.find(u64)!=mp.end()) + { + return 1; + } + return 0; + } + /* + int insert(uint32_t ip,uint16_t port) + { + uint64_t u64=0; + u64=ip; + u64<<=32u; + u64|=port; + mp[u64]; + return 0; + }*/ + conn_info_t *& conn_manager_t::find_insert_p(u32_t ip,uint16_t port) //be aware,the adress may change after rehash + { + u64_t u64=0; + u64=ip; + u64<<=32u; + u64|=port; + unordered_map::iterator it=mp.find(u64); + if(it==mp.end()) + { + mp[u64]=new conn_info_t; + } + return mp[u64]; + } + conn_info_t & conn_manager_t::find_insert(u32_t ip,uint16_t port) //be aware,the adress may change after rehash + { + u64_t u64=0; + u64=ip; + u64<<=32u; + u64|=port; + unordered_map::iterator it=mp.find(u64); + if(it==mp.end()) + { + mp[u64]=new conn_info_t; + } + return *mp[u64]; + } + int conn_manager_t::erase(unordered_map::iterator erase_it) + { + if(erase_it->second->state.server_current_state==server_ready) + { + ready_num--; + assert(i32_t(ready_num)!=-1); + assert(erase_it->second!=0); + assert(erase_it->second->timer_fd !=0); + assert(erase_it->second->oppsite_const_id!=0); + assert(const_id_mp.find(erase_it->second->oppsite_const_id)!=const_id_mp.end()); + assert(timer_fd_mp.find(erase_it->second->timer_fd)!=timer_fd_mp.end()); + + const_id_mp.erase(erase_it->second->oppsite_const_id); + timer_fd_mp.erase(erase_it->second->timer_fd); + close(erase_it->second->timer_fd);// close will auto delte it from epoll + delete(erase_it->second); + mp.erase(erase_it->first); + } + else + { + assert(erase_it->second->blob==0); + assert(erase_it->second->timer_fd ==0); + assert(erase_it->second->oppsite_const_id==0); + delete(erase_it->second); + mp.erase(erase_it->first); + } + return 0; + } +int conn_manager_t::clear_inactive() +{ + if(get_current_time()-last_clear_time>conn_clear_interval) + { + last_clear_time=get_current_time(); + return clear_inactive0(); + } + return 0; +} +int conn_manager_t::clear_inactive0() +{ + unordered_map::iterator it; + unordered_map::iterator old_it; + + if(disable_conn_clear) return 0; + + //map::iterator it; + int cnt=0; + it=clear_it; + int size=mp.size(); + int num_to_clean=size/conn_clear_ratio+conn_clear_min; //clear 1/10 each time,to avoid latency glitch + + mylog(log_trace,"mp.size() %d\n", size); + + num_to_clean=min(num_to_clean,(int)mp.size()); + u64_t current_time=get_current_time(); + + for(;;) + { + if(cnt>=num_to_clean) break; + if(mp.begin()==mp.end()) break; + + if(it==mp.end()) + { + it=mp.begin(); + } + + if(it->second->state.server_current_state==server_ready &¤t_time - it->second->last_hb_recv_time <=server_conn_timeout) + { + it++; + } + else if(it->second->state.server_current_state!=server_ready&& current_time - it->second->last_state_time <=server_handshake_timeout ) + { + it++; + } + else if(it->second->blob!=0&&it->second->blob->conv_manager.get_size() >0) + { + assert(it->second->state.server_current_state==server_ready); + it++; + } + else + { + mylog(log_info,"[%s:%d]inactive conn cleared \n",my_ntoa(it->second->raw_info.recv_info.src_ip),it->second->raw_info.recv_info.src_port); + old_it=it; + it++; + erase(old_it); + } + cnt++; + } + return 0; +} + + + diff --git a/connection.h b/connection.h new file mode 100644 index 0000000..e35a828 --- /dev/null +++ b/connection.h @@ -0,0 +1,145 @@ +/* + * connection.h + * + * Created on: Sep 23, 2017 + * Author: root + */ + +#ifndef CONNECTION_H_ +#define CONNECTION_H_ + +extern int disable_anti_replay; + +#include "connection.h" +#include "common.h" +#include "log.h" +#include "network.h" + +struct anti_replay_t //its for anti replay attack,similar to openvpn/ipsec 's anti replay window +{ + u64_t max_packet_received; + char window[anti_replay_window_size]; + anti_replay_seq_t anti_replay_seq; + anti_replay_seq_t get_new_seq_for_send(); + anti_replay_t(); + void re_init(); + + int is_vaild(u64_t seq); +};//anti_replay; + + +struct conv_manager_t // manage the udp connections +{ + //typedef hash_map map; + unordered_map u64_to_conv; //conv and u64 are both supposed to be uniq + unordered_map conv_to_u64; + + unordered_map conv_last_active_time; + + unordered_map::iterator clear_it; + + unordered_map::iterator it; + unordered_map::iterator old_it; + + //void (*clear_function)(uint64_t u64) ; + + long long last_clear_time; + + conv_manager_t(); + ~conv_manager_t(); + int get_size(); + void reserve(); + void clear(); + u32_t get_new_conv(); + int is_conv_used(u32_t conv); + int is_u64_used(u64_t u64); + u32_t find_conv_by_u64(u64_t u64); + u64_t find_u64_by_conv(u32_t conv); + int update_active_time(u32_t conv); + int insert_conv(u32_t conv,u64_t u64); + int erase_conv(u32_t conv); + int clear_inactive(char * ip_port=0); + int clear_inactive0(char * ip_port); +};//g_conv_manager; + +struct blob_t //used in conn_info_t. conv_manager_t and anti_replay_t are costly data structures ,we dont allocate them until its necessary +{ + conv_manager_t conv_manager; + anti_replay_t anti_replay; +}; +struct conn_info_t //stores info for a raw connection.for client ,there is only one connection,for server there can be thousand of connection since server can +//handle multiple clients +{ + current_state_t state; + + raw_info_t raw_info; + u64_t last_state_time; + u64_t last_hb_sent_time; //client re-use this for retry + u64_t last_hb_recv_time; + //long long last_resent_time; + + id_t my_id; + id_t oppsite_id; + + + int timer_fd; + id_t oppsite_const_id; + + blob_t *blob; + + uint8_t my_roller; + uint8_t oppsite_roller; + u64_t last_oppsite_roller_time; + +/* + const uint32_t &ip=raw_info.recv_info.src_ip; + const uint16_t &port=raw_info.recv_info.src_port; + +*/ + void recover(const conn_info_t &conn_info); + void re_init(); + conn_info_t(); + void prepare(); + conn_info_t(const conn_info_t&b); + conn_info_t& operator=(const conn_info_t& b); + ~conn_info_t(); +};//g_conn_info; + +struct conn_manager_t //manager for connections. for client,we dont need conn_manager since there is only one connection.for server we use one conn_manager for all connections +{ + + u32_t ready_num; + + unordered_map udp_fd_mp; //a bit dirty to used pointer,but can void unordered_map search + unordered_map timer_fd_mp;//we can use pointer here since unordered_map.rehash() uses shallow copy + + unordered_map const_id_mp; + + unordered_map mp; //put it at end so that it de-consturcts first + + unordered_map::iterator clear_it; + + long long last_clear_time; + + conn_manager_t(); + int exist(u32_t ip,uint16_t port); + /* + int insert(uint32_t ip,uint16_t port) + { + uint64_t u64=0; + u64=ip; + u64<<=32u; + u64|=port; + mp[u64]; + return 0; + }*/ + conn_info_t *& find_insert_p(u32_t ip,uint16_t port); //be aware,the adress may change after rehash + conn_info_t & find_insert(u32_t ip,uint16_t port) ; //be aware,the adress may change after rehash + + int erase(unordered_map::iterator erase_it); +int clear_inactive(); +int clear_inactive0(); + +}; + +#endif /* CONNECTION_H_ */ diff --git a/main.cpp b/main.cpp index a470ed0..c61d75a 100755 --- a/main.cpp +++ b/main.cpp @@ -1,5 +1,6 @@ #include "common.h" #include "network.h" +#include "connection.h" #include "log.h" #include "lib/md5.h" #include "encrypt.h" @@ -20,18 +21,6 @@ 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 -const int disable_conv_clear=0;//a udp connection in the multiplexer is called conversation in this program,conv for short. - -const int disable_conn_clear=0;//a raw connection is called conn. - - -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; -}; 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 @@ -49,7 +38,7 @@ int generate_iptables_rule=0;//if -g is set int generate_iptables_rule_add=0;// if --gen-add is set int debug_resend=0; // debug only -int disable_anti_replay=0;//if anti_replay windows is diabled + char key_string[1000]= "secret key";// -k option char key[16];//generated from key_string by md5. @@ -57,520 +46,10 @@ int mtu_warn=1375;//if a packet larger than mtu warn is receviced,there will be //uint64_t current_time_rough=0; - +conn_manager_t conn_manager; int VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV; ////////==============================variable divider============================================================= -struct anti_replay_t //its for anti replay attack,similar to openvpn/ipsec 's anti replay window -{ - u64_t max_packet_received; - char window[anti_replay_window_size]; - anti_replay_seq_t anti_replay_seq; - anti_replay_seq_t get_new_seq_for_send() - { - return anti_replay_seq++; - } - anti_replay_t() - { - max_packet_received=0; - anti_replay_seq=get_true_random_number_64()/10;//random first seq - //memset(window,0,sizeof(window)); //not necessary - } - void re_init() - { - max_packet_received=0; - //memset(window,0,sizeof(window)); - } - - int is_vaild(u64_t seq) - { - if(disable_anti_replay) return 1; - //if(disabled) return 0; - - if(seq==max_packet_received) return 0; - else if(seq>max_packet_received) - { - if(seq-max_packet_received>=anti_replay_window_size) - { - memset(window,0,sizeof(window)); - window[seq%anti_replay_window_size]=1; - } - else - { - for (u64_t i=max_packet_received+1;i=anti_replay_window_size) return 0; - else - { - if (window[seq%anti_replay_window_size]==1) return 0; - else - { - window[seq%anti_replay_window_size]=1; - return 1; - } - } - } - - - return 0; //for complier check - } -};//anti_replay; - -void server_clear_function(u64_t u64); -struct conv_manager_t // manage the udp connections -{ - //typedef hash_map map; - unordered_map u64_to_conv; //conv and u64 are both supposed to be uniq - unordered_map conv_to_u64; - - unordered_map conv_last_active_time; - - unordered_map::iterator clear_it; - - unordered_map::iterator it; - unordered_map::iterator old_it; - - //void (*clear_function)(uint64_t u64) ; - - long long last_clear_time; - - conv_manager_t() - { - clear_it=conv_last_active_time.begin(); - long long last_clear_time=0; - //clear_function=0; - } - ~conv_manager_t() - { - clear(); - } - int get_size() - { - return conv_to_u64.size(); - } - void reserve() - { - u64_to_conv.reserve(10007); - conv_to_u64.reserve(10007); - conv_last_active_time.reserve(10007); - } - void clear() - { - if(disable_conv_clear) return ; - - if(program_mode==server_mode) - { - for(it=conv_to_u64.begin();it!=conv_to_u64.end();it++) - { - //int fd=int((it->second<<32u)>>32u); - server_clear_function( it->second); - } - } - u64_to_conv.clear(); - conv_to_u64.clear(); - conv_last_active_time.clear(); - - clear_it=conv_last_active_time.begin(); - - } - u32_t get_new_conv() - { - u32_t conv=get_true_random_number_nz(); - while(conv_to_u64.find(conv)!=conv_to_u64.end()) - { - conv=get_true_random_number_nz(); - } - return conv; - } - int is_conv_used(u32_t conv) - { - return conv_to_u64.find(conv)!=conv_to_u64.end(); - } - int is_u64_used(u64_t u64) - { - return u64_to_conv.find(u64)!=u64_to_conv.end(); - } - u32_t find_conv_by_u64(u64_t u64) - { - return u64_to_conv[u64]; - } - u64_t find_u64_by_conv(u32_t conv) - { - return conv_to_u64[conv]; - } - int update_active_time(u32_t conv) - { - return conv_last_active_time[conv]=get_current_time(); - } - int insert_conv(u32_t conv,u64_t u64) - { - u64_to_conv[u64]=conv; - conv_to_u64[conv]=u64; - conv_last_active_time[conv]=get_current_time(); - return 0; - } - int erase_conv(u32_t conv) - { - if(disable_conv_clear) return 0; - u64_t u64=conv_to_u64[conv]; - if(program_mode==server_mode) - { - server_clear_function(u64); - } - conv_to_u64.erase(conv); - u64_to_conv.erase(u64); - conv_last_active_time.erase(conv); - return 0; - } - int clear_inactive(char * ip_port=0) - { - if(get_current_time()-last_clear_time>conv_clear_interval) - { - last_clear_time=get_current_time(); - return clear_inactive0(ip_port); - } - return 0; - } - int clear_inactive0(char * ip_port) - { - if(disable_conv_clear) return 0; - - - //map::iterator it; - int cnt=0; - it=clear_it; - int size=conv_last_active_time.size(); - int num_to_clean=size/conv_clear_ratio+conv_clear_min; //clear 1/10 each time,to avoid latency glitch - - num_to_clean=min(num_to_clean,size); - - u64_t current_time=get_current_time(); - for(;;) - { - if(cnt>=num_to_clean) break; - if(conv_last_active_time.begin()==conv_last_active_time.end()) break; - - if(it==conv_last_active_time.end()) - { - it=conv_last_active_time.begin(); - } - - if( current_time -it->second >conv_timeout ) - { - //mylog(log_info,"inactive conv %u cleared \n",it->first); - old_it=it; - it++; - u32_t conv= old_it->first; - erase_conv(old_it->first); - if(ip_port==0) - { - mylog(log_info,"conv %x cleared\n",conv); - } - else - { - mylog(log_info,"[%s]conv %x cleared\n",ip_port,conv); - } - } - else - { - it++; - } - cnt++; - } - return 0; - } -};//g_conv_manager; -struct blob_t //used in conn_info_t. conv_manager_t and anti_replay_t are costly data structures ,we dont allocate them until its necessary -{ - conv_manager_t conv_manager; - anti_replay_t anti_replay; -}; -struct conn_info_t //stores info for a raw connection.for client ,there is only one connection,for server there can be thousand of connection since server can -//handle multiple clients -{ - current_state_t state; - - raw_info_t raw_info; - u64_t last_state_time; - u64_t last_hb_sent_time; //client re-use this for retry - u64_t last_hb_recv_time; - //long long last_resent_time; - - id_t my_id; - id_t oppsite_id; - - - int timer_fd; - id_t oppsite_const_id; - - blob_t *blob; - - uint8_t my_roller; - uint8_t oppsite_roller; - u64_t last_oppsite_roller_time; - -/* - const uint32_t &ip=raw_info.recv_info.src_ip; - const uint16_t &port=raw_info.recv_info.src_port; - -*/ - void recover(const conn_info_t &conn_info) - { - raw_info=conn_info.raw_info; - last_state_time=conn_info.last_state_time; - last_hb_recv_time=conn_info.last_hb_recv_time; - last_hb_sent_time=conn_info.last_hb_sent_time; - my_id=conn_info.my_id; - oppsite_id=conn_info.oppsite_id; - blob->anti_replay.re_init(); - - my_roller=0;//no need to set,but for easier debug,set it to zero - oppsite_roller=0;//same as above - last_oppsite_roller_time=0; - } - - void re_init() - { - //send_packet_info.protocol=g_packet_info_send.protocol; - if(program_mode==server_mode) - state.server_current_state=server_idle; - else - state.client_current_state=client_idle; - last_state_time=0; - oppsite_const_id=0; - - timer_fd=0; - - my_roller=0; - oppsite_roller=0; - last_oppsite_roller_time=0; - } - conn_info_t() - { - blob=0; - re_init(); - } - void prepare() - { - blob=new blob_t; - - } - conn_info_t(const conn_info_t&b) - { - //mylog(log_error,"called!!!!!!!!!!!!!\n"); - *this=b; - if(blob!=0) - { - blob=new blob_t(*b.blob); - } - } - conn_info_t& operator=(const conn_info_t& b) - { - mylog(log_fatal,"not allowed\n"); - myexit(-1); - return *this; - } - ~conn_info_t(); -};//g_conn_info; - -struct conn_manager_t //manager for connections. for client,we dont need conn_manager since there is only one connection.for server we use one conn_manager for all connections -{ - - u32_t ready_num; - - unordered_map udp_fd_mp; //a bit dirty to used pointer,but can void unordered_map search - unordered_map timer_fd_mp;//we can use pointer here since unordered_map.rehash() uses shallow copy - - unordered_map const_id_mp; - - unordered_map mp; //put it at end so that it de-consturcts first - - unordered_map::iterator clear_it; - - long long last_clear_time; - - conn_manager_t() - { - ready_num=0; - mp.reserve(10007); - clear_it=mp.begin(); - timer_fd_mp.reserve(10007); - const_id_mp.reserve(10007); - udp_fd_mp.reserve(100007); - last_clear_time=0; - //current_ready_ip=0; - // current_ready_port=0; - } - int exist(u32_t ip,uint16_t port) - { - u64_t u64=0; - u64=ip; - u64<<=32u; - u64|=port; - if(mp.find(u64)!=mp.end()) - { - return 1; - } - return 0; - } - /* - int insert(uint32_t ip,uint16_t port) - { - uint64_t u64=0; - u64=ip; - u64<<=32u; - u64|=port; - mp[u64]; - return 0; - }*/ - conn_info_t *& find_insert_p(u32_t ip,uint16_t port) //be aware,the adress may change after rehash - { - u64_t u64=0; - u64=ip; - u64<<=32u; - u64|=port; - unordered_map::iterator it=mp.find(u64); - if(it==mp.end()) - { - mp[u64]=new conn_info_t; - } - return mp[u64]; - } - conn_info_t & find_insert(u32_t ip,uint16_t port) //be aware,the adress may change after rehash - { - u64_t u64=0; - u64=ip; - u64<<=32u; - u64|=port; - unordered_map::iterator it=mp.find(u64); - if(it==mp.end()) - { - mp[u64]=new conn_info_t; - } - return *mp[u64]; - } - int erase(unordered_map::iterator erase_it) - { - if(erase_it->second->state.server_current_state==server_ready) - { - ready_num--; - assert(i32_t(ready_num)!=-1); - assert(erase_it->second!=0); - assert(erase_it->second->timer_fd !=0); - assert(erase_it->second->oppsite_const_id!=0); - assert(const_id_mp.find(erase_it->second->oppsite_const_id)!=const_id_mp.end()); - assert(timer_fd_mp.find(erase_it->second->timer_fd)!=timer_fd_mp.end()); - - const_id_mp.erase(erase_it->second->oppsite_const_id); - timer_fd_mp.erase(erase_it->second->timer_fd); - close(erase_it->second->timer_fd);// close will auto delte it from epoll - delete(erase_it->second); - mp.erase(erase_it->first); - } - else - { - assert(erase_it->second->blob==0); - assert(erase_it->second->timer_fd ==0); - assert(erase_it->second->oppsite_const_id==0); - delete(erase_it->second); - mp.erase(erase_it->first); - } - return 0; - } -int clear_inactive() -{ - if(get_current_time()-last_clear_time>conn_clear_interval) - { - last_clear_time=get_current_time(); - return clear_inactive0(); - } - return 0; -} -int clear_inactive0() -{ - unordered_map::iterator it; - unordered_map::iterator old_it; - - if(disable_conn_clear) return 0; - - //map::iterator it; - int cnt=0; - it=clear_it; - int size=mp.size(); - int num_to_clean=size/conn_clear_ratio+conn_clear_min; //clear 1/10 each time,to avoid latency glitch - - mylog(log_trace,"mp.size() %d\n", size); - - num_to_clean=min(num_to_clean,(int)mp.size()); - u64_t current_time=get_current_time(); - - for(;;) - { - if(cnt>=num_to_clean) break; - if(mp.begin()==mp.end()) break; - - if(it==mp.end()) - { - it=mp.begin(); - } - - if(it->second->state.server_current_state==server_ready &¤t_time - it->second->last_hb_recv_time <=server_conn_timeout) - { - it++; - } - else if(it->second->state.server_current_state!=server_ready&& current_time - it->second->last_state_time <=server_handshake_timeout ) - { - it++; - } - else if(it->second->blob!=0&&it->second->blob->conv_manager.get_size() >0) - { - assert(it->second->state.server_current_state==server_ready); - it++; - } - else - { - mylog(log_info,"[%s:%d]inactive conn cleared \n",my_ntoa(it->second->raw_info.recv_info.src_ip),it->second->raw_info.recv_info.src_port); - old_it=it; - it++; - erase(old_it); - } - cnt++; - } - return 0; -} - -}conn_manager; - -conn_info_t::~conn_info_t() -{ - if(program_mode==server_mode) - { - if(state.server_current_state==server_ready) - { - assert(blob!=0); - assert(oppsite_const_id!=0); - //assert(conn_manager.const_id_mp.find(oppsite_const_id)!=conn_manager.const_id_mp.end()); // conn_manager 's deconstuction function erases it - } - else - { - assert(blob==0); - assert(oppsite_const_id==0); - } - } - //if(oppsite_const_id!=0) //do this at conn_manager 's deconstuction function - //conn_manager.const_id_mp.erase(oppsite_const_id); - if(blob!=0) - delete blob; - - //send_packet_info.protocol=g_packet_info_send.protocol; -} int TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT; ////////==========================type divider======================================================= diff --git a/makefile b/makefile index 6ca021f..743a861 100755 --- a/makefile +++ b/makefile @@ -8,7 +8,7 @@ cc_arm= /toolchains/arm-2014.05/bin/arm-none-linux-gnueabi-g++ #cc_bcm2708=/home/wangyu/raspberry/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf-g++ FLAGS= -std=c++11 -Wall -Wextra -Wno-unused-variable -Wno-unused-parameter -Wno-missing-field-initializers -COMMON=main.cpp lib/md5.c encrypt.cpp log.cpp network.cpp common.cpp -lpthread +COMMON=main.cpp lib/md5.c encrypt.cpp log.cpp network.cpp common.cpp connection.cpp -lpthread SOURCES= $(COMMON) lib/aes_faster_c/aes.c lib/aes_faster_c/wrapper.c SOURCES_TINY_AES= $(COMMON) lib/aes.c SOURCES_AES_ACC=$(COMMON) $(wildcard lib/aes_acc/aes*.c)