From 5a7734a007b5496f77f71bef628accf66e6dc872 Mon Sep 17 00:00:00 2001 From: wangyu Date: Thu, 27 Jul 2017 02:00:31 +0800 Subject: [PATCH] server can handle multi handshake now,but still much work left --- main.cpp | 339 +++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 316 insertions(+), 23 deletions(-) diff --git a/main.cpp b/main.cpp index ed11731..289221d 100755 --- a/main.cpp +++ b/main.cpp @@ -925,7 +925,7 @@ unsigned short csum(const unsigned short *ptr,int nbytes) { -int send_raw_ip(const packet_info_t &info,const char * payload,int payloadlen) +int send_raw_ip(const packet_info_t info,const char * payload,int payloadlen) { char send_raw_ip_buf[buf_len]; @@ -1047,7 +1047,7 @@ int recv_raw_ip(packet_info_t &info,char * &payload,int &payloadlen) } -int send_raw_icmp(const packet_info_t &info, const char * payload, int payloadlen) +int send_raw_icmp(packet_info_t &info, const char * payload, int payloadlen) { char send_raw_icmp_buf[buf_len]; icmphdr *icmph=(struct icmphdr *) (send_raw_icmp_buf); @@ -1061,9 +1061,9 @@ int send_raw_icmp(const packet_info_t &info, const char * payload, int payloadle icmph->type=0; } icmph->code=0; - icmph->id=htons(g_packet_info_send.src_port); + icmph->id=htons(info.src_port); - icmph->seq=htons(g_packet_info_send.icmp_seq++); + icmph->seq=htons(info.icmp_seq++); memcpy(send_raw_icmp_buf+sizeof(icmphdr),payload,payloadlen); @@ -1119,7 +1119,7 @@ int send_raw_udp(const packet_info_t &info, const char * payload, int payloadlen return 0; } -int send_raw_tcp(const packet_info_t &info,const char * payload, int payloadlen) { //TODO seq increase +int send_raw_tcp(packet_info_t &info,const char * payload, int payloadlen) { //TODO seq increase char send_raw_tcp_buf[buf_len]; struct tcphdr *tcph = (struct tcphdr *) (send_raw_tcp_buf @@ -1217,15 +1217,15 @@ int send_raw_tcp(const packet_info_t &info,const char * payload, int payloadlen) { return -1; } - if (g_packet_info_send.syn == 0 && g_packet_info_send.ack == 1 + if (info.syn == 0 && info.ack == 1 && payloadlen != 0) { if (seq_mode == 0) { } else if (seq_mode == 1) { - g_packet_info_send.seq += payloadlen; + info.seq += payloadlen; } else if (seq_mode == 2) { if (random() % 5 == 3) - g_packet_info_send.seq += payloadlen; + info.seq += payloadlen; } } @@ -1795,7 +1795,7 @@ int recv_raw_tcp_deprecated(packet_info_t &info,char * &payload,int &payloadlen) return 0; } -int send_raw(const packet_info_t &info,const char * payload,int payloadlen) +int send_raw(packet_info_t &info,const char * payload,int payloadlen) { switch(raw_mode) { @@ -1816,7 +1816,7 @@ int recv_raw(packet_info_t &info,char * &payload,int &payloadlen) return -1; } -int send_bare(const packet_info_t &info,const char* data,int len) +int send_bare(packet_info_t &info,const char* data,int len) { char send_data_buf[buf_len]; //buf for send data and send hb char send_data_buf2[buf_len]; @@ -1898,7 +1898,7 @@ int char_to_numbers(const char * data,int len,id_t &id1,id_t &id2,id_t &id3) } -int send_handshake(const packet_info_t &info,id_t id1,id_t id2,id_t id3) +int send_handshake(packet_info_t &info,id_t id1,id_t id2,id_t id3) { char * data;int len; len=sizeof(id_t)*3; @@ -1917,7 +1917,7 @@ int recv_handshake(packet_info_t &info,id_t &id1,id_t &id2,id_t &id3) return 0; }*/ -int send_safer(const packet_info_t &info,const char* data,int len) +int send_safer(packet_info_t &info,const char* data,int len) { char send_data_buf[buf_len]; //buf for send data and send hb char send_data_buf2[buf_len]; @@ -2324,14 +2324,16 @@ int keep_connection_client() //for client } struct conn_info_t { - server_current_state_t current_stat; - packet_info_t recv_packet_info; + server_current_state_t server_current_state; + //packet_info_t recv_packet_info; packet_info_t send_packet_info; long long last_state_time; id_t my_id; + id_t oppsite_id; conn_info_t() { - current_stat=server_nothing; + send_packet_info.protocol=g_packet_info_send.protocol; + server_current_state=server_nothing; last_state_time=0; } }; @@ -2339,9 +2341,13 @@ struct conn_info_t struct conn_manager_t { unordered_map mp; + uint32_t current_ready_ip; + uint16_t current_ready_port; conn_manager_t() { mp.reserve(10007); + current_ready_ip=0; + current_ready_port=0; } int exist(uint32_t ip,uint16_t port) { @@ -2378,8 +2384,38 @@ struct conn_manager_t int keep_connection_server_multi() { - //current_time_rough=get_current_time(); - //conv_manager.clean_inactive(); + current_time_rough=get_current_time(); + conv_manager.clean_inactive(); + + if(server_current_state==server_ready) + { + if( get_current_time()-last_hb_recv_time>heartbeat_timeout ) + { + mylog(log_trace,"%lld %lld\n",get_current_time(),last_state_time); + server_current_state=server_nothing; + + mylog(log_info,"changed server id\n"); + my_id=get_true_random_number_nz(); + + conn_manager.current_ready_ip=0; + conn_manager.current_ready_port=0; + mylog(log_info,"changed state to server_nothing\n"); + return 0; + } + + if(get_current_time()-last_hb_sent_time\n",my_id); + } + } int keep_connection_server() { @@ -2676,18 +2712,276 @@ int server_on_raw_recv_multi() { char* data;int data_len; packet_info_t recv_info; - if(recv_bare(recv_info,data,data_len)!=0) + if(recv_raw(recv_info,data,data_len)!=0) { return -1; } uint32_t ip=recv_info.src_ip; uint16_t port=recv_info.src_port; + if(ip==conn_manager.current_ready_ip&&port==conn_manager.current_ready_port) + { + if (parse_safer(data, data_len, data, data_len) != 0) { + return -1; + } + + if( (raw_mode==mode_faketcp&&(recv_info.syn==1||recv_info.ack!=1)) ||data_len==0) return 0; + if(recv_info.src_ip!=g_packet_info_send.dst_ip||recv_info.src_port!=g_packet_info_send.dst_port) + { + mylog(log_debug,"unexpected adress\n"); + return 0; + } + + if(data[0]=='h'&&data_len==1) + { + uint32_t tmp= ntohl(* ((uint32_t *)&data[1+sizeof(uint32_t)])); + mylog(log_debug,"received hb <%x,%x>\n",oppsite_id,tmp); + last_hb_recv_time=current_time_rough; + return 0; + } + else if(data[0]=='d'&&data_len>=sizeof(uint32_t)+1) + { + uint32_t tmp_conv_id=ntohl(* ((uint32_t *)&data[1])); + + last_hb_recv_time=current_time_rough; + + mylog(log_debug,"<<<>>>\n",tmp_conv_id); + if(!conv_manager.is_conv_used(tmp_conv_id)) + { + if(conv_manager.get_size() >=max_conv_num) + { + mylog(log_warn,"ignored new conv %x connect bc max_conv_num exceed\n",tmp_conv_id); + return 0; + } + struct sockaddr_in remote_addr_in; + + 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_address_uint32; + + int new_udp_fd=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if(new_udp_fd<0) + { + mylog(log_warn,"create udp_fd error\n"); + return -1; + } + set_buf_size(new_udp_fd); + + mylog(log_debug,"created new udp_fd %d\n",new_udp_fd); + int ret = connect(new_udp_fd, (struct sockaddr *) &remote_addr_in, slen); + if(ret!=0) + { + mylog(log_warn,"udp fd connect fail\n"); + close(new_udp_fd); + return -1; + } + struct epoll_event ev; + + uint64_t u64=((u_int64_t(tmp_conv_id))<<32u)+(uint32_t)new_udp_fd; + mylog(log_trace,"u64: %ld\n",u64); + ev.events = EPOLLIN; + + ev.data.u64 = u64; + + ret = epoll_ctl(epollfd, EPOLL_CTL_ADD, new_udp_fd, &ev); + + if (ret!= 0) { + mylog(log_warn,"add udp_fd error\n"); + close(new_udp_fd); + return -1; + } + + conv_manager.insert_conv(tmp_conv_id,u64); + + mylog(log_info,"new conv conv_id=%x, assigned fd=%d\n",tmp_conv_id,new_udp_fd); + + } + + uint64_t u64=conv_manager.find_u64_by_conv(tmp_conv_id); + + conv_manager.update_active_time(tmp_conv_id); + + int fd=int((u64<<32u)>>32u); + + mylog(log_debug,"received a data from fake tcp,len:%d\n",data_len); + int ret=send(fd,data+1+sizeof(uint32_t),data_len -(1+sizeof(uint32_t)),0); + + mylog(log_debug,"%d byte sent ,fd :%d\n ",ret,fd); + if(ret<0) + { + mylog(log_warn,"send returned %d\n",ret); + //perror("what happened????"); + } + return 0; + } + } + //else + if(parse_bare(data,data_len,data,data_len)!=0) + { + return -1; + } + if(!conn_manager.exist(ip,port)) + { + if(raw_mode==mode_faketcp) + { + if (!(recv_info.syn == 1 && recv_info.ack == 0 && data_len == 0)) + return 0; + + } + else if(raw_mode==mode_udp||raw_mode==mode_icmp) + { + + if(data_len==strlen("hello")&& memcmp((char *)"hello",data,strlen("hello"))!=0) + { + //data[6]=0; + mylog(log_debug,"not a hello packet %d\n",data,data_len); + return 0; + } + } + } conn_info_t & conn_info=conn_manager.find(ip,port); packet_info_t &send_info=conn_info.send_packet_info; - server_current_state_t &server_current_state=conn_info.current_stat; - int retry_counter; + server_current_state=server_nothing; //dummy variable,to avoid accidently access global variable + if(conn_info.server_current_state==server_nothing) + { + send_info.src_ip=recv_info.dst_ip; + send_info.src_port=recv_info.dst_port; + + send_info.dst_port = recv_info.src_port; + send_info.dst_ip = recv_info.src_ip; + + mylog(log_info,"send_info.src_port %d,%d\n",send_info.src_port,send_info.dst_port); + + if(raw_mode==mode_faketcp) + { + send_info.ack_seq = recv_info.seq + 1; + + send_info.psh = 0; + send_info.syn = 1; + send_info.ack = 1; + + send_info.seq = get_true_random_number_nz(); //not necessary to set + + mylog(log_info,"sent syn ack\n"); + send_bare(send_info, 0, 0); //////////////send + + mylog(log_info,"changed state to server_syn_ack_sent\n"); + + conn_info.server_current_state = server_syn_ack_sent; + conn_info.last_state_time = get_current_time(); + } + else if(raw_mode==mode_udp||raw_mode==mode_icmp) + { + mylog(log_info,"got a hello packet\n"); + + mylog(log_info,"sent handshake\n"); + + conn_info.my_id=get_true_random_number_nz(); + send_handshake(send_info,conn_info.my_id,random(),const_id); //////////////send + + mylog(log_info,"changed state to server_heartbeat_sent_sent\n"); + + conn_info.server_current_state = server_handshake_sent; + conn_info.last_state_time = get_current_time(); + } + } + else if(conn_info.server_current_state==server_syn_ack_sent) + { + if(raw_mode==mode_faketcp&&!( recv_info.syn==0&&recv_info.ack==1 &&data_len==0)) return 0; + if(recv_info.src_ip!=send_info.dst_ip||recv_info.src_port!=send_info.dst_port) + { + mylog(log_debug,"unexpected adress\n"); + return 0; + } + + send_info.syn=0; + send_info.ack=1; + send_info.seq+=1;////////is this right? + + conn_info.my_id=get_true_random_number_nz(); + send_handshake(send_info,conn_info.my_id,0,const_id); //////////////send + + mylog(log_info,"changed state to server_handshake_sent\n"); + + conn_info.server_current_state=server_handshake_sent; + conn_info.last_state_time=get_current_time(); + } + else if(conn_info.server_current_state==server_handshake_sent)//heart beat received + { + if(( raw_mode==mode_faketcp&& (recv_info.syn==1||recv_info.ack!=1)) ||data_len==0) return 0; + + if(recv_info.src_ip!=send_info.dst_ip||recv_info.src_port!=send_info.dst_port) + { + mylog(log_trace,"unexpected adress\n"); + return 0; + } + + if(conn_info.last_state_time