connection.h 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
  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 "delay_manager.h"
  14. #include "fd_manager.h"
  15. #include "fec_manager.h"
  16. extern int report_interval;
  17. const int disable_conv_clear=0;
  18. void server_clear_function(u64_t u64);
  19. template <class T>
  20. struct conv_manager_t // manage the udp connections
  21. {
  22. //typedef hash_map map;
  23. unordered_map<T,u32_t> data_to_conv; //conv and u64 are both supposed to be uniq
  24. unordered_map<u32_t,T> conv_to_data;
  25. lru_collector_t<u32_t> lru;
  26. //unordered_map<u32_t,u64_t> conv_last_active_time;
  27. //unordered_map<u32_t,u64_t>::iterator clear_it;
  28. void (*additional_clear_function)(T data) =0;
  29. long long last_clear_time;
  30. conv_manager_t()
  31. {
  32. //clear_it=conv_last_active_time.begin();
  33. long long last_clear_time=0;
  34. additional_clear_function=0;
  35. }
  36. ~conv_manager_t()
  37. {
  38. clear();
  39. }
  40. int get_size()
  41. {
  42. return conv_to_data.size();
  43. }
  44. void reserve()
  45. {
  46. data_to_conv.reserve(10007);
  47. conv_to_data.reserve(10007);
  48. //conv_last_active_time.reserve(10007);
  49. lru.mp.reserve(10007);
  50. }
  51. void clear()
  52. {
  53. if(disable_conv_clear) return ;
  54. if(additional_clear_function!=0)
  55. {
  56. for(auto it=conv_to_data.begin();it!=conv_to_data.end();it++)
  57. {
  58. //int fd=int((it->second<<32u)>>32u);
  59. additional_clear_function( it->second);
  60. }
  61. }
  62. data_to_conv.clear();
  63. conv_to_data.clear();
  64. lru.clear();
  65. //conv_last_active_time.clear();
  66. //clear_it=conv_last_active_time.begin();
  67. }
  68. u32_t get_new_conv()
  69. {
  70. u32_t conv=get_fake_random_number_nz();
  71. while(conv_to_data.find(conv)!=conv_to_data.end())
  72. {
  73. conv=get_fake_random_number_nz();
  74. }
  75. return conv;
  76. }
  77. int is_conv_used(u32_t conv)
  78. {
  79. return conv_to_data.find(conv)!=conv_to_data.end();
  80. }
  81. int is_data_used(T data)
  82. {
  83. return data_to_conv.find(data)!=data_to_conv.end();
  84. }
  85. u32_t find_conv_by_data(T data)
  86. {
  87. return data_to_conv[data];
  88. }
  89. T find_data_by_conv(u32_t conv)
  90. {
  91. return conv_to_data[conv];
  92. }
  93. int update_active_time(u32_t conv)
  94. {
  95. //return conv_last_active_time[conv]=get_current_time();
  96. lru.update(conv);
  97. return 0;
  98. }
  99. int insert_conv(u32_t conv,T data)
  100. {
  101. data_to_conv[data]=conv;
  102. conv_to_data[conv]=data;
  103. //conv_last_active_time[conv]=get_current_time();
  104. lru.new_key(conv);
  105. return 0;
  106. }
  107. int erase_conv(u32_t conv)
  108. {
  109. if(disable_conv_clear) return 0;
  110. T data=conv_to_data[conv];
  111. if(additional_clear_function!=0)
  112. {
  113. additional_clear_function(data);
  114. }
  115. conv_to_data.erase(conv);
  116. data_to_conv.erase(data);
  117. //conv_last_active_time.erase(conv);
  118. lru.erase(conv);
  119. return 0;
  120. }
  121. int clear_inactive(char * info=0)
  122. {
  123. if(get_current_time()-last_clear_time>conv_clear_interval)
  124. {
  125. last_clear_time=get_current_time();
  126. return clear_inactive0(info);
  127. }
  128. return 0;
  129. }
  130. int clear_inactive0(char * info)
  131. {
  132. if(disable_conv_clear) return 0;
  133. unordered_map<u32_t,u64_t>::iterator it;
  134. unordered_map<u32_t,u64_t>::iterator old_it;
  135. //map<uint32_t,uint64_t>::iterator it;
  136. int cnt=0;
  137. //it=clear_it;
  138. int size=lru.size();
  139. int num_to_clean=size/conv_clear_ratio+conv_clear_min; //clear 1/10 each time,to avoid latency glitch
  140. num_to_clean=min(num_to_clean,size);
  141. my_time_t current_time=get_current_time();
  142. for(;;)
  143. {
  144. if(cnt>=num_to_clean) break;
  145. if(lru.empty()) break;
  146. u32_t conv;
  147. my_time_t ts=lru.peek_back(conv);
  148. if(current_time- ts < conv_timeout) break;
  149. erase_conv(conv);
  150. if(info==0)
  151. {
  152. mylog(log_info,"conv %x cleared\n",conv);
  153. }
  154. else
  155. {
  156. mylog(log_info,"[%s]conv %x cleared\n",info,conv);
  157. }
  158. cnt++;
  159. }
  160. return 0;
  161. }
  162. /*
  163. conv_manager_t();
  164. ~conv_manager_t();
  165. int get_size();
  166. void reserve();
  167. void clear();
  168. u32_t get_new_conv();
  169. int is_conv_used(u32_t conv);
  170. int is_u64_used(T u64);
  171. u32_t find_conv_by_u64(T u64);
  172. T find_u64_by_conv(u32_t conv);
  173. int update_active_time(u32_t conv);
  174. int insert_conv(u32_t conv,T u64);
  175. int erase_conv(u32_t conv);
  176. int clear_inactive(char * ip_port=0);
  177. int clear_inactive0(char * ip_port);*/
  178. };//g_conv_manager;
  179. struct inner_stat_t
  180. {
  181. u64_t input_packet_num;
  182. u64_t input_packet_size;
  183. u64_t output_packet_num;
  184. u64_t output_packet_size;
  185. };
  186. struct stat_t
  187. {
  188. u64_t last_report_time;
  189. inner_stat_t normal_to_fec;
  190. inner_stat_t fec_to_normal;
  191. stat_t()
  192. {
  193. memset(this,0,sizeof(stat_t));
  194. }
  195. void report_as_client()
  196. {
  197. if(report_interval!=0 &&get_current_time()-last_report_time>u64_t(report_interval)*1000)
  198. {
  199. last_report_time=get_current_time();
  200. inner_stat_t &a=normal_to_fec;
  201. inner_stat_t &b=fec_to_normal;
  202. mylog(log_info,"[report]client-->server:(original:%llu pkt;%llu byte) (fec:%llu pkt,%llu byte) server-->client:(original:%llu pkt;%llu byte) (fec:%llu pkt;%llu byte)\n",
  203. a.input_packet_num,a.input_packet_size,a.output_packet_num,a.output_packet_size,
  204. b.output_packet_num,b.output_packet_size,b.input_packet_num,b.input_packet_size
  205. );
  206. }
  207. }
  208. void report_as_server(address_t &addr)
  209. {
  210. if(report_interval!=0 &&get_current_time()-last_report_time>u64_t(report_interval)*1000)
  211. {
  212. last_report_time=get_current_time();
  213. inner_stat_t &a=fec_to_normal;
  214. inner_stat_t &b=normal_to_fec;
  215. mylog(log_info,"[report][%s]client-->server:(original:%llu pkt;%llu byte) (fec:%llu pkt;%llu byte) server-->client:(original:%llu pkt;%llu byte) (fec:%llu pkt;%llu byte)\n",
  216. addr.get_str(),
  217. a.output_packet_num,a.output_packet_size,a.input_packet_num,a.input_packet_size,
  218. b.input_packet_num,b.input_packet_size,b.output_packet_num,b.output_packet_size
  219. );
  220. }
  221. }
  222. };
  223. 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
  224. //handle multiple clients
  225. {
  226. union tmp_union_t
  227. {
  228. conv_manager_t<address_t> c;
  229. conv_manager_t<u64_t> s;
  230. //avoid templates here and there, avoid pointer and type cast
  231. tmp_union_t()
  232. {
  233. if(program_mode==client_mode)
  234. {
  235. new( &c ) conv_manager_t<address_t>();
  236. }
  237. else
  238. {
  239. assert(program_mode==server_mode);
  240. new( &s ) conv_manager_t<u64_t>();
  241. }
  242. }
  243. ~tmp_union_t()
  244. {
  245. if(program_mode==client_mode)
  246. {
  247. c.~conv_manager_t<address_t>();
  248. }
  249. else
  250. {
  251. assert(program_mode==server_mode);
  252. s.~conv_manager_t<u64_t>();
  253. }
  254. }
  255. }conv_manager;
  256. fec_encode_manager_t fec_encode_manager;
  257. fec_decode_manager_t fec_decode_manager;
  258. ev_timer timer;
  259. //my_timer_t timer;
  260. u64_t last_active_time;
  261. stat_t stat;
  262. ev_loop* loop=0;
  263. int local_listen_fd;
  264. int remote_fd; //only used for client
  265. fd64_t remote_fd64;//only used for client
  266. //ip_port_t ip_port;
  267. address_t addr;//only used for server
  268. conn_info_t()
  269. {
  270. if(program_mode==server_mode)
  271. {
  272. conv_manager.s.additional_clear_function=server_clear_function;
  273. }
  274. else
  275. {
  276. assert(program_mode==client_mode);
  277. }
  278. }
  279. ~conn_info_t()
  280. {
  281. if(loop)
  282. ev_timer_stop(loop,&timer);
  283. }
  284. void update_active_time()
  285. {
  286. last_active_time=get_current_time();
  287. }
  288. conn_info_t(const conn_info_t &b)
  289. {
  290. assert(0==1);
  291. }
  292. };
  293. /*
  294. 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
  295. {
  296. unordered_map<u64_t,conn_info_t*> mp;//<ip,port> to conn_info_t;
  297. unordered_map<u64_t,conn_info_t*>::iterator clear_it;
  298. long long last_clear_time;
  299. conn_manager_t();
  300. conn_manager_t(const conn_info_t &b)
  301. {
  302. assert(0==1);
  303. }
  304. int exist(ip_port_t);
  305. conn_info_t *& find_p(ip_port_t); //be aware,the adress may change after rehash
  306. conn_info_t & find(ip_port_t) ; //be aware,the adress may change after rehash
  307. int insert(ip_port_t);
  308. int erase(unordered_map<u64_t,conn_info_t*>::iterator erase_it);
  309. int clear_inactive();
  310. int clear_inactive0();
  311. };*/
  312. 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
  313. {
  314. unordered_map<address_t,conn_info_t*> mp; //put it at end so that it de-consturcts first
  315. unordered_map<address_t,conn_info_t*>::iterator clear_it;
  316. long long last_clear_time;
  317. conn_manager_t();
  318. int exist(address_t addr);
  319. conn_info_t *& find_insert_p(address_t addr); //be aware,the adress may change after rehash //not true?
  320. conn_info_t & find_insert(address_t addr) ; //be aware,the adress may change after rehash
  321. int erase(unordered_map<address_t,conn_info_t*>::iterator erase_it);
  322. int clear_inactive();
  323. int clear_inactive0();
  324. };
  325. extern conn_manager_t conn_manager;
  326. #endif /* CONNECTION_H_ */