From 077d1023a7ed7f49134870429795637cfc24dd05 Mon Sep 17 00:00:00 2001 From: wangyu- Date: Wed, 29 Aug 2018 02:10:46 -0500 Subject: [PATCH] split main.cpp into main.cpp and client.cpp --- client.cpp | 981 +++++++++++++++++++++++++++++++++++++++++++++++++++++ main.cpp | 980 +--------------------------------------------------- makefile | 2 +- misc.cpp | 1 + misc.h | 2 + 5 files changed, 987 insertions(+), 979 deletions(-) create mode 100644 client.cpp diff --git a/client.cpp b/client.cpp new file mode 100644 index 0000000..82706d8 --- /dev/null +++ b/client.cpp @@ -0,0 +1,981 @@ +#include "common.h" +#include "network.h" +#include "connection.h" +#include "misc.h" +#include "log.h" +#include "lib/md5.h" +#include "encrypt.h" +#include "fd_manager.h" + + +u32_t detect_interval=1500; +u64_t laste_detect_time=0; + +int use_udp_for_detection=0; +int use_tcp_for_detection=1; + + +extern pcap_t *pcap_handle; + +extern int pcap_captured_full_len; + +int client_on_timer(conn_info_t &conn_info) //for client. called when a timer is ready in epoll +{ + 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; + conn_info.blob->conv_manager.c.clear_inactive(); + mylog(log_trace,"timer!\n"); + + mylog(log_trace,"roller my %d,oppsite %d,%lld\n",int(conn_info.my_roller),int(conn_info.oppsite_roller),conn_info.last_oppsite_roller_time); + + mylog(log_trace,"\n",send_info.ts_ack); + + + //mylog(log_debug,"pcap cnt :%d\n",pcap_cnt); + if(send_with_pcap&&!pcap_header_captured) + { + + if(get_current_time()-laste_detect_time>detect_interval) + { + laste_detect_time=get_current_time(); + } + else + { + return 0; + } + + struct sockaddr_in remote_addr_in={0}; + + socklen_t slen = sizeof(sockaddr_in); + //memset(&remote_addr_in, 0, sizeof(remote_addr_in)); + int port=get_true_random_number()%65534+1; + remote_addr_in.sin_family = AF_INET; + remote_addr_in.sin_port = htons(port); + remote_addr_in.sin_addr.s_addr = remote_ip_uint32; + + if(use_udp_for_detection) + { + int new_udp_fd=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if(new_udp_fd<0) + { + mylog(log_warn,"create new_udp_fd error\n"); + return -1; + } + setnonblocking(new_udp_fd); + u64_t tmp=get_true_random_number(); + + int ret=sendto(new_udp_fd,(char*)(&tmp),sizeof(tmp),0,(struct sockaddr *)&remote_addr_in,sizeof(remote_addr_in)); + if(ret==-1) + { + mylog(log_warn,"sendto() failed\n"); + } + sock_close(new_udp_fd); + } + + if(use_tcp_for_detection) + { + static int last_tcp_fd=-1; + + int new_tcp_fd=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if(new_tcp_fd<0) + { + mylog(log_warn,"create new_tcp_fd error\n"); + return -1; + } + setnonblocking(new_tcp_fd); + connect(new_tcp_fd,(struct sockaddr *)&remote_addr_in,sizeof(remote_addr_in)); + if(last_tcp_fd!=-1) + sock_close(last_tcp_fd); + last_tcp_fd=new_tcp_fd; + //close(new_tcp_fd); + } + + + + mylog(log_info,"waiting for a use-able packet to be captured\n"); + + return 0; + } + + if(raw_info.disabled) + { + conn_info.state.client_current_state=client_idle; + conn_info.my_id=get_true_random_number_nz(); + + mylog(log_info,"state back to client_idle\n"); + } + + if(conn_info.state.client_current_state==client_idle) + { + raw_info.rst_received=0; + raw_info.disabled=0; + + fail_time_counter++; + if(max_fail_time>0&&fail_time_counter>max_fail_time) + { + mylog(log_fatal,"max_fail_time exceed\n"); + myexit(-1); + } + + conn_info.blob->anti_replay.re_init(); + conn_info.my_id = get_true_random_number_nz(); ///todo no need to do this everytime + + + + u32_t new_ip=0; + if(!force_source_ip&&get_src_adress(new_ip,remote_ip_uint32,remote_port)==0) + { + if(new_ip!=source_ip_uint32) + { + mylog(log_info,"source ip changed from %s to ",my_ntoa(source_ip_uint32)); + log_bare(log_info,"%s\n",my_ntoa(new_ip)); + source_ip_uint32=new_ip; + send_info.src_ip=new_ip; + } + } + + if (source_port == 0) + { + send_info.src_port = client_bind_to_a_new_port(bind_fd,0); + } + else + { + send_info.src_port = source_port; + assert(try_to_list_and_bind(bind_fd,0,source_port)==0); + } + + + if (raw_mode == mode_icmp) + { + send_info.dst_port = send_info.src_port; + } + + mylog(log_info, "using port %d\n", send_info.src_port); + init_filter(send_info.src_port); + + if(raw_mode==mode_icmp||raw_mode==mode_udp) + { + conn_info.state.client_current_state=client_handshake1; + + mylog(log_info,"state changed from client_idle to client_pre_handshake\n"); + } + if(raw_mode==mode_faketcp) + { + if(use_tcp_dummy_socket) + { + + struct sockaddr_in remote_addr_in={0}; + socklen_t slen = sizeof(sockaddr_in); + //memset(&remote_addr_in, 0, sizeof(remote_addr_in)); + remote_addr_in.sin_family = AF_INET; + remote_addr_in.sin_port = htons(remote_port); + remote_addr_in.sin_addr.s_addr = remote_ip_uint32; + + //int new_tcp_fd=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + + setnonblocking(bind_fd); + int ret=connect(bind_fd,(struct sockaddr *)&remote_addr_in,sizeof(remote_addr_in)); + mylog(log_info,"ret=%d,errno=%s,%d %d\n",ret,get_sock_error(),bind_fd,remote_port); + conn_info.state.client_current_state=client_tcp_handshake_dummy; + mylog(log_info,"state changed from client_idle to client_tcp_handshake_dummy\n"); + } + else + { + + conn_info.state.client_current_state=client_tcp_handshake; + mylog(log_info,"state changed from client_idle to client_tcp_handshake\n"); + } + + } + conn_info.last_state_time=get_current_time(); + conn_info.last_hb_sent_time=0; + //dont return; + } + if(conn_info.state.client_current_state==client_tcp_handshake) //send and resend syn + { + assert(raw_mode==mode_faketcp); + if (get_current_time() - conn_info.last_state_time > client_handshake_timeout) + { + conn_info.state.client_current_state = client_idle; + mylog(log_info, "state back to client_idle from client_tcp_handshake\n"); + return 0; + + } + else if (get_current_time() - conn_info.last_hb_sent_time > client_retry_interval) + { + + if (raw_mode == mode_faketcp) + { + if (conn_info.last_hb_sent_time == 0) + { + send_info.psh = 0; + send_info.syn = 1; + send_info.ack = 0; + send_info.ts_ack =0; + send_info.seq=get_true_random_number(); + send_info.ack_seq=get_true_random_number(); + } + } + + send_raw0(raw_info, 0, 0); + + conn_info.last_hb_sent_time = get_current_time(); + mylog(log_info, "(re)sent tcp syn\n"); + return 0; + } + else + { + return 0; + } + return 0; + } + else if(conn_info.state.client_current_state==client_tcp_handshake_dummy) + { + assert(raw_mode==mode_faketcp); + if (get_current_time() - conn_info.last_state_time > client_handshake_timeout) + { + conn_info.state.client_current_state = client_idle; + mylog(log_info, "state back to client_idle from client_tcp_handshake_dummy\n"); + return 0; + + } + } + else if(conn_info.state.client_current_state==client_handshake1)//send and resend handshake1 + { + if(get_current_time()-conn_info.last_state_time>client_handshake_timeout) + { + conn_info.state.client_current_state=client_idle; + mylog(log_info,"state back to client_idle from client_handshake1\n"); + return 0; + + } + else if(get_current_time()-conn_info.last_hb_sent_time>client_retry_interval) + { + + if(raw_mode==mode_faketcp) + { + if(conn_info.last_hb_sent_time==0) + { + send_info.seq++; + send_info.ack_seq=recv_info.seq+1; + send_info.ts_ack=recv_info.ts; + raw_info.reserved_send_seq=send_info.seq; + } + send_info.seq=raw_info.reserved_send_seq; + send_info.psh = 0; + send_info.syn = 0; + send_info.ack = 1; + + if(!use_tcp_dummy_socket) + send_raw0(raw_info, 0, 0); + + send_handshake(raw_info,conn_info.my_id,0,const_id); + + send_info.seq+=raw_info.send_info.data_len; + } + else + { + + send_handshake(raw_info,conn_info.my_id,0,const_id); + if(raw_mode==mode_icmp) + send_info.my_icmp_seq++; + } + + conn_info.last_hb_sent_time=get_current_time(); + mylog(log_info,"(re)sent handshake1\n"); + return 0; + } + else + { + return 0; + } + return 0; + } + else if(conn_info.state.client_current_state==client_handshake2) + { + if(get_current_time()-conn_info.last_state_time>client_handshake_timeout) + { + conn_info.state.client_current_state=client_idle; + mylog(log_info,"state back to client_idle from client_handshake2\n"); + return 0; + } + else if(get_current_time()-conn_info.last_hb_sent_time>client_retry_interval) + { + if(raw_mode==mode_faketcp) + { + if(conn_info.last_hb_sent_time==0) + { + send_info.ack_seq=recv_info.seq+raw_info.recv_info.data_len; + send_info.ts_ack=recv_info.ts; + raw_info.reserved_send_seq=send_info.seq; + } + send_info.seq=raw_info.reserved_send_seq; + send_handshake(raw_info,conn_info.my_id,conn_info.oppsite_id,const_id); + send_info.seq+=raw_info.send_info.data_len; + + } + else + { + + send_handshake(raw_info,conn_info.my_id,conn_info.oppsite_id,const_id); + if(raw_mode==mode_icmp) + send_info.my_icmp_seq++; + } + conn_info.last_hb_sent_time=get_current_time(); + mylog(log_info,"(re)sent handshake2\n"); + return 0; + + } + else + { + return 0; + } + return 0; + } + else if(conn_info.state.client_current_state==client_ready) + { + fail_time_counter=0; + mylog(log_trace,"time %llu,%llu\n",get_current_time(),conn_info.last_state_time); + + if(get_current_time()-conn_info.last_hb_recv_time>client_conn_timeout) + { + conn_info.state.client_current_state=client_idle; + conn_info.my_id=get_true_random_number_nz(); + mylog(log_info,"state back to client_idle from client_ready bc of server-->client direction timeout\n"); + return 0; + } + + if(get_current_time()- conn_info.last_oppsite_roller_time>client_conn_uplink_timeout) + { + conn_info.state.client_current_state=client_idle; + conn_info.my_id=get_true_random_number_nz(); + mylog(log_info,"state back to client_idle from client_ready bc of client-->server direction timeout\n"); + } + + + if(get_current_time()-conn_info.last_hb_sent_time\n",conn_info.oppsite_id,conn_info.my_id); + + if(hb_mode==0) + send_safer(conn_info,'h',hb_buf,0);/////////////send + else + send_safer(conn_info,'h',hb_buf,hb_len); + conn_info.last_hb_sent_time=get_current_time(); + return 0; + } + else + { + mylog(log_fatal,"unknown state,this shouldnt happen.\n"); + myexit(-1); + } + return 0; +} +int client_on_raw_recv(conn_info_t &conn_info) //called when raw fd received a packet. +{ + char* data;int data_len; + 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; + + mylog(log_trace,"\n",send_info.ts_ack); + + if(conn_info.state.client_current_state==client_idle ) + { + g_packet_buf_cnt--; + //recv(raw_recv_fd, 0,0, 0 ); + //pthread_mutex_lock(&queue_mutex); + //my_queue.pop_front(); + //pthread_mutex_unlock(&queue_mutex); + } + else if(conn_info.state.client_current_state==client_tcp_handshake||conn_info.state.client_current_state==client_tcp_handshake_dummy)//received syn ack + { + assert(raw_mode==mode_faketcp); + if(recv_raw0(raw_info,data,data_len)<0) + { + return -1; + } + if(recv_info.src_ip!=send_info.dst_ip||recv_info.src_port!=send_info.dst_port) + { + mylog(log_debug,"unexpected adress %x %x %d %d\n",recv_info.src_ip,send_info.dst_ip,recv_info.src_port,send_info.dst_port); + return -1; + } + if(data_len==0&&raw_info.recv_info.syn==1&&raw_info.recv_info.ack==1) + { + if(conn_info.state.client_current_state==client_tcp_handshake) + { + if(recv_info.ack_seq!=send_info.seq+1) + { + mylog(log_debug,"seq ack_seq mis match\n"); + return -1; + } + mylog(log_info,"state changed from client_tcp_handshake to client_handshake1\n"); + } + else + { + send_info.seq=recv_info.ack_seq-1; + mylog(log_info,"state changed from client_tcp_dummy to client_handshake1\n"); + //send_info.ack_seq=recv_info.seq+1; + } + conn_info.state.client_current_state = client_handshake1; + + conn_info.last_state_time = get_current_time(); + conn_info.last_hb_sent_time=0; + client_on_timer(conn_info); + return 0; + } + else + { + mylog(log_debug,"unexpected packet type,expected:syn ack\n"); + return -1; + } + } + else if(conn_info.state.client_current_state==client_handshake1)//recevied respond of handshake1 + { + if(recv_bare(raw_info,data,data_len)!=0) + { + mylog(log_debug,"recv_bare failed!\n"); + return -1; + } + if(recv_info.src_ip!=send_info.dst_ip||recv_info.src_port!=send_info.dst_port) + { + mylog(log_debug,"unexpected adress %x %x %d %d\n",recv_info.src_ip,send_info.dst_ip,recv_info.src_port,send_info.dst_port); + return -1; + } + if(data_len=0&&type=='h') + { + mylog(log_debug,"[hb]heart beat received,oppsite_roller=%d\n",int(conn_info.oppsite_roller)); + conn_info.last_hb_recv_time=get_current_time(); + return 0; + } + else if(data_len>= int( sizeof(u32_t))&&type=='d') + { + mylog(log_trace,"received a data from fake tcp,len:%d\n",data_len); + + if(hb_mode==0) + conn_info.last_hb_recv_time=get_current_time(); + + u32_t tmp_conv_id; + memcpy(&tmp_conv_id,&data[0],sizeof(tmp_conv_id)); + tmp_conv_id=ntohl(tmp_conv_id); + + if(!conn_info.blob->conv_manager.c.is_conv_used(tmp_conv_id)) + { + mylog(log_info,"unknow conv %d,ignore\n",tmp_conv_id); + return 0; + } + + conn_info.blob->conv_manager.c.update_active_time(tmp_conv_id); + + //u64_t u64=conn_info.blob->conv_manager.c.find_dat_by_conv(tmp_conv_id); + address_t addr=conn_info.blob->conv_manager.c.find_data_by_conv(tmp_conv_id); + + //sockaddr_in tmp_sockaddr={0}; + + //tmp_sockaddr.sin_family = AF_INET; + //tmp_sockaddr.sin_addr.s_addr=(u64>>32u); + + //tmp_sockaddr.sin_port= htons(uint16_t((u64<<32u)>>32u)); + + + int ret=sendto(udp_fd,data+sizeof(u32_t),data_len -(sizeof(u32_t)),0,(struct sockaddr *)&addr.inner,addr.get_len()); + + if(ret<0) + { + mylog(log_warn,"sento returned %d\n",ret); + + } + //mylog(log_trace,"%s :%d\n",inet_ntoa(tmp_sockaddr.sin_addr),ntohs(tmp_sockaddr.sin_port)); + //mylog(log_trace,"%d byte sent\n",ret); + } + else + { + mylog(log_warn,"unknown packet,this shouldnt happen.\n"); + return -1; + } + + return 0; + } + else + { + mylog(log_fatal,"unknown state,this shouldnt happen.\n"); + myexit(-1); + } + return 0; +} + +void udp_accept_cb(struct ev_loop *loop, struct ev_io *watcher, int revents) +{ + char buf[buf_len]; + + conn_info_t & conn_info= *((conn_info_t*)watcher->data);; + + int recv_len; + address_t addr; + + address_t::storage_t udp_new_addr_in={0}; + socklen_t udp_new_addr_len = sizeof(address_t::storage_t); + if ((recv_len = recvfrom(udp_fd, buf, max_data_len, 0, + (struct sockaddr *) &udp_new_addr_in, &udp_new_addr_len)) == -1) { + mylog(log_debug,"recv_from error,this shouldnt happen,err=%s,but we can try to continue\n",get_sock_error()); + return; + }; + + if(recv_len==max_data_len+1) + { + mylog(log_warn,"huge packet, data_len > %d,dropped\n",max_data_len); + return; + } + + if(recv_len>=mtu_warn) + { + mylog(log_warn,"huge packet,data len=%d (>=%d).strongly suggested to set a smaller mtu at upper level,to get rid of this warn\n ",recv_len,mtu_warn); + } + //mylog(log_trace,"Received packet from %s:%d,len: %d\n", inet_ntoa(udp_new_addr_in.sin_addr), + //ntohs(udp_new_addr_in.sin_port),recv_len); + + addr.from_sockaddr((struct sockaddr *) &udp_new_addr_in,udp_new_addr_len); + + //u64_t u64=((u64_t(udp_new_addr_in.sin_addr.s_addr))<<32u)+ntohs(udp_new_addr_in.sin_port); + u32_t conv; + + if(!conn_info.blob->conv_manager.c.is_data_used(addr)) + { + if(conn_info.blob->conv_manager.c.get_size() >=max_conv_num) + { + mylog(log_warn,"ignored new udp connect bc max_conv_num exceed\n"); + return; + } + conv=conn_info.blob->conv_manager.c.get_new_conv(); + conn_info.blob->conv_manager.c.insert_conv(conv,addr); + //mylog(log_info,"new packet from %s:%d,conv_id=%x\n",inet_ntoa(udp_new_addr_in.sin_addr),ntohs(udp_new_addr_in.sin_port),conv); + mylog(log_info,"new packet from %s,conv_id=%x\n",addr.get_str(),conv); + } + else + { + conv=conn_info.blob->conv_manager.c.find_conv_by_data(addr); + } + + conn_info.blob->conv_manager.c.update_active_time(conv); + + if(conn_info.state.client_current_state==client_ready) + { + send_data_safer(conn_info,buf,recv_len,conv); + } + +} + +void raw_recv_cb(struct ev_loop *loop, struct ev_io *watcher, int revents) +{ + assert(0==1); + conn_info_t & conn_info= *((conn_info_t*)watcher->data); + client_on_raw_recv(conn_info); +} +void async_cb(struct ev_loop *loop, struct ev_async *watcher, int revents) +{ + conn_info_t & conn_info= *((conn_info_t*)watcher->data); + + if(send_with_pcap&&!pcap_header_captured) + { + int empty=0;char *p;int len; + pthread_mutex_lock(&queue_mutex); + empty=my_queue.empty(); + if(!empty) + { + my_queue.peek_front(p,len); + my_queue.pop_front(); + } + pthread_mutex_unlock(&queue_mutex); + if(empty) return; + + pcap_header_captured=1; + assert(pcap_link_header_len!=-1); + memcpy(pcap_header_buf,p,max_data_len); + + log_bare(log_info,"link level header captured:\n"); + unsigned char *tmp=(unsigned char*)pcap_header_buf; + pcap_captured_full_len=len; + for(int i=0;i",(u32_t)tmp[i]); + + log_bare(log_info,"\n"); + return ; + } + + //mylog(log_info,"async_cb called\n"); + while(1) + { + int empty=0;char *p;int len; + pthread_mutex_lock(&queue_mutex); + empty=my_queue.empty(); + if(!empty) + { + my_queue.peek_front(p,len); + my_queue.pop_front(); + } + pthread_mutex_unlock(&queue_mutex); + + if(empty) break; + + int new_len=len-pcap_link_header_len; + memcpy(g_packet_buf,p+pcap_link_header_len,new_len); + g_packet_buf_len=new_len; + assert(g_packet_buf_cnt==0); + g_packet_buf_cnt++; + client_on_raw_recv(conn_info); + } +} +void clear_timer_cb(struct ev_loop *loop, struct ev_timer *watcher, int revents) +{ + conn_info_t & conn_info= *((conn_info_t*)watcher->data); + //u64_t value; + //read(timer_fd, &value, 8); + client_on_timer(conn_info); + mylog(log_trace,"epoll_trigger_counter: %d \n",epoll_trigger_counter); + epoll_trigger_counter=0; +} + +void fifo_cb(struct ev_loop *loop, struct ev_io *watcher, int revents) +{ + conn_info_t & conn_info= *((conn_info_t*)watcher->data); + + char buf[buf_len]; + int fifo_fd=watcher->fd; + + int len=read (fifo_fd, buf, sizeof (buf)); + if(len<0) + { + mylog(log_warn,"fifo read failed len=%d,errno=%s\n",len,get_sock_error()); + return; + } + buf[len]=0; + while(len>=1&&buf[len-1]=='\n') + buf[len-1]=0; + mylog(log_info,"got data from fifo,len=%d,s=[%s]\n",len,buf); + if(strcmp(buf,"reconnect")==0) + { + mylog(log_info,"received command: reconnect\n"); + conn_info.state.client_current_state=client_idle; + conn_info.my_id=get_true_random_number_nz(); + } + else + { + mylog(log_info,"unknown command\n"); + } + +} + +int client_event_loop() +{ + char buf[buf_len]; + + conn_info_t conn_info; + conn_info.my_id=get_true_random_number_nz(); + + conn_info.prepare(); + packet_info_t &send_info=conn_info.raw_info.send_info; + packet_info_t &recv_info=conn_info.raw_info.recv_info; + + if(source_ip_uint32==0) + { + mylog(log_info,"get_src_adress called\n"); + if(retry_on_error==0) + { + if(get_src_adress(source_ip_uint32,remote_ip_uint32,remote_port)!=0) + { + mylog(log_fatal,"the trick to auto get source ip failed, maybe you dont have internet access\n"); + myexit(-1); + } + } + else + { + int ok=0; + while(!ok) + { + if(get_src_adress(source_ip_uint32,remote_ip_uint32,remote_port)!=0) + { + mylog(log_warn,"the trick to auto get source ip failed, maybe you dont have internet access, retry in %d seconds\n",retry_on_error_interval); + sleep(retry_on_error_interval); + } + else + { + ok=1; + } + + } + } + + } + //in_addr tmp; + //tmp.s_addr=source_ip_uint32; + mylog(log_info,"source ip = %s\n",my_ntoa(source_ip_uint32)); + //printf("done\n"); + + if(strcmp(dev,"")==0) + { + mylog(log_info,"--dev have not been set, trying to detect automatically, avaliable deives:\n"); + + mylog(log_info,"avaliable deives(device name: ip address ; description):\n"); + + char errbuf[PCAP_ERRBUF_SIZE]; + + int found=0; + + pcap_if_t *interfaces,*d; + if(pcap_findalldevs(&interfaces,errbuf)==-1) + { + mylog(log_fatal,"error in pcap_findalldevs(),%s\n",errbuf); + myexit(-1); + } + + for(pcap_if_t *d=interfaces; d!=NULL; d=d->next) { + log_bare(log_warn,"%s:", d->name); + int cnt=0; + for(pcap_addr_t *a=d->addresses; a!=NULL; a=a->next) { + if(a->addr==NULL) + { + log_bare(log_debug," [a->addr==NULL]"); + continue; + } + if(a->addr->sa_family == AF_INET) + { + cnt++; + log_bare(log_warn," [%s]", inet_ntoa(((struct sockaddr_in*)a->addr)->sin_addr)); + + if(((struct sockaddr_in*)a->addr)->sin_addr.s_addr ==source_ip_uint32) + { + found++; + strcpy(dev,d->name); + } + } + else + { + log_bare(log_debug," [unknow:%d]",int(a->addr->sa_family)); + } + } + if(cnt==0) log_bare(log_warn," [no ip found]"); + if(d->description==0) + { + log_bare(log_warn,"; (no description avaliable)"); + } + else + { + log_bare(log_warn,"; %s", d->description); + } + log_bare(log_warn,"\n"); + } + + if(found==0) + { + mylog(log_fatal,"no matched device found for ip: [%s]\n",my_ntoa(source_ip_uint32)); + myexit(-1); + } + else if(found==1) + { + mylog(log_info,"using device:[%s], ip: [%s]\n",dev,my_ntoa(source_ip_uint32)); + } + else + { + mylog(log_fatal,"more than one devices found for ip: [%s] , you need to use --dev manually\n",my_ntoa(source_ip_uint32)); + myexit(-1); + } + } + else + { + mylog(log_info,"--dev has been manually set, using device:[%s]\n",dev); + } + + + if(try_to_list_and_bind(bind_fd,local_ip_uint32,source_port)!=0) + { + mylog(log_fatal,"bind to source_port:%d fail\n ",source_port); + myexit(-1); + } + send_info.src_port=source_port; + send_info.src_ip = source_ip_uint32; + + int i, j, k;int ret; + + + send_info.dst_ip=remote_ip_uint32; + send_info.dst_port=remote_port; + + + udp_fd=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + set_buf_size(udp_fd,socket_buf_size); + + int yes = 1; + + struct sockaddr_in local_me={0}; + + socklen_t slen = sizeof(sockaddr_in); + local_me.sin_family = AF_INET; + local_me.sin_port = htons(local_port); + local_me.sin_addr.s_addr = local_ip_uint32; + + + if (::bind(udp_fd, (struct sockaddr*) &local_me, slen) == -1) { + mylog(log_fatal,"socket bind error\n"); + myexit(1); + } + setnonblocking(udp_fd); + + //epollfd = epoll_create1(0); + + //const int max_events = 4096; + //struct epoll_event ev, events[max_events]; + //if (epollfd < 0) { + // mylog(log_fatal,"epoll return %d\n", epollfd); + // myexit(-1); + //} + + struct ev_loop * loop= ev_default_loop(0); + assert(loop != NULL); + + //ev.events = EPOLLIN; + //ev.data.u64 = udp_fd; + //ret = epoll_ctl(epollfd, EPOLL_CTL_ADD, udp_fd, &ev); + //if (ret!=0) { + // mylog(log_fatal,"add udp_listen_fd error\n"); + // myexit(-1); + //} + + + struct ev_io udp_accept_watcher; + + udp_accept_watcher.data=&conn_info; + ev_io_init(&udp_accept_watcher, udp_accept_cb, udp_fd, EV_READ); + ev_io_start(loop, &udp_accept_watcher); + + + //ev.events = EPOLLIN; + //ev.data.u64 = raw_recv_fd; + + //ret = epoll_ctl(epollfd, EPOLL_CTL_ADD, raw_recv_fd, &ev); + //if (ret!= 0) { + // mylog(log_fatal,"add raw_fd error\n"); + // myexit(-1); + //} + + //struct ev_io raw_watcher; + + //raw_watcher.data=&conn_info; + // ev_io_init(&raw_watcher, raw_recv_cb, raw_recv_fd, EV_READ); + //ev_io_start(loop, &raw_watcher); + + g_default_loop=loop; + async_watcher.data=&conn_info; + ev_async_init(&async_watcher,async_cb); + ev_async_start(loop,&async_watcher); + + init_raw_socket(); + + + + int unbind=1; + + //set_timer(epollfd,timer_fd); + + struct ev_timer clear_timer; + + clear_timer.data=&conn_info; + ev_timer_init(&clear_timer, clear_timer_cb, 0, timer_interval/1000.0); + ev_timer_start(loop, &clear_timer); + + mylog(log_debug,"send_raw : from %x %d to %x %d\n",send_info.src_ip,send_info.src_port,send_info.dst_ip,send_info.dst_port); + + int fifo_fd=-1; + + struct ev_io fifo_watcher; + fifo_watcher.data=&conn_info; + + if(fifo_file[0]!=0) + { + fifo_fd=create_fifo(fifo_file); + + ev_io_init(&fifo_watcher, fifo_cb, fifo_fd, EV_READ); + ev_io_start(loop, &fifo_watcher); + + mylog(log_info,"fifo_file=%s\n",fifo_file); + } + + ev_run(loop, 0); + return 0; +} diff --git a/main.cpp b/main.cpp index 1991b6b..8e88c1e 100755 --- a/main.cpp +++ b/main.cpp @@ -7,984 +7,6 @@ #include "encrypt.h" #include "fd_manager.h" - -char hb_buf[buf_len]; - -int on_epoll_recv_event=0; //TODO, just a flag to help detect epoll infinite shoot - - -u32_t detect_interval=1500; -u64_t laste_detect_time=0; - -int use_udp_for_detection=0; -int use_tcp_for_detection=1; - - -extern pcap_t *pcap_handle; - -extern int pcap_captured_full_len; - -int client_on_timer(conn_info_t &conn_info) //for client. called when a timer is ready in epoll -{ - 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; - conn_info.blob->conv_manager.c.clear_inactive(); - mylog(log_trace,"timer!\n"); - - mylog(log_trace,"roller my %d,oppsite %d,%lld\n",int(conn_info.my_roller),int(conn_info.oppsite_roller),conn_info.last_oppsite_roller_time); - - mylog(log_trace,"\n",send_info.ts_ack); - - - //mylog(log_debug,"pcap cnt :%d\n",pcap_cnt); - if(send_with_pcap&&!pcap_header_captured) - { - - if(get_current_time()-laste_detect_time>detect_interval) - { - laste_detect_time=get_current_time(); - } - else - { - return 0; - } - - struct sockaddr_in remote_addr_in={0}; - - socklen_t slen = sizeof(sockaddr_in); - //memset(&remote_addr_in, 0, sizeof(remote_addr_in)); - int port=get_true_random_number()%65534+1; - remote_addr_in.sin_family = AF_INET; - remote_addr_in.sin_port = htons(port); - remote_addr_in.sin_addr.s_addr = remote_ip_uint32; - - if(use_udp_for_detection) - { - int new_udp_fd=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - if(new_udp_fd<0) - { - mylog(log_warn,"create new_udp_fd error\n"); - return -1; - } - setnonblocking(new_udp_fd); - u64_t tmp=get_true_random_number(); - - int ret=sendto(new_udp_fd,(char*)(&tmp),sizeof(tmp),0,(struct sockaddr *)&remote_addr_in,sizeof(remote_addr_in)); - if(ret==-1) - { - mylog(log_warn,"sendto() failed\n"); - } - sock_close(new_udp_fd); - } - - if(use_tcp_for_detection) - { - static int last_tcp_fd=-1; - - int new_tcp_fd=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - if(new_tcp_fd<0) - { - mylog(log_warn,"create new_tcp_fd error\n"); - return -1; - } - setnonblocking(new_tcp_fd); - connect(new_tcp_fd,(struct sockaddr *)&remote_addr_in,sizeof(remote_addr_in)); - if(last_tcp_fd!=-1) - sock_close(last_tcp_fd); - last_tcp_fd=new_tcp_fd; - //close(new_tcp_fd); - } - - - - mylog(log_info,"waiting for a use-able packet to be captured\n"); - - return 0; - } - - if(raw_info.disabled) - { - conn_info.state.client_current_state=client_idle; - conn_info.my_id=get_true_random_number_nz(); - - mylog(log_info,"state back to client_idle\n"); - } - - if(conn_info.state.client_current_state==client_idle) - { - raw_info.rst_received=0; - raw_info.disabled=0; - - fail_time_counter++; - if(max_fail_time>0&&fail_time_counter>max_fail_time) - { - mylog(log_fatal,"max_fail_time exceed\n"); - myexit(-1); - } - - conn_info.blob->anti_replay.re_init(); - conn_info.my_id = get_true_random_number_nz(); ///todo no need to do this everytime - - - - u32_t new_ip=0; - if(!force_source_ip&&get_src_adress(new_ip,remote_ip_uint32,remote_port)==0) - { - if(new_ip!=source_ip_uint32) - { - mylog(log_info,"source ip changed from %s to ",my_ntoa(source_ip_uint32)); - log_bare(log_info,"%s\n",my_ntoa(new_ip)); - source_ip_uint32=new_ip; - send_info.src_ip=new_ip; - } - } - - if (source_port == 0) - { - send_info.src_port = client_bind_to_a_new_port(bind_fd,0); - } - else - { - send_info.src_port = source_port; - assert(try_to_list_and_bind(bind_fd,0,source_port)==0); - } - - - if (raw_mode == mode_icmp) - { - send_info.dst_port = send_info.src_port; - } - - mylog(log_info, "using port %d\n", send_info.src_port); - init_filter(send_info.src_port); - - if(raw_mode==mode_icmp||raw_mode==mode_udp) - { - conn_info.state.client_current_state=client_handshake1; - - mylog(log_info,"state changed from client_idle to client_pre_handshake\n"); - } - if(raw_mode==mode_faketcp) - { - if(use_tcp_dummy_socket) - { - - struct sockaddr_in remote_addr_in={0}; - socklen_t slen = sizeof(sockaddr_in); - //memset(&remote_addr_in, 0, sizeof(remote_addr_in)); - remote_addr_in.sin_family = AF_INET; - remote_addr_in.sin_port = htons(remote_port); - remote_addr_in.sin_addr.s_addr = remote_ip_uint32; - - //int new_tcp_fd=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - - setnonblocking(bind_fd); - int ret=connect(bind_fd,(struct sockaddr *)&remote_addr_in,sizeof(remote_addr_in)); - mylog(log_info,"ret=%d,errno=%s,%d %d\n",ret,get_sock_error(),bind_fd,remote_port); - conn_info.state.client_current_state=client_tcp_handshake_dummy; - mylog(log_info,"state changed from client_idle to client_tcp_handshake_dummy\n"); - } - else - { - - conn_info.state.client_current_state=client_tcp_handshake; - mylog(log_info,"state changed from client_idle to client_tcp_handshake\n"); - } - - } - conn_info.last_state_time=get_current_time(); - conn_info.last_hb_sent_time=0; - //dont return; - } - if(conn_info.state.client_current_state==client_tcp_handshake) //send and resend syn - { - assert(raw_mode==mode_faketcp); - if (get_current_time() - conn_info.last_state_time > client_handshake_timeout) - { - conn_info.state.client_current_state = client_idle; - mylog(log_info, "state back to client_idle from client_tcp_handshake\n"); - return 0; - - } - else if (get_current_time() - conn_info.last_hb_sent_time > client_retry_interval) - { - - if (raw_mode == mode_faketcp) - { - if (conn_info.last_hb_sent_time == 0) - { - send_info.psh = 0; - send_info.syn = 1; - send_info.ack = 0; - send_info.ts_ack =0; - send_info.seq=get_true_random_number(); - send_info.ack_seq=get_true_random_number(); - } - } - - send_raw0(raw_info, 0, 0); - - conn_info.last_hb_sent_time = get_current_time(); - mylog(log_info, "(re)sent tcp syn\n"); - return 0; - } - else - { - return 0; - } - return 0; - } - else if(conn_info.state.client_current_state==client_tcp_handshake_dummy) - { - assert(raw_mode==mode_faketcp); - if (get_current_time() - conn_info.last_state_time > client_handshake_timeout) - { - conn_info.state.client_current_state = client_idle; - mylog(log_info, "state back to client_idle from client_tcp_handshake_dummy\n"); - return 0; - - } - } - else if(conn_info.state.client_current_state==client_handshake1)//send and resend handshake1 - { - if(get_current_time()-conn_info.last_state_time>client_handshake_timeout) - { - conn_info.state.client_current_state=client_idle; - mylog(log_info,"state back to client_idle from client_handshake1\n"); - return 0; - - } - else if(get_current_time()-conn_info.last_hb_sent_time>client_retry_interval) - { - - if(raw_mode==mode_faketcp) - { - if(conn_info.last_hb_sent_time==0) - { - send_info.seq++; - send_info.ack_seq=recv_info.seq+1; - send_info.ts_ack=recv_info.ts; - raw_info.reserved_send_seq=send_info.seq; - } - send_info.seq=raw_info.reserved_send_seq; - send_info.psh = 0; - send_info.syn = 0; - send_info.ack = 1; - - if(!use_tcp_dummy_socket) - send_raw0(raw_info, 0, 0); - - send_handshake(raw_info,conn_info.my_id,0,const_id); - - send_info.seq+=raw_info.send_info.data_len; - } - else - { - - send_handshake(raw_info,conn_info.my_id,0,const_id); - if(raw_mode==mode_icmp) - send_info.my_icmp_seq++; - } - - conn_info.last_hb_sent_time=get_current_time(); - mylog(log_info,"(re)sent handshake1\n"); - return 0; - } - else - { - return 0; - } - return 0; - } - else if(conn_info.state.client_current_state==client_handshake2) - { - if(get_current_time()-conn_info.last_state_time>client_handshake_timeout) - { - conn_info.state.client_current_state=client_idle; - mylog(log_info,"state back to client_idle from client_handshake2\n"); - return 0; - } - else if(get_current_time()-conn_info.last_hb_sent_time>client_retry_interval) - { - if(raw_mode==mode_faketcp) - { - if(conn_info.last_hb_sent_time==0) - { - send_info.ack_seq=recv_info.seq+raw_info.recv_info.data_len; - send_info.ts_ack=recv_info.ts; - raw_info.reserved_send_seq=send_info.seq; - } - send_info.seq=raw_info.reserved_send_seq; - send_handshake(raw_info,conn_info.my_id,conn_info.oppsite_id,const_id); - send_info.seq+=raw_info.send_info.data_len; - - } - else - { - - send_handshake(raw_info,conn_info.my_id,conn_info.oppsite_id,const_id); - if(raw_mode==mode_icmp) - send_info.my_icmp_seq++; - } - conn_info.last_hb_sent_time=get_current_time(); - mylog(log_info,"(re)sent handshake2\n"); - return 0; - - } - else - { - return 0; - } - return 0; - } - else if(conn_info.state.client_current_state==client_ready) - { - fail_time_counter=0; - mylog(log_trace,"time %llu,%llu\n",get_current_time(),conn_info.last_state_time); - - if(get_current_time()-conn_info.last_hb_recv_time>client_conn_timeout) - { - conn_info.state.client_current_state=client_idle; - conn_info.my_id=get_true_random_number_nz(); - mylog(log_info,"state back to client_idle from client_ready bc of server-->client direction timeout\n"); - return 0; - } - - if(get_current_time()- conn_info.last_oppsite_roller_time>client_conn_uplink_timeout) - { - conn_info.state.client_current_state=client_idle; - conn_info.my_id=get_true_random_number_nz(); - mylog(log_info,"state back to client_idle from client_ready bc of client-->server direction timeout\n"); - } - - - if(get_current_time()-conn_info.last_hb_sent_time\n",conn_info.oppsite_id,conn_info.my_id); - - if(hb_mode==0) - send_safer(conn_info,'h',hb_buf,0);/////////////send - else - send_safer(conn_info,'h',hb_buf,hb_len); - conn_info.last_hb_sent_time=get_current_time(); - return 0; - } - else - { - mylog(log_fatal,"unknown state,this shouldnt happen.\n"); - myexit(-1); - } - return 0; -} -int client_on_raw_recv(conn_info_t &conn_info) //called when raw fd received a packet. -{ - char* data;int data_len; - 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; - - mylog(log_trace,"\n",send_info.ts_ack); - - if(conn_info.state.client_current_state==client_idle ) - { - g_packet_buf_cnt--; - //recv(raw_recv_fd, 0,0, 0 ); - //pthread_mutex_lock(&queue_mutex); - //my_queue.pop_front(); - //pthread_mutex_unlock(&queue_mutex); - } - else if(conn_info.state.client_current_state==client_tcp_handshake||conn_info.state.client_current_state==client_tcp_handshake_dummy)//received syn ack - { - assert(raw_mode==mode_faketcp); - if(recv_raw0(raw_info,data,data_len)<0) - { - return -1; - } - if(recv_info.src_ip!=send_info.dst_ip||recv_info.src_port!=send_info.dst_port) - { - mylog(log_debug,"unexpected adress %x %x %d %d\n",recv_info.src_ip,send_info.dst_ip,recv_info.src_port,send_info.dst_port); - return -1; - } - if(data_len==0&&raw_info.recv_info.syn==1&&raw_info.recv_info.ack==1) - { - if(conn_info.state.client_current_state==client_tcp_handshake) - { - if(recv_info.ack_seq!=send_info.seq+1) - { - mylog(log_debug,"seq ack_seq mis match\n"); - return -1; - } - mylog(log_info,"state changed from client_tcp_handshake to client_handshake1\n"); - } - else - { - send_info.seq=recv_info.ack_seq-1; - mylog(log_info,"state changed from client_tcp_dummy to client_handshake1\n"); - //send_info.ack_seq=recv_info.seq+1; - } - conn_info.state.client_current_state = client_handshake1; - - conn_info.last_state_time = get_current_time(); - conn_info.last_hb_sent_time=0; - client_on_timer(conn_info); - return 0; - } - else - { - mylog(log_debug,"unexpected packet type,expected:syn ack\n"); - return -1; - } - } - else if(conn_info.state.client_current_state==client_handshake1)//recevied respond of handshake1 - { - if(recv_bare(raw_info,data,data_len)!=0) - { - mylog(log_debug,"recv_bare failed!\n"); - return -1; - } - if(recv_info.src_ip!=send_info.dst_ip||recv_info.src_port!=send_info.dst_port) - { - mylog(log_debug,"unexpected adress %x %x %d %d\n",recv_info.src_ip,send_info.dst_ip,recv_info.src_port,send_info.dst_port); - return -1; - } - if(data_len=0&&type=='h') - { - mylog(log_debug,"[hb]heart beat received,oppsite_roller=%d\n",int(conn_info.oppsite_roller)); - conn_info.last_hb_recv_time=get_current_time(); - return 0; - } - else if(data_len>= int( sizeof(u32_t))&&type=='d') - { - mylog(log_trace,"received a data from fake tcp,len:%d\n",data_len); - - if(hb_mode==0) - conn_info.last_hb_recv_time=get_current_time(); - - u32_t tmp_conv_id; - memcpy(&tmp_conv_id,&data[0],sizeof(tmp_conv_id)); - tmp_conv_id=ntohl(tmp_conv_id); - - if(!conn_info.blob->conv_manager.c.is_conv_used(tmp_conv_id)) - { - mylog(log_info,"unknow conv %d,ignore\n",tmp_conv_id); - return 0; - } - - conn_info.blob->conv_manager.c.update_active_time(tmp_conv_id); - - //u64_t u64=conn_info.blob->conv_manager.c.find_dat_by_conv(tmp_conv_id); - address_t addr=conn_info.blob->conv_manager.c.find_data_by_conv(tmp_conv_id); - - //sockaddr_in tmp_sockaddr={0}; - - //tmp_sockaddr.sin_family = AF_INET; - //tmp_sockaddr.sin_addr.s_addr=(u64>>32u); - - //tmp_sockaddr.sin_port= htons(uint16_t((u64<<32u)>>32u)); - - - int ret=sendto(udp_fd,data+sizeof(u32_t),data_len -(sizeof(u32_t)),0,(struct sockaddr *)&addr.inner,addr.get_len()); - - if(ret<0) - { - mylog(log_warn,"sento returned %d\n",ret); - - } - //mylog(log_trace,"%s :%d\n",inet_ntoa(tmp_sockaddr.sin_addr),ntohs(tmp_sockaddr.sin_port)); - //mylog(log_trace,"%d byte sent\n",ret); - } - else - { - mylog(log_warn,"unknown packet,this shouldnt happen.\n"); - return -1; - } - - return 0; - } - else - { - mylog(log_fatal,"unknown state,this shouldnt happen.\n"); - myexit(-1); - } - return 0; -} - -void udp_accept_cb(struct ev_loop *loop, struct ev_io *watcher, int revents) -{ - char buf[buf_len]; - - conn_info_t & conn_info= *((conn_info_t*)watcher->data);; - - int recv_len; - address_t addr; - - address_t::storage_t udp_new_addr_in={0}; - socklen_t udp_new_addr_len = sizeof(address_t::storage_t); - if ((recv_len = recvfrom(udp_fd, buf, max_data_len, 0, - (struct sockaddr *) &udp_new_addr_in, &udp_new_addr_len)) == -1) { - mylog(log_debug,"recv_from error,this shouldnt happen,err=%s,but we can try to continue\n",get_sock_error()); - return; - }; - - if(recv_len==max_data_len+1) - { - mylog(log_warn,"huge packet, data_len > %d,dropped\n",max_data_len); - return; - } - - if(recv_len>=mtu_warn) - { - mylog(log_warn,"huge packet,data len=%d (>=%d).strongly suggested to set a smaller mtu at upper level,to get rid of this warn\n ",recv_len,mtu_warn); - } - //mylog(log_trace,"Received packet from %s:%d,len: %d\n", inet_ntoa(udp_new_addr_in.sin_addr), - //ntohs(udp_new_addr_in.sin_port),recv_len); - - addr.from_sockaddr((struct sockaddr *) &udp_new_addr_in,udp_new_addr_len); - - //u64_t u64=((u64_t(udp_new_addr_in.sin_addr.s_addr))<<32u)+ntohs(udp_new_addr_in.sin_port); - u32_t conv; - - if(!conn_info.blob->conv_manager.c.is_data_used(addr)) - { - if(conn_info.blob->conv_manager.c.get_size() >=max_conv_num) - { - mylog(log_warn,"ignored new udp connect bc max_conv_num exceed\n"); - return; - } - conv=conn_info.blob->conv_manager.c.get_new_conv(); - conn_info.blob->conv_manager.c.insert_conv(conv,addr); - //mylog(log_info,"new packet from %s:%d,conv_id=%x\n",inet_ntoa(udp_new_addr_in.sin_addr),ntohs(udp_new_addr_in.sin_port),conv); - mylog(log_info,"new packet from %s,conv_id=%x\n",addr.get_str(),conv); - } - else - { - conv=conn_info.blob->conv_manager.c.find_conv_by_data(addr); - } - - conn_info.blob->conv_manager.c.update_active_time(conv); - - if(conn_info.state.client_current_state==client_ready) - { - send_data_safer(conn_info,buf,recv_len,conv); - } - -} - -void raw_recv_cb(struct ev_loop *loop, struct ev_io *watcher, int revents) -{ - assert(0==1); - conn_info_t & conn_info= *((conn_info_t*)watcher->data); - client_on_raw_recv(conn_info); -} -void async_cb(struct ev_loop *loop, struct ev_async *watcher, int revents) -{ - conn_info_t & conn_info= *((conn_info_t*)watcher->data); - - if(send_with_pcap&&!pcap_header_captured) - { - int empty=0;char *p;int len; - pthread_mutex_lock(&queue_mutex); - empty=my_queue.empty(); - if(!empty) - { - my_queue.peek_front(p,len); - my_queue.pop_front(); - } - pthread_mutex_unlock(&queue_mutex); - if(empty) return; - - pcap_header_captured=1; - assert(pcap_link_header_len!=-1); - memcpy(pcap_header_buf,p,max_data_len); - - log_bare(log_info,"link level header captured:\n"); - unsigned char *tmp=(unsigned char*)pcap_header_buf; - pcap_captured_full_len=len; - for(int i=0;i",(u32_t)tmp[i]); - - log_bare(log_info,"\n"); - return ; - } - - //mylog(log_info,"async_cb called\n"); - while(1) - { - int empty=0;char *p;int len; - pthread_mutex_lock(&queue_mutex); - empty=my_queue.empty(); - if(!empty) - { - my_queue.peek_front(p,len); - my_queue.pop_front(); - } - pthread_mutex_unlock(&queue_mutex); - - if(empty) break; - - int new_len=len-pcap_link_header_len; - memcpy(g_packet_buf,p+pcap_link_header_len,new_len); - g_packet_buf_len=new_len; - assert(g_packet_buf_cnt==0); - g_packet_buf_cnt++; - client_on_raw_recv(conn_info); - } -} -void clear_timer_cb(struct ev_loop *loop, struct ev_timer *watcher, int revents) -{ - conn_info_t & conn_info= *((conn_info_t*)watcher->data); - //u64_t value; - //read(timer_fd, &value, 8); - client_on_timer(conn_info); - mylog(log_trace,"epoll_trigger_counter: %d \n",epoll_trigger_counter); - epoll_trigger_counter=0; -} - -void fifo_cb(struct ev_loop *loop, struct ev_io *watcher, int revents) -{ - conn_info_t & conn_info= *((conn_info_t*)watcher->data); - - char buf[buf_len]; - int fifo_fd=watcher->fd; - - int len=read (fifo_fd, buf, sizeof (buf)); - if(len<0) - { - mylog(log_warn,"fifo read failed len=%d,errno=%s\n",len,get_sock_error()); - return; - } - buf[len]=0; - while(len>=1&&buf[len-1]=='\n') - buf[len-1]=0; - mylog(log_info,"got data from fifo,len=%d,s=[%s]\n",len,buf); - if(strcmp(buf,"reconnect")==0) - { - mylog(log_info,"received command: reconnect\n"); - conn_info.state.client_current_state=client_idle; - conn_info.my_id=get_true_random_number_nz(); - } - else - { - mylog(log_info,"unknown command\n"); - } - -} - -int client_event_loop() -{ - char buf[buf_len]; - - conn_info_t conn_info; - conn_info.my_id=get_true_random_number_nz(); - - conn_info.prepare(); - packet_info_t &send_info=conn_info.raw_info.send_info; - packet_info_t &recv_info=conn_info.raw_info.recv_info; - - if(source_ip_uint32==0) - { - mylog(log_info,"get_src_adress called\n"); - if(retry_on_error==0) - { - if(get_src_adress(source_ip_uint32,remote_ip_uint32,remote_port)!=0) - { - mylog(log_fatal,"the trick to auto get source ip failed, maybe you dont have internet access\n"); - myexit(-1); - } - } - else - { - int ok=0; - while(!ok) - { - if(get_src_adress(source_ip_uint32,remote_ip_uint32,remote_port)!=0) - { - mylog(log_warn,"the trick to auto get source ip failed, maybe you dont have internet access, retry in %d seconds\n",retry_on_error_interval); - sleep(retry_on_error_interval); - } - else - { - ok=1; - } - - } - } - - } - //in_addr tmp; - //tmp.s_addr=source_ip_uint32; - mylog(log_info,"source ip = %s\n",my_ntoa(source_ip_uint32)); - //printf("done\n"); - - if(strcmp(dev,"")==0) - { - mylog(log_info,"--dev have not been set, trying to detect automatically, avaliable deives:\n"); - - mylog(log_info,"avaliable deives(device name: ip address ; description):\n"); - - char errbuf[PCAP_ERRBUF_SIZE]; - - int found=0; - - pcap_if_t *interfaces,*d; - if(pcap_findalldevs(&interfaces,errbuf)==-1) - { - mylog(log_fatal,"error in pcap_findalldevs(),%s\n",errbuf); - myexit(-1); - } - - for(pcap_if_t *d=interfaces; d!=NULL; d=d->next) { - log_bare(log_warn,"%s:", d->name); - int cnt=0; - for(pcap_addr_t *a=d->addresses; a!=NULL; a=a->next) { - if(a->addr==NULL) - { - log_bare(log_debug," [a->addr==NULL]"); - continue; - } - if(a->addr->sa_family == AF_INET) - { - cnt++; - log_bare(log_warn," [%s]", inet_ntoa(((struct sockaddr_in*)a->addr)->sin_addr)); - - if(((struct sockaddr_in*)a->addr)->sin_addr.s_addr ==source_ip_uint32) - { - found++; - strcpy(dev,d->name); - } - } - else - { - log_bare(log_debug," [unknow:%d]",int(a->addr->sa_family)); - } - } - if(cnt==0) log_bare(log_warn," [no ip found]"); - if(d->description==0) - { - log_bare(log_warn,"; (no description avaliable)"); - } - else - { - log_bare(log_warn,"; %s", d->description); - } - log_bare(log_warn,"\n"); - } - - if(found==0) - { - mylog(log_fatal,"no matched device found for ip: [%s]\n",my_ntoa(source_ip_uint32)); - myexit(-1); - } - else if(found==1) - { - mylog(log_info,"using device:[%s], ip: [%s]\n",dev,my_ntoa(source_ip_uint32)); - } - else - { - mylog(log_fatal,"more than one devices found for ip: [%s] , you need to use --dev manually\n",my_ntoa(source_ip_uint32)); - myexit(-1); - } - } - else - { - mylog(log_info,"--dev has been manually set, using device:[%s]\n",dev); - } - - - if(try_to_list_and_bind(bind_fd,local_ip_uint32,source_port)!=0) - { - mylog(log_fatal,"bind to source_port:%d fail\n ",source_port); - myexit(-1); - } - send_info.src_port=source_port; - send_info.src_ip = source_ip_uint32; - - int i, j, k;int ret; - - - send_info.dst_ip=remote_ip_uint32; - send_info.dst_port=remote_port; - - - udp_fd=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - set_buf_size(udp_fd,socket_buf_size); - - int yes = 1; - - struct sockaddr_in local_me={0}; - - socklen_t slen = sizeof(sockaddr_in); - local_me.sin_family = AF_INET; - local_me.sin_port = htons(local_port); - local_me.sin_addr.s_addr = local_ip_uint32; - - - if (::bind(udp_fd, (struct sockaddr*) &local_me, slen) == -1) { - mylog(log_fatal,"socket bind error\n"); - myexit(1); - } - setnonblocking(udp_fd); - - //epollfd = epoll_create1(0); - - //const int max_events = 4096; - //struct epoll_event ev, events[max_events]; - //if (epollfd < 0) { - // mylog(log_fatal,"epoll return %d\n", epollfd); - // myexit(-1); - //} - - struct ev_loop * loop= ev_default_loop(0); - assert(loop != NULL); - - //ev.events = EPOLLIN; - //ev.data.u64 = udp_fd; - //ret = epoll_ctl(epollfd, EPOLL_CTL_ADD, udp_fd, &ev); - //if (ret!=0) { - // mylog(log_fatal,"add udp_listen_fd error\n"); - // myexit(-1); - //} - - - struct ev_io udp_accept_watcher; - - udp_accept_watcher.data=&conn_info; - ev_io_init(&udp_accept_watcher, udp_accept_cb, udp_fd, EV_READ); - ev_io_start(loop, &udp_accept_watcher); - - - //ev.events = EPOLLIN; - //ev.data.u64 = raw_recv_fd; - - //ret = epoll_ctl(epollfd, EPOLL_CTL_ADD, raw_recv_fd, &ev); - //if (ret!= 0) { - // mylog(log_fatal,"add raw_fd error\n"); - // myexit(-1); - //} - - //struct ev_io raw_watcher; - - //raw_watcher.data=&conn_info; - // ev_io_init(&raw_watcher, raw_recv_cb, raw_recv_fd, EV_READ); - //ev_io_start(loop, &raw_watcher); - - g_default_loop=loop; - async_watcher.data=&conn_info; - ev_async_init(&async_watcher,async_cb); - ev_async_start(loop,&async_watcher); - - init_raw_socket(); - - - - int unbind=1; - - //set_timer(epollfd,timer_fd); - - struct ev_timer clear_timer; - - clear_timer.data=&conn_info; - ev_timer_init(&clear_timer, clear_timer_cb, 0, timer_interval/1000.0); - ev_timer_start(loop, &clear_timer); - - mylog(log_debug,"send_raw : from %x %d to %x %d\n",send_info.src_ip,send_info.src_port,send_info.dst_ip,send_info.dst_port); - - int fifo_fd=-1; - - struct ev_io fifo_watcher; - fifo_watcher.data=&conn_info; - - if(fifo_file[0]!=0) - { - fifo_fd=create_fifo(fifo_file); - - ev_io_init(&fifo_watcher, fifo_cb, fifo_fd, EV_READ); - ev_io_start(loop, &fifo_watcher); - - mylog(log_info,"fifo_file=%s\n",fifo_file); - } - - ev_run(loop, 0); - return 0; -} - void sigpipe_cb(struct ev_loop *l, ev_signal *w, int revents) { mylog(log_info, "got sigpipe, ignored"); @@ -1002,6 +24,8 @@ void sigint_cb(struct ev_loop *l, ev_signal *w, int revents) myexit(0); } +int client_event_loop(); + int main(int argc, char *argv[]) { assert(sizeof(unsigned short)==2); diff --git a/makefile b/makefile index c3b6643..9e54570 100755 --- a/makefile +++ b/makefile @@ -10,7 +10,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 ${OPT} -COMMON=main.cpp lib/md5.cpp encrypt.cpp log.cpp network.cpp common.cpp connection.cpp misc.cpp fd_manager.cpp -lpthread my_ev.cpp -isystem libev +COMMON=main.cpp lib/md5.cpp encrypt.cpp log.cpp network.cpp common.cpp connection.cpp misc.cpp fd_manager.cpp client.cpp -lpthread my_ev.cpp -isystem libev PCAP="-lpcap" diff --git a/misc.cpp b/misc.cpp index 22510e8..02e2ae2 100644 --- a/misc.cpp +++ b/misc.cpp @@ -15,6 +15,7 @@ int hb_mode=1; int hb_len=1200; +char hb_buf[buf_len]; int mtu_warn=1375;//if a packet larger than mtu warn is receviced,there will be a warning diff --git a/misc.h b/misc.h index 61672fc..e7325fd 100644 --- a/misc.h +++ b/misc.h @@ -15,6 +15,8 @@ extern int hb_mode; extern int hb_len; +extern char hb_buf[buf_len]; + extern int mtu_warn; extern int max_rst_allowed;