common.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609
  1. /*
  2. * comm.cpp
  3. *
  4. * Created on: Jul 29, 2017
  5. * Author: wangyu
  6. */
  7. #include "common.h"
  8. #include "log.h"
  9. int about_to_exit=0;
  10. raw_mode_t raw_mode=mode_faketcp;
  11. unordered_map<int, const char*> raw_mode_tostring = {{mode_faketcp, "faketcp"}, {mode_udp, "udp"}, {mode_icmp, "icmp"}};
  12. int socket_buf_size=1024*1024;
  13. static int random_number_fd=-1;
  14. string iptables_pattern="";
  15. int iptables_rule_added=0;
  16. int iptables_rule_keeped=0;
  17. int iptables_rule_keep_index=0;
  18. //int iptables_rule_no_clear=0;
  19. program_mode_t program_mode=unset_mode;//0 unset; 1client 2server
  20. u64_t get_current_time()
  21. {
  22. timespec tmp_time;
  23. clock_gettime(CLOCK_MONOTONIC, &tmp_time);
  24. return tmp_time.tv_sec*1000+tmp_time.tv_nsec/(1000*1000l);
  25. }
  26. u64_t pack_u64(u32_t a,u32_t b)
  27. {
  28. u64_t ret=a;
  29. ret<<=32u;
  30. ret+=b;
  31. return ret;
  32. }
  33. u32_t get_u64_h(u64_t a)
  34. {
  35. return a>>32u;
  36. }
  37. u32_t get_u64_l(u64_t a)
  38. {
  39. return (a<<32u)>>32u;
  40. }
  41. char * my_ntoa(u32_t ip)
  42. {
  43. in_addr a;
  44. a.s_addr=ip;
  45. return inet_ntoa(a);
  46. }
  47. /*
  48. int add_iptables_rule(const char * s)
  49. {
  50. iptables_pattern=s;
  51. string rule="iptables -I INPUT ";
  52. rule+=iptables_pattern;
  53. rule+=" -j DROP";
  54. char *output;
  55. if(run_command(rule.c_str(),output)==0)
  56. {
  57. mylog(log_warn,"auto added iptables rule by: %s\n",rule.c_str());
  58. }
  59. else
  60. {
  61. mylog(log_fatal,"auto added iptables failed by: %s\n",rule.c_str());
  62. //mylog(log_fatal,"reason : %s\n",strerror(errno));
  63. myexit(-1);
  64. }
  65. iptables_rule_added=1;
  66. return 0;
  67. }*/
  68. string chain[2];
  69. string rule_keep[2];
  70. string rule_keep_add[2];
  71. string rule_keep_del[2];
  72. u64_t keep_rule_last_time=0;
  73. pthread_t keep_thread;
  74. int keep_thread_created=0;
  75. int iptables_gen_add(const char * s,u32_t const_id)
  76. {
  77. string dummy="";
  78. iptables_pattern=s;
  79. chain[0] =dummy+ "udp2rawDwrW_C";
  80. rule_keep[0]=dummy+ iptables_pattern+" -j " +chain[0];
  81. rule_keep_add[0]=dummy+"iptables -I INPUT "+rule_keep[0];
  82. char *output;
  83. run_command(dummy+"iptables -N "+chain[0],output,show_none);
  84. run_command(dummy+"iptables -F "+chain[0],output);
  85. run_command(dummy+"iptables -I "+chain[0] + " -j DROP",output);
  86. rule_keep_del[0]=dummy+"iptables -D INPUT "+rule_keep[0];
  87. run_command(rule_keep_del[0],output,show_none);
  88. run_command(rule_keep_del[0],output,show_none);
  89. if(run_command(rule_keep_add[0],output)!=0)
  90. {
  91. mylog(log_fatal,"auto added iptables failed by: %s\n",rule_keep_add[0].c_str());
  92. myexit(-1);
  93. }
  94. return 0;
  95. }
  96. int iptables_rule_init(const char * s,u32_t const_id,int keep)
  97. {
  98. iptables_pattern=s;
  99. iptables_rule_added=1;
  100. iptables_rule_keeped=keep;
  101. string dummy="";
  102. char const_id_str[100];
  103. sprintf(const_id_str, "%x", const_id);
  104. chain[0] =dummy+ "udp2rawDwrW_"+const_id_str+"_C0";
  105. chain[1] =dummy+ "udp2rawDwrW_"+const_id_str+"_C1";
  106. rule_keep[0]=dummy+ iptables_pattern+" -j " +chain[0];
  107. rule_keep[1]=dummy+ iptables_pattern+" -j " +chain[1];
  108. rule_keep_add[0]=dummy+"iptables -I INPUT "+rule_keep[0];
  109. rule_keep_add[1]=dummy+"iptables -I INPUT "+rule_keep[1];
  110. rule_keep_del[0]=dummy+"iptables -D INPUT "+rule_keep[0];
  111. rule_keep_del[1]=dummy+"iptables -D INPUT "+rule_keep[1];
  112. keep_rule_last_time=get_current_time();
  113. char *output;
  114. for(int i=0;i<=iptables_rule_keeped;i++)
  115. {
  116. run_command(dummy+"iptables -N "+chain[i],output);
  117. run_command(dummy+"iptables -F "+chain[i],output);
  118. run_command(dummy+"iptables -I "+chain[i] + " -j DROP",output);
  119. if(run_command(rule_keep_add[i],output)!=0)
  120. {
  121. mylog(log_fatal,"auto added iptables failed by: %s\n",rule_keep_add[i].c_str());
  122. myexit(-1);
  123. }
  124. }
  125. return 0;
  126. }
  127. int keep_iptables_rule() //magic to work on a machine without grep/iptables --check/-m commment
  128. {
  129. /*
  130. if(iptables_rule_keeped==0) return 0;
  131. uint64_t tmp_current_time=get_current_time();
  132. if(tmp_current_time-keep_rule_last_time<=iptables_rule_keep_interval)
  133. {
  134. return 0;
  135. }
  136. else
  137. {
  138. keep_rule_last_time=tmp_current_time;
  139. }*/
  140. mylog(log_debug,"keep_iptables_rule begin %llu\n",get_current_time());
  141. iptables_rule_keep_index+=1;
  142. iptables_rule_keep_index%=2;
  143. string dummy="";
  144. char *output;
  145. int i=iptables_rule_keep_index;
  146. run_command(dummy + "iptables -N " + chain[i], output,show_none);
  147. if (run_command(dummy + "iptables -F " + chain[i], output,show_none) != 0)
  148. mylog(log_warn, "iptables -F failed %d\n",i);
  149. if (run_command(dummy + "iptables -I " + chain[i] + " -j DROP",output,show_none) != 0)
  150. mylog(log_warn, "iptables -I failed %d\n",i);
  151. if (run_command(rule_keep_del[i], output,show_none) != 0)
  152. mylog(log_warn, "rule_keep_del failed %d\n",i);
  153. run_command(rule_keep_del[i], output,show_none); //do it twice,incase it fails for unknown random reason
  154. if(run_command(rule_keep_add[i], output,show_log)!=0)
  155. mylog(log_warn, "rule_keep_del failed %d\n",i);
  156. mylog(log_debug,"keep_iptables_rule end %llu\n",get_current_time());
  157. return 0;
  158. }
  159. int clear_iptables_rule()
  160. {
  161. char *output;
  162. string dummy="";
  163. if(!iptables_rule_added) return 0;
  164. for(int i=0;i<=iptables_rule_keeped;i++ )
  165. {
  166. run_command(rule_keep_del[i],output);
  167. run_command(dummy+"iptables -F "+chain[i],output);
  168. run_command(dummy+"iptables -X "+chain[i],output);
  169. }
  170. return 0;
  171. }
  172. void init_random_number_fd()
  173. {
  174. random_number_fd=open("/dev/urandom",O_RDONLY);
  175. if(random_number_fd==-1)
  176. {
  177. mylog(log_fatal,"error open /dev/urandom\n");
  178. myexit(-1);
  179. }
  180. setnonblocking(random_number_fd);
  181. }
  182. u64_t get_true_random_number_64()
  183. {
  184. u64_t ret;
  185. int size=read(random_number_fd,&ret,sizeof(ret));
  186. if(size!=sizeof(ret))
  187. {
  188. mylog(log_fatal,"get random number failed %d\n",size);
  189. myexit(-1);
  190. }
  191. return ret;
  192. }
  193. u32_t get_true_random_number()
  194. {
  195. u32_t ret;
  196. int size=read(random_number_fd,&ret,sizeof(ret));
  197. if(size!=sizeof(ret))
  198. {
  199. mylog(log_fatal,"get random number failed %d\n",size);
  200. myexit(-1);
  201. }
  202. return ret;
  203. }
  204. u32_t get_true_random_number_nz() //nz for non-zero
  205. {
  206. u32_t ret=0;
  207. while(ret==0)
  208. {
  209. ret=get_true_random_number();
  210. }
  211. return ret;
  212. }
  213. u64_t ntoh64(u64_t a)
  214. {
  215. if(__BYTE_ORDER == __LITTLE_ENDIAN)
  216. {
  217. return bswap_64( a);
  218. }
  219. else return a;
  220. }
  221. u64_t hton64(u64_t a)
  222. {
  223. if(__BYTE_ORDER == __LITTLE_ENDIAN)
  224. {
  225. return bswap_64( a);
  226. }
  227. else return a;
  228. }
  229. void setnonblocking(int sock) {
  230. int opts;
  231. opts = fcntl(sock, F_GETFL);
  232. if (opts < 0) {
  233. mylog(log_fatal,"fcntl(sock,GETFL)\n");
  234. //perror("fcntl(sock,GETFL)");
  235. myexit(1);
  236. }
  237. opts = opts | O_NONBLOCK;
  238. if (fcntl(sock, F_SETFL, opts) < 0) {
  239. mylog(log_fatal,"fcntl(sock,SETFL,opts)\n");
  240. //perror("fcntl(sock,SETFL,opts)");
  241. myexit(1);
  242. }
  243. }
  244. /*
  245. Generic checksum calculation function
  246. */
  247. unsigned short csum(const unsigned short *ptr,int nbytes) {
  248. register long sum;
  249. unsigned short oddbyte;
  250. register short answer;
  251. sum=0;
  252. while(nbytes>1) {
  253. sum+=*ptr++;
  254. nbytes-=2;
  255. }
  256. if(nbytes==1) {
  257. oddbyte=0;
  258. *((u_char*)&oddbyte)=*(u_char*)ptr;
  259. sum+=oddbyte;
  260. }
  261. sum = (sum>>16)+(sum & 0xffff);
  262. sum = sum + (sum>>16);
  263. answer=(short)~sum;
  264. return(answer);
  265. }
  266. int set_buf_size(int fd)
  267. {
  268. if(setsockopt(fd, SOL_SOCKET, SO_SNDBUFFORCE, &socket_buf_size, sizeof(socket_buf_size))<0)
  269. {
  270. mylog(log_fatal,"SO_SNDBUFFORCE fail,fd %d\n",fd);
  271. myexit(1);
  272. }
  273. if(setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, &socket_buf_size, sizeof(socket_buf_size))<0)
  274. {
  275. mylog(log_fatal,"SO_RCVBUFFORCE fail,fd %d\n",fd);
  276. myexit(1);
  277. }
  278. return 0;
  279. }
  280. void myexit(int a)
  281. {
  282. if(enable_log_color)
  283. printf("%s\n",RESET);
  284. if(keep_thread_created)
  285. {
  286. if(pthread_cancel(keep_thread))
  287. {
  288. mylog(log_warn,"pthread_cancel failed\n");
  289. }
  290. else
  291. {
  292. mylog(log_info,"pthread_cancel success\n");
  293. }
  294. }
  295. clear_iptables_rule();
  296. exit(a);
  297. }
  298. void signal_handler(int sig)
  299. {
  300. about_to_exit=1;
  301. // myexit(0);
  302. }
  303. int numbers_to_char(id_t id1,id_t id2,id_t id3,char * &data,int &len)
  304. {
  305. static char buf[buf_len];
  306. data=buf;
  307. id_t tmp=htonl(id1);
  308. memcpy(buf,&tmp,sizeof(tmp));
  309. tmp=htonl(id2);
  310. memcpy(buf+sizeof(tmp),&tmp,sizeof(tmp));
  311. tmp=htonl(id3);
  312. memcpy(buf+sizeof(tmp)*2,&tmp,sizeof(tmp));
  313. len=sizeof(id_t)*3;
  314. return 0;
  315. }
  316. int char_to_numbers(const char * data,int len,id_t &id1,id_t &id2,id_t &id3)
  317. {
  318. if(len<int(sizeof(id_t)*3)) return -1;
  319. id1=ntohl( *((id_t*)(data+0)) );
  320. id2=ntohl( *((id_t*)(data+sizeof(id_t))) );
  321. id3=ntohl( *((id_t*)(data+sizeof(id_t)*2)) );
  322. return 0;
  323. }
  324. bool larger_than_u32(u32_t a,u32_t b)
  325. {
  326. u32_t smaller,bigger;
  327. smaller=min(a,b);//smaller in normal sense
  328. bigger=max(a,b);
  329. u32_t distance=min(bigger-smaller,smaller+(0xffffffff-bigger+1));
  330. if(distance==bigger-smaller)
  331. {
  332. if(bigger==a)
  333. {
  334. return 1;
  335. }
  336. else
  337. {
  338. return 0;
  339. }
  340. }
  341. else
  342. {
  343. if(smaller==b)
  344. {
  345. return 0;
  346. }
  347. else
  348. {
  349. return 1;
  350. }
  351. }
  352. }
  353. bool larger_than_u16(uint16_t a,uint16_t b)
  354. {
  355. uint16_t smaller,bigger;
  356. smaller=min(a,b);//smaller in normal sense
  357. bigger=max(a,b);
  358. uint16_t distance=min(bigger-smaller,smaller+(0xffff-bigger+1));
  359. if(distance==bigger-smaller)
  360. {
  361. if(bigger==a)
  362. {
  363. return 1;
  364. }
  365. else
  366. {
  367. return 0;
  368. }
  369. }
  370. else
  371. {
  372. if(smaller==b)
  373. {
  374. return 0;
  375. }
  376. else
  377. {
  378. return 1;
  379. }
  380. }
  381. }
  382. vector<string> string_to_vec(const char * s,const char * sp) {
  383. vector<string> res;
  384. string str=s;
  385. char *p = strtok ((char *)str.c_str(),sp);
  386. while (p != NULL)
  387. {
  388. res.push_back(p);
  389. //printf ("%s\n",p);
  390. p = strtok (NULL, sp);
  391. }
  392. return res;
  393. }
  394. vector< vector <string> > string_to_vec2(const char * s)
  395. {
  396. vector< vector <string> > res;
  397. vector<string> lines=string_to_vec(s,"\n");
  398. for(int i=0;i<int(lines.size());i++)
  399. {
  400. vector<string> tmp;
  401. tmp=string_to_vec(lines[i].c_str(),"\t ");
  402. res.push_back(tmp);
  403. }
  404. return res;
  405. }
  406. int read_file(const char * file,char * &output)
  407. {
  408. static char buf[1024*1024+100];
  409. buf[sizeof(buf)-1]=0;
  410. int fd=open(file,O_RDONLY);
  411. if(fd==-1)
  412. {
  413. mylog(log_error,"read_file %s fail\n",file);
  414. return -1;
  415. }
  416. int len=read(fd,buf,1024*1024);
  417. if(len==1024*1024)
  418. {
  419. buf[0]=0;
  420. mylog(log_error,"too long,buf not larger enough\n");
  421. return -2;
  422. }
  423. else if(len<0)
  424. {
  425. buf[0]=0;
  426. mylog(log_error,"read fail %d\n",len);
  427. return -3;
  428. }
  429. else
  430. {
  431. output=buf;
  432. buf[len]=0;
  433. }
  434. return 0;
  435. }
  436. int run_command(string command0,char * &output,int flag) {
  437. FILE *in;
  438. if((flag&show_log)==0) command0+=" 2>&1 ";
  439. const char * command=command0.c_str();
  440. int level= (flag&show_log)?log_warn:log_debug;
  441. if(flag&show_command)
  442. {
  443. mylog(log_info,"run_command %s\n",command);
  444. }
  445. else
  446. {
  447. mylog(log_debug,"run_command %s\n",command);
  448. }
  449. static char buf[1024*1024+100];
  450. buf[sizeof(buf)-1]=0;
  451. if(!(in = popen(command, "r"))){
  452. mylog(level,"command %s popen failed,errno %s\n",command,strerror(errno));
  453. return -1;
  454. }
  455. int len =fread(buf, 1024*1024, 1, in);
  456. if(len==1024*1024)
  457. {
  458. buf[0]=0;
  459. mylog(level,"too long,buf not larger enough\n");
  460. return -2;
  461. }
  462. else
  463. {
  464. buf[len]=0;
  465. }
  466. int ret;
  467. if(( ret=ferror(in) ))
  468. {
  469. mylog(level,"command %s fread failed,ferror return value %d \n",command,ret);
  470. return -3;
  471. }
  472. //if(output!=0)
  473. output=buf;
  474. ret= pclose(in);
  475. int ret2=WEXITSTATUS(ret);
  476. if(ret!=0||ret2!=0)
  477. {
  478. mylog(level,"commnad %s ,pclose returned %d ,WEXITSTATUS %d,errnor :%s \n",command,ret,ret2,strerror(errno));
  479. return -4;
  480. }
  481. return 0;
  482. }
  483. /*
  484. int run_command_no_log(string command0,char * &output) {
  485. FILE *in;
  486. command0+=" 2>&1 ";
  487. const char * command=command0.c_str();
  488. mylog(log_debug,"run_command_no_log %s\n",command);
  489. static char buf[1024*1024+100];
  490. buf[sizeof(buf)-1]=0;
  491. if(!(in = popen(command, "r"))){
  492. mylog(log_debug,"command %s popen failed,errno %s\n",command,strerror(errno));
  493. return -1;
  494. }
  495. int len =fread(buf, 1024*1024, 1, in);
  496. if(len==1024*1024)
  497. {
  498. buf[0]=0;
  499. mylog(log_debug,"too long,buf not larger enough\n");
  500. return -2;
  501. }
  502. else
  503. {
  504. buf[len]=0;
  505. }
  506. int ret;
  507. if(( ret=ferror(in) ))
  508. {
  509. mylog(log_debug,"command %s fread failed,ferror return value %d \n",command,ret);
  510. return -3;
  511. }
  512. //if(output!=0)
  513. output=buf;
  514. ret= pclose(in);
  515. int ret2=WEXITSTATUS(ret);
  516. if(ret!=0||ret2!=0)
  517. {
  518. mylog(log_debug,"commnad %s ,pclose returned %d ,WEXITSTATUS %d,errnor :%s \n",command,ret,ret2,strerror(errno));
  519. return -4;
  520. }
  521. return 0;
  522. }*/