connection.h 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  1. /*
  2. * connection.h
  3. *
  4. * Created on: Sep 23, 2017
  5. * Author: root
  6. */
  7. #ifndef CONNECTION_H_
  8. #define CONNECTION_H_
  9. extern int disable_anti_replay;
  10. #include "connection.h"
  11. #include "common.h"
  12. #include "log.h"
  13. #include "network.h"
  14. #include "misc.h"
  15. const int disable_conv_clear=0;//a udp connection in the multiplexer is called conversation in this program,conv for short.
  16. struct anti_replay_t //its for anti replay attack,similar to openvpn/ipsec 's anti replay window
  17. {
  18. u64_t max_packet_received;
  19. char window[anti_replay_window_size];
  20. anti_replay_seq_t anti_replay_seq;
  21. anti_replay_seq_t get_new_seq_for_send();
  22. anti_replay_t();
  23. void re_init();
  24. int is_vaild(u64_t seq);
  25. };//anti_replay;
  26. void server_clear_function(u64_t u64);
  27. #include <type_traits>
  28. template <class T>
  29. struct conv_manager_t // manage the udp connections
  30. {
  31. //typedef hash_map map;
  32. unordered_map<T,u32_t> data_to_conv; //conv and u64 are both supposed to be uniq
  33. unordered_map<u32_t,T> conv_to_data;
  34. lru_collector_t<u32_t> lru;
  35. //unordered_map<u32_t,u64_t> conv_last_active_time;
  36. //unordered_map<u32_t,u64_t>::iterator clear_it;
  37. void (*additional_clear_function)(T data) =0;
  38. long long last_clear_time;
  39. conv_manager_t()
  40. {
  41. //clear_it=conv_last_active_time.begin();
  42. long long last_clear_time=0;
  43. additional_clear_function=0;
  44. }
  45. ~conv_manager_t()
  46. {
  47. clear();
  48. }
  49. int get_size()
  50. {
  51. return conv_to_data.size();
  52. }
  53. void reserve()
  54. {
  55. data_to_conv.reserve(10007);
  56. conv_to_data.reserve(10007);
  57. //conv_last_active_time.reserve(10007);
  58. lru.mp.reserve(10007);
  59. }
  60. void clear()
  61. {
  62. if(disable_conv_clear) return ;
  63. if(additional_clear_function!=0)
  64. {
  65. for(auto it=conv_to_data.begin();it!=conv_to_data.end();it++)
  66. {
  67. //int fd=int((it->second<<32u)>>32u);
  68. additional_clear_function( it->second);
  69. }
  70. }
  71. data_to_conv.clear();
  72. conv_to_data.clear();
  73. lru.clear();
  74. //conv_last_active_time.clear();
  75. //clear_it=conv_last_active_time.begin();
  76. }
  77. u32_t get_new_conv()
  78. {
  79. u32_t conv=get_true_random_number_nz();
  80. while(conv_to_data.find(conv)!=conv_to_data.end())
  81. {
  82. conv=get_true_random_number_nz();
  83. }
  84. return conv;
  85. }
  86. int is_conv_used(u32_t conv)
  87. {
  88. return conv_to_data.find(conv)!=conv_to_data.end();
  89. }
  90. int is_data_used(T data)
  91. {
  92. return data_to_conv.find(data)!=data_to_conv.end();
  93. }
  94. u32_t find_conv_by_data(T data)
  95. {
  96. return data_to_conv[data];
  97. }
  98. T find_data_by_conv(u32_t conv)
  99. {
  100. return conv_to_data[conv];
  101. }
  102. int update_active_time(u32_t conv)
  103. {
  104. //return conv_last_active_time[conv]=get_current_time();
  105. lru.update(conv);
  106. return 0;
  107. }
  108. int insert_conv(u32_t conv,T data)
  109. {
  110. data_to_conv[data]=conv;
  111. conv_to_data[conv]=data;
  112. //conv_last_active_time[conv]=get_current_time();
  113. lru.new_key(conv);
  114. return 0;
  115. }
  116. int erase_conv(u32_t conv)
  117. {
  118. if(disable_conv_clear) return 0;
  119. T data=conv_to_data[conv];
  120. if(additional_clear_function!=0)
  121. {
  122. additional_clear_function(data);
  123. }
  124. conv_to_data.erase(conv);
  125. data_to_conv.erase(data);
  126. //conv_last_active_time.erase(conv);
  127. lru.erase(conv);
  128. return 0;
  129. }
  130. int clear_inactive(char * info=0)
  131. {
  132. if(get_current_time()-last_clear_time>conv_clear_interval)
  133. {
  134. last_clear_time=get_current_time();
  135. return clear_inactive0(info);
  136. }
  137. return 0;
  138. }
  139. int clear_inactive0(char * info)
  140. {
  141. if(disable_conv_clear) return 0;
  142. unordered_map<u32_t,u64_t>::iterator it;
  143. unordered_map<u32_t,u64_t>::iterator old_it;
  144. //map<uint32_t,uint64_t>::iterator it;
  145. int cnt=0;
  146. //it=clear_it;
  147. int size=lru.size();
  148. int num_to_clean=size/conv_clear_ratio+conv_clear_min; //clear 1/10 each time,to avoid latency glitch
  149. num_to_clean=min(num_to_clean,size);
  150. my_time_t current_time=get_current_time();
  151. for(;;)
  152. {
  153. if(cnt>=num_to_clean) break;
  154. if(lru.empty()) break;
  155. u32_t conv;
  156. my_time_t ts=lru.peek_back(conv);
  157. if(current_time- ts < conv_timeout) break;
  158. erase_conv(conv);
  159. if(info==0)
  160. {
  161. mylog(log_info,"conv %x cleared\n",conv);
  162. }
  163. else
  164. {
  165. mylog(log_info,"[%s]conv %x cleared\n",info,conv);
  166. }
  167. cnt++;
  168. }
  169. return 0;
  170. }
  171. /*
  172. conv_manager_t();
  173. ~conv_manager_t();
  174. int get_size();
  175. void reserve();
  176. void clear();
  177. u32_t get_new_conv();
  178. int is_conv_used(u32_t conv);
  179. int is_u64_used(T u64);
  180. u32_t find_conv_by_u64(T u64);
  181. T find_u64_by_conv(u32_t conv);
  182. int update_active_time(u32_t conv);
  183. int insert_conv(u32_t conv,T u64);
  184. int erase_conv(u32_t conv);
  185. int clear_inactive(char * ip_port=0);
  186. int clear_inactive0(char * ip_port);*/
  187. };//g_conv_manager;
  188. struct blob_t:not_copy_able_t //used in conn_info_t.
  189. {
  190. union tmp_union_t//conv_manager_t is here to avoid copying when a connection is recovered
  191. {
  192. conv_manager_t<address_t> c;
  193. conv_manager_t<u64_t> s;
  194. //avoid templates here and there, avoid pointer and type cast
  195. tmp_union_t()
  196. {
  197. if(program_mode==client_mode)
  198. {
  199. new( &c ) conv_manager_t<address_t>();
  200. }
  201. else
  202. {
  203. assert(program_mode==server_mode);
  204. new( &s ) conv_manager_t<u64_t>();
  205. }
  206. }
  207. ~tmp_union_t()
  208. {
  209. if(program_mode==client_mode)
  210. {
  211. c.~conv_manager_t<address_t>();
  212. }
  213. else
  214. {
  215. assert(program_mode==server_mode);
  216. s.~conv_manager_t<u64_t>();
  217. }
  218. }
  219. }conv_manager;
  220. anti_replay_t anti_replay;//anti_replay_t is here bc its huge,its allocation is delayed.
  221. };
  222. 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
  223. //handle multiple clients
  224. {
  225. current_state_t state;
  226. raw_info_t raw_info;
  227. u64_t last_state_time;
  228. u64_t last_hb_sent_time; //client re-use this for retry
  229. u64_t last_hb_recv_time;
  230. //long long last_resent_time;
  231. my_id_t my_id;
  232. my_id_t oppsite_id;
  233. fd64_t timer_fd64;
  234. fd64_t udp_fd64;
  235. my_id_t oppsite_const_id;
  236. blob_t *blob;
  237. uint8_t my_roller;
  238. uint8_t oppsite_roller;
  239. u64_t last_oppsite_roller_time;
  240. // ip_port_t ip_port;
  241. /*
  242. const uint32_t &ip=raw_info.recv_info.src_ip;
  243. const uint16_t &port=raw_info.recv_info.src_port;
  244. */
  245. void recover(const conn_info_t &conn_info);
  246. void re_init();
  247. conn_info_t();
  248. void prepare();
  249. conn_info_t(const conn_info_t&b);
  250. conn_info_t& operator=(const conn_info_t& b);
  251. ~conn_info_t();
  252. };//g_conn_info;
  253. 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
  254. {
  255. u32_t ready_num;
  256. //unordered_map<int,conn_info_t *> udp_fd_mp; //a bit dirty to used pointer,but can void unordered_map search
  257. //unordered_map<int,conn_info_t *> timer_fd_mp;//we can use pointer here since unordered_map.rehash() uses shallow copy
  258. unordered_map<my_id_t,conn_info_t *> const_id_mp;
  259. unordered_map<address_t,conn_info_t*> mp; //put it at end so that it de-consturcts first
  260. //lru_collector_t<address_t> lru;
  261. unordered_map<address_t,conn_info_t*>::iterator clear_it;
  262. long long last_clear_time;
  263. conn_manager_t();
  264. int exist(address_t addr);
  265. /*
  266. int insert(uint32_t ip,uint16_t port)
  267. {
  268. uint64_t u64=0;
  269. u64=ip;
  270. u64<<=32u;
  271. u64|=port;
  272. mp[u64];
  273. return 0;
  274. }*/
  275. conn_info_t *& find_insert_p(address_t addr); //be aware,the adress may change after rehash //not true?
  276. conn_info_t & find_insert(address_t addr) ; //be aware,the adress may change after rehash
  277. int erase(unordered_map<address_t,conn_info_t*>::iterator erase_it);
  278. int clear_inactive();
  279. int clear_inactive0();
  280. };
  281. extern conn_manager_t conn_manager;
  282. void server_clear_function(u64_t u64);
  283. int send_bare(raw_info_t &raw_info,const char* data,int len);//send function with encryption but no anti replay,this is used when client and server verifys each other
  284. //you have to design the protocol carefully, so that you wont be affect by relay attack
  285. //int reserved_parse_bare(const char *input,int input_len,char* & data,int & len); // a sub function used in recv_bare
  286. int recv_bare(raw_info_t &raw_info,char* & data,int & len);//recv function with encryption but no anti replay,this is used when client and server verifys each other
  287. //you have to design the protocol carefully, so that you wont be affect by relay attack
  288. int send_handshake(raw_info_t &raw_info,my_id_t id1,my_id_t id2,my_id_t id3);// a warp for send_bare for sending handshake(this is not tcp handshake) easily
  289. int send_safer(conn_info_t &conn_info,char type,const char* data,int len); //safer transfer function with anti-replay,when mutually verification is done.
  290. int send_data_safer(conn_info_t &conn_info,const char* data,int len,u32_t conv_num);//a wrap for send_safer for transfer data.
  291. //int reserved_parse_safer(conn_info_t &conn_info,const char * input,int input_len,char &type,char* &data,int &len);//subfunction for recv_safer,allow overlap
  292. //int recv_safer(conn_info_t &conn_info,char &type,char* &data,int &len);///safer transfer function with anti-replay,when mutually verification is done.
  293. int recv_safer_multi(conn_info_t &conn_info,vector<char> &type_arr,vector<string> &data_arr);//new api for handle gro
  294. #endif /* CONNECTION_H_ */