diff --git a/client.cpp b/client.cpp index 605098a..9d16055 100644 --- a/client.cpp +++ b/client.cpp @@ -8,1066 +8,888 @@ #include "fd_manager.h" #ifdef UDP2RAW_MP -u32_t detect_interval=1500; -u64_t laste_detect_time=0; - -int use_udp_for_detection=0; -int use_tcp_for_detection=1; +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; #endif -int client_on_timer(conn_info_t &conn_info) //for client. called when a timer is ready in epoll +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"); + 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, "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_trace, "\n", send_info.ts_ack); #ifdef UDP2RAW_MP - //mylog(log_debug,"pcap cnt :%d\n",pcap_cnt); - if(send_with_pcap&&!pcap_header_captured) - { + // 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}; - 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); + 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;*/ + int port = get_true_random_number() % 65534 + 1; + address_t tmp_addr = remote_addr; + tmp_addr.set_port(port); - socklen_t slen = sizeof(sockaddr_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;*/ - int port=get_true_random_number()%65534+1; - address_t tmp_addr=remote_addr; - tmp_addr.set_port(port); + if (use_udp_for_detection) { + int new_udp_fd = socket(tmp_addr.get_type(), 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(); - if(use_udp_for_detection) - { - int new_udp_fd=socket(tmp_addr.get_type(), 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 *)&tmp_addr.inner, tmp_addr.get_len()); + if (ret == -1) { + mylog(log_warn, "sendto() failed\n"); + } + sock_close(new_udp_fd); + } - int ret=sendto(new_udp_fd,(char*)(&tmp),sizeof(tmp),0,(struct sockaddr *)&tmp_addr.inner,tmp_addr.get_len()); - 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; - if(use_tcp_for_detection) - { - static int last_tcp_fd=-1; + int new_tcp_fd = socket(tmp_addr.get_type(), 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 *)&tmp_addr.inner, tmp_addr.get_len()); + if (last_tcp_fd != -1) + sock_close(last_tcp_fd); + last_tcp_fd = new_tcp_fd; + // close(new_tcp_fd); + } - int new_tcp_fd=socket(tmp_addr.get_type(), 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 *)&tmp_addr.inner,tmp_addr.get_len()); - 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"); - - - mylog(log_info,"waiting for a use-able packet to be captured\n"); - - return 0; - } + return 0; + } #endif - if(raw_info.disabled) - { - conn_info.state.client_current_state=client_idle; - conn_info.my_id=get_true_random_number_nz(); + 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"); - } + 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; + 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); - } + 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 + conn_info.blob->anti_replay.re_init(); + conn_info.my_id = get_true_random_number_nz(); /// todo no need to do this everytime + address_t tmp_addr; + // u32_t new_ip=0; + if (!force_source_ip) { + if (get_src_adress2(tmp_addr, remote_addr) != 0) { + mylog(log_warn, "get_src_adress() failed\n"); + return -1; + } + // source_addr=new_addr; + // source_addr.set_port(0); + mylog(log_info, "source_addr is now %s\n", tmp_addr.get_ip()); - address_t tmp_addr; - //u32_t new_ip=0; - if(!force_source_ip) - { - if(get_src_adress2(tmp_addr,remote_addr)!=0) - { - mylog(log_warn,"get_src_adress() failed\n"); - return -1; - } - //source_addr=new_addr; - //source_addr.set_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; + }*/ - mylog(log_info,"source_addr is now %s\n",tmp_addr.get_ip()); + } else { + tmp_addr = source_addr; + } - /* - 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; - }*/ + send_info.new_src_ip.from_address_t(tmp_addr); - } - else - { - tmp_addr=source_addr; - } + if (force_source_port == 0) { + send_info.src_port = client_bind_to_a_new_port2(bind_fd, tmp_addr); + } else { + send_info.src_port = source_port; + } - send_info.new_src_ip.from_address_t(tmp_addr); + if (raw_mode == mode_icmp) { + send_info.dst_port = send_info.src_port; + } - if (force_source_port == 0) - { - send_info.src_port = client_bind_to_a_new_port2(bind_fd,tmp_addr); - } - else - { - send_info.src_port = source_port; - } + mylog(log_info, "using port %d\n", send_info.src_port); + init_filter(send_info.src_port); - if (raw_mode == mode_icmp) - { - send_info.dst_port = send_info.src_port; - } + if (raw_mode == mode_icmp || raw_mode == mode_udp) { + conn_info.state.client_current_state = client_handshake1; - 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) - { - setnonblocking(bind_fd); - int ret=connect(bind_fd,(struct sockaddr *)&remote_addr.inner,remote_addr.get_len()); - mylog(log_debug,"ret=%d,errno=%s, %d %s\n",ret,get_sock_error(),bind_fd,remote_addr.get_str()); - //mylog(log_info,"ret=%d,errno=,%d %s\n",ret,bind_fd,remote_addr.get_str()); - 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_hs2_or_ready(conn_info_t &conn_info,char type,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; - - if(!recv_info.new_src_ip.equal(send_info.new_dst_ip)||recv_info.src_port!=send_info.dst_port) + mylog(log_info, "state changed from client_idle to client_pre_handshake\n"); + } + if (raw_mode == mode_faketcp) { + if (use_tcp_dummy_socket) { + setnonblocking(bind_fd); + int ret = connect(bind_fd, (struct sockaddr *)&remote_addr.inner, remote_addr.get_len()); + mylog(log_debug, "ret=%d,errno=%s, %d %s\n", ret, get_sock_error(), bind_fd, remote_addr.get_str()); + // mylog(log_info,"ret=%d,errno=,%d %s\n",ret,bind_fd,remote_addr.get_str()); + 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 { - mylog(log_warn,"unexpected adress %s %s %d %d,this shouldnt happen.\n",recv_info.new_src_ip.get_str1(),send_info.new_dst_ip.get_str2(),recv_info.src_port,send_info.dst_port); + 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 < heartbeat_interval) { + return 0; + } + + mylog(log_debug, "heartbeat sent <%x,%x>\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_hs2_or_ready(conn_info_t &conn_info, char type, 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; + + if (!recv_info.new_src_ip.equal(send_info.new_dst_ip) || recv_info.src_port != send_info.dst_port) { + mylog(log_warn, "unexpected adress %s %s %d %d,this shouldnt happen.\n", recv_info.new_src_ip.get_str1(), send_info.new_dst_ip.get_str2(), recv_info.src_port, send_info.dst_port); return -1; } - if(conn_info.state.client_current_state==client_handshake2) - { - mylog(log_info,"changed state from to client_handshake2 to client_ready\n"); - conn_info.state.client_current_state=client_ready; - conn_info.last_hb_sent_time=0; - conn_info.last_hb_recv_time=get_current_time(); - conn_info.last_oppsite_roller_time=conn_info.last_hb_recv_time; + if (conn_info.state.client_current_state == client_handshake2) { + mylog(log_info, "changed state from to client_handshake2 to client_ready\n"); + conn_info.state.client_current_state = client_ready; + conn_info.last_hb_sent_time = 0; + conn_info.last_hb_recv_time = get_current_time(); + conn_info.last_oppsite_roller_time = conn_info.last_hb_recv_time; client_on_timer(conn_info); } - 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(); + 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); + } 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(); + 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); + 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); + 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_data_by_conv(tmp_conv_id); - address_t tmp_addr=conn_info.blob->conv_manager.c.find_data_by_conv(tmp_conv_id); + // u64_t u64=conn_info.blob->conv_manager.c.find_data_by_conv(tmp_conv_id); + address_t tmp_addr = conn_info.blob->conv_manager.c.find_data_by_conv(tmp_conv_id); - //sockaddr_in tmp_sockaddr={0}; + // sockaddr_in tmp_sockaddr={0}; - //tmp_sockaddr.sin_family = AF_INET; - //tmp_sockaddr.sin_addr.s_addr=(u64>>32u); + // tmp_sockaddr.sin_family = AF_INET; + // tmp_sockaddr.sin_addr.s_addr=(u64>>32u); - //tmp_sockaddr.sin_port= htons(uint16_t((u64<<32u)>>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 *)&tmp_addr.inner, tmp_addr.get_len()); - int ret=sendto(udp_fd,data+sizeof(u32_t),data_len -(sizeof(u32_t)),0,(struct sockaddr *)&tmp_addr.inner,tmp_addr.get_len()); - - if(ret<0) - { - mylog(log_warn,"sento returned %d,%s,%02x,%s\n",ret,get_sock_error(),int(tmp_addr.get_type()),tmp_addr.get_str()); - //perror("ret<0"); + if (ret < 0) { + mylog(log_warn, "sento returned %d,%s,%02x,%s\n", ret, get_sock_error(), int(tmp_addr.get_type()), tmp_addr.get_str()); + // perror("ret<0"); } - } - else - { - mylog(log_warn,"unknown packet,this shouldnt happen.\n"); + } else { + mylog(log_warn, "unknown packet,this shouldnt happen.\n"); return -1; } return 0; } -int client_on_raw_recv(conn_info_t &conn_info) //called when raw fd received a packet. +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; + 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; + raw_info_t &raw_info = conn_info.raw_info; - mylog(log_trace,"\n",send_info.ts_ack); + mylog(log_trace, "\n", send_info.ts_ack); #ifdef UDP2RAW_LINUX - if(pre_recv_raw_packet()<0) return -1; + if (pre_recv_raw_packet() < 0) return -1; #endif - if(conn_info.state.client_current_state==client_idle ) - { - discard_raw_packet(); - //recv(raw_recv_fd, 0,0, 0 ); - } - 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(data_len>=max_data_len+1) - { - mylog(log_debug,"data_len=%d >= max_data_len+1,ignored",data_len); - return -1; - } - if(!recv_info.new_src_ip.equal(send_info.new_dst_ip)||recv_info.src_port!=send_info.dst_port) - { - mylog(log_debug,"unexpected adress %s %s %d %d\n",recv_info.new_src_ip.get_str1(),send_info.new_dst_ip.get_str2(),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; + if (conn_info.state.client_current_state == client_idle) { + discard_raw_packet(); + // recv(raw_recv_fd, 0,0, 0 ); + } 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 (data_len >= max_data_len + 1) { + mylog(log_debug, "data_len=%d >= max_data_len+1,ignored", data_len); + return -1; + } + if (!recv_info.new_src_ip.equal(send_info.new_dst_ip) || recv_info.src_port != send_info.dst_port) { + mylog(log_debug, "unexpected adress %s %s %d %d\n", recv_info.new_src_ip.get_str1(), send_info.new_dst_ip.get_str2(), 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.new_src_ip.equal(send_info.new_dst_ip)||recv_info.src_port!=send_info.dst_port) - { - mylog(log_debug,"unexpected adress %s %s %d %d\n",recv_info.new_src_ip.get_str1(),send_info.new_dst_ip.get_str2(),recv_info.src_port,send_info.dst_port); - return -1; - } - if(data_len type_vec; - vector data_vec; - recv_safer_multi(conn_info,type_vec,data_vec); - if(data_vec.empty()) - { - mylog(log_debug,"recv_safer failed!\n"); - return -1; - } - - for(int i=0;i<(int)type_vec.size();i++) - { - char type=type_vec[i]; - char *data=(char *)data_vec[i].c_str(); //be careful, do not append data to it - int data_len=data_vec[i].length(); - client_on_raw_recv_hs2_or_ready(conn_info, type, data,data_len); + if (tmp_my_id != conn_info.my_id) { + mylog(log_debug, "tmp_my_id doesnt match\n"); + return -1; } - return 0; - } - else - { - mylog(log_fatal,"unknown state,this shouldnt happen.\n"); - myexit(-1); - } - return 0; + if (raw_mode == mode_faketcp) { + if (recv_info.ack_seq != send_info.seq) { + mylog(log_debug, "seq ack_seq mis match\n"); + return -1; + } + if (recv_info.seq != send_info.ack_seq) { + mylog(log_debug, "seq ack_seq mis match\n"); + return -1; + } + } + conn_info.oppsite_id = tmp_oppsite_id; + + mylog(log_info, "changed state from to client_handshake1 to client_handshake2,my_id is %x,oppsite id is %x\n", conn_info.my_id, conn_info.oppsite_id); + + conn_info.state.client_current_state = client_handshake2; + conn_info.last_state_time = get_current_time(); + conn_info.last_hb_sent_time = 0; + client_on_timer(conn_info); + + return 0; + } else if (conn_info.state.client_current_state == client_handshake2 || conn_info.state.client_current_state == client_ready) // received heartbeat or data + { + vector type_vec; + vector data_vec; + recv_safer_multi(conn_info, type_vec, data_vec); + if (data_vec.empty()) { + mylog(log_debug, "recv_safer failed!\n"); + return -1; + } + + for (int i = 0; i < (int)type_vec.size(); i++) { + char type = type_vec[i]; + char *data = (char *)data_vec[i].c_str(); // be careful, do not append data to it + int data_len = data_vec[i].length(); + client_on_raw_recv_hs2_or_ready(conn_info, type, data, data_len); + } + + return 0; + } else { + mylog(log_fatal, "unknown state,this shouldnt happen.\n"); + myexit(-1); + } + return 0; } -int client_on_udp_recv(conn_info_t &conn_info) -{ - int recv_len; - char buf[buf_len]; - 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+1, 0, - (struct sockaddr *) &udp_new_addr_in, &udp_new_addr_len)) == -1) { - mylog(log_debug,"recv_from error,%s\n",get_sock_error()); - return -1; - //myexit(1); - }; +int client_on_udp_recv(conn_info_t &conn_info) { + int recv_len; + char buf[buf_len]; + 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 + 1, 0, + (struct sockaddr *)&udp_new_addr_in, &udp_new_addr_len)) == -1) { + mylog(log_debug, "recv_from error,%s\n", get_sock_error()); + return -1; + // myexit(1); + }; - if(recv_len==max_data_len+1) - { - mylog(log_warn,"huge packet, data_len > %d,dropped\n",max_data_len); - return -1; - } + if (recv_len == max_data_len + 1) { + mylog(log_warn, "huge packet, data_len > %d,dropped\n", max_data_len); + return -1; + } - 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); - } + 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); + } - address_t tmp_addr; - tmp_addr.from_sockaddr((sockaddr *)&udp_new_addr_in,udp_new_addr_len); - u32_t conv; + address_t tmp_addr; + tmp_addr.from_sockaddr((sockaddr *)&udp_new_addr_in, udp_new_addr_len); + u32_t conv; - if(!conn_info.blob->conv_manager.c.is_data_used(tmp_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 -1; - } - conv=conn_info.blob->conv_manager.c.get_new_conv(); - conn_info.blob->conv_manager.c.insert_conv(conv,tmp_addr); - mylog(log_info,"new packet from %s,conv_id=%x\n",tmp_addr.get_str(),conv); - } - else - { - conv=conn_info.blob->conv_manager.c.find_conv_by_data(tmp_addr); - } + if (!conn_info.blob->conv_manager.c.is_data_used(tmp_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 -1; + } + conv = conn_info.blob->conv_manager.c.get_new_conv(); + conn_info.blob->conv_manager.c.insert_conv(conv, tmp_addr); + mylog(log_info, "new packet from %s,conv_id=%x\n", tmp_addr.get_str(), conv); + } else { + conv = conn_info.blob->conv_manager.c.find_conv_by_data(tmp_addr); + } - conn_info.blob->conv_manager.c.update_active_time(conv); + 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); - } - return 0; + if (conn_info.state.client_current_state == client_ready) { + send_data_safer(conn_info, buf, recv_len, conv); + } + return 0; } -void udp_accept_cb(struct ev_loop *loop, struct ev_io *watcher, int revents) -{ - conn_info_t & conn_info= *((conn_info_t*)watcher->data); - client_on_udp_recv(conn_info); +void udp_accept_cb(struct ev_loop *loop, struct ev_io *watcher, int revents) { + conn_info_t &conn_info = *((conn_info_t *)watcher->data); + client_on_udp_recv(conn_info); } -void raw_recv_cb(struct ev_loop *loop, struct ev_io *watcher, int revents) -{ - if(is_udp2raw_mp)assert(0==1); - conn_info_t & conn_info= *((conn_info_t*)watcher->data); - client_on_raw_recv(conn_info); +void raw_recv_cb(struct ev_loop *loop, struct ev_io *watcher, int revents) { + if (is_udp2raw_mp) assert(0 == 1); + conn_info_t &conn_info = *((conn_info_t *)watcher->data); + client_on_raw_recv(conn_info); } #ifdef UDP2RAW_MP -void async_cb(struct ev_loop *loop, struct ev_async *watcher, int revents) -{ - conn_info_t & conn_info= *((conn_info_t*)watcher->data); +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; + 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); + 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, "link level header captured:\n"); + unsigned char *tmp = (unsigned char *)pcap_header_buf; + pcap_captured_full_len = len; + for (int i = 0; i < pcap_link_header_len; i++) + log_bare(log_info, "<%x>", (u32_t)tmp[i]); - log_bare(log_info,"\n"); - return ; - } + 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); + // 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; - if(g_fix_gro==0&&len>max_data_len) - { - mylog(log_warn,"huge packet %d > %d, dropped. maybe you need to turn down mtu at upper level, or maybe you need the --fix-gro option\n",len,max_data_len); - break; - } + if (empty) break; + if (g_fix_gro == 0 && len > max_data_len) { + mylog(log_warn, "huge packet %d > %d, dropped. maybe you need to turn down mtu at upper level, or maybe you need the --fix-gro option\n", len, max_data_len); + 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); - } + 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); + } } #endif -void clear_timer_cb(struct ev_loop *loop, struct ev_timer *watcher, int revents) -{ - conn_info_t & conn_info= *((conn_info_t*)watcher->data); - client_on_timer(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); + client_on_timer(conn_info); } -void fifo_cb(struct ev_loop *loop, struct ev_io *watcher, int revents) -{ - conn_info_t & conn_info= *((conn_info_t*)watcher->data); +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"); - } + 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]; +int client_event_loop() { + char buf[buf_len]; - conn_info_t conn_info; - conn_info.my_id=get_true_random_number_nz(); + 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; + 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; #ifdef UDP2RAW_LINUX - if(lower_level) - { - if(lower_level_manual) - { - int index; - init_ifindex(if_name,raw_send_fd,index); - //init_ifindex(if_name); - memset(&send_info.addr_ll, 0, sizeof(send_info.addr_ll)); - send_info.addr_ll.sll_family = AF_PACKET; - send_info.addr_ll.sll_ifindex =index; - send_info.addr_ll.sll_halen = ETHER_ADDR_LEN; - send_info.addr_ll.sll_protocol = htons(ETH_P_IP); - memcpy(&send_info.addr_ll.sll_addr, dest_hw_addr, ETHER_ADDR_LEN); - mylog(log_info,"we are running at lower-level (manual) mode\n"); - } - else - { - u32_t dest_ip; - string if_name_string; - string hw_string; - assert(remote_addr.get_type()==AF_INET); + if (lower_level) { + if (lower_level_manual) { + int index; + init_ifindex(if_name, raw_send_fd, index); + // init_ifindex(if_name); + memset(&send_info.addr_ll, 0, sizeof(send_info.addr_ll)); + send_info.addr_ll.sll_family = AF_PACKET; + send_info.addr_ll.sll_ifindex = index; + send_info.addr_ll.sll_halen = ETHER_ADDR_LEN; + send_info.addr_ll.sll_protocol = htons(ETH_P_IP); + memcpy(&send_info.addr_ll.sll_addr, dest_hw_addr, ETHER_ADDR_LEN); + mylog(log_info, "we are running at lower-level (manual) mode\n"); + } else { + u32_t dest_ip; + string if_name_string; + string hw_string; + assert(remote_addr.get_type() == AF_INET); - if(retry_on_error==0) - { - if(find_lower_level_info(remote_addr.inner.ipv4.sin_addr.s_addr,dest_ip,if_name_string,hw_string)!=0) - { - mylog(log_fatal,"auto detect lower-level info failed for %s,specific it manually\n",remote_addr.get_ip()); - myexit(-1); - } - } - else - { - int ok=0; - while(!ok) - { - if(find_lower_level_info(remote_addr.inner.ipv4.sin_addr.s_addr,dest_ip,if_name_string,hw_string)!=0) - { - mylog(log_warn,"auto detect lower-level info failed for %s,retry in %d seconds\n",remote_addr.get_ip(),retry_on_error_interval); - sleep(retry_on_error_interval); - } - else - { - ok=1; - } + if (retry_on_error == 0) { + if (find_lower_level_info(remote_addr.inner.ipv4.sin_addr.s_addr, dest_ip, if_name_string, hw_string) != 0) { + mylog(log_fatal, "auto detect lower-level info failed for %s,specific it manually\n", remote_addr.get_ip()); + myexit(-1); + } + } else { + int ok = 0; + while (!ok) { + if (find_lower_level_info(remote_addr.inner.ipv4.sin_addr.s_addr, dest_ip, if_name_string, hw_string) != 0) { + mylog(log_warn, "auto detect lower-level info failed for %s,retry in %d seconds\n", remote_addr.get_ip(), retry_on_error_interval); + sleep(retry_on_error_interval); + } else { + ok = 1; + } + } + } + mylog(log_info, "we are running at lower-level (auto) mode,%s %s %s\n", my_ntoa(dest_ip), if_name_string.c_str(), hw_string.c_str()); - } - } - mylog(log_info,"we are running at lower-level (auto) mode,%s %s %s\n",my_ntoa(dest_ip),if_name_string.c_str(),hw_string.c_str()); + u32_t hw[6]; + memset(hw, 0, sizeof(hw)); + sscanf(hw_string.c_str(), "%x:%x:%x:%x:%x:%x", &hw[0], &hw[1], &hw[2], + &hw[3], &hw[4], &hw[5]); - u32_t hw[6]; - memset(hw, 0, sizeof(hw)); - sscanf(hw_string.c_str(), "%x:%x:%x:%x:%x:%x",&hw[0], &hw[1], &hw[2], - &hw[3], &hw[4], &hw[5]); + mylog(log_warn, + "make sure this is correct: if_name=<%s> dest_mac_adress=<%02x:%02x:%02x:%02x:%02x:%02x> \n", + if_name_string.c_str(), hw[0], hw[1], hw[2], hw[3], hw[4], hw[5]); + for (int i = 0; i < 6; i++) { + dest_hw_addr[i] = uint8_t(hw[i]); + } - mylog(log_warn, - "make sure this is correct: if_name=<%s> dest_mac_adress=<%02x:%02x:%02x:%02x:%02x:%02x> \n", - if_name_string.c_str(), hw[0], hw[1], hw[2], hw[3], hw[4], hw[5]); - for (int i = 0; i < 6; i++) { - dest_hw_addr[i] = uint8_t(hw[i]); - } + // mylog(log_fatal,"--lower-level auto for client hasnt been implemented\n"); + int index; + init_ifindex(if_name_string.c_str(), raw_send_fd, index); - //mylog(log_fatal,"--lower-level auto for client hasnt been implemented\n"); - int index; - init_ifindex(if_name_string.c_str(),raw_send_fd,index); - - memset(&send_info.addr_ll, 0, sizeof(send_info.addr_ll)); - send_info.addr_ll.sll_family = AF_PACKET; - send_info.addr_ll.sll_ifindex = index; - send_info.addr_ll.sll_halen = ETHER_ADDR_LEN; - send_info.addr_ll.sll_protocol = htons(ETH_P_IP); - memcpy(&send_info.addr_ll.sll_addr, dest_hw_addr, ETHER_ADDR_LEN); - //mylog(log_info,"we are running at lower-level (manual) mode\n"); - } - - } + memset(&send_info.addr_ll, 0, sizeof(send_info.addr_ll)); + send_info.addr_ll.sll_family = AF_PACKET; + send_info.addr_ll.sll_ifindex = index; + send_info.addr_ll.sll_halen = ETHER_ADDR_LEN; + send_info.addr_ll.sll_protocol = htons(ETH_P_IP); + memcpy(&send_info.addr_ll.sll_addr, dest_hw_addr, ETHER_ADDR_LEN); + // mylog(log_info,"we are running at lower-level (manual) mode\n"); + } + } #endif - + #ifdef UDP2RAW_MP - address_t tmp_addr; - if(get_src_adress2(tmp_addr,remote_addr)!=0) - { - mylog(log_error,"get_src_adress() failed\n"); - myexit(-1); - } - if(strcmp(dev,"")==0) - { - mylog(log_info,"--dev have not been set, trying to detect automatically, available devices:\n"); + address_t tmp_addr; + if (get_src_adress2(tmp_addr, remote_addr) != 0) { + mylog(log_error, "get_src_adress() failed\n"); + myexit(-1); + } + if (strcmp(dev, "") == 0) { + mylog(log_info, "--dev have not been set, trying to detect automatically, available devices:\n"); - mylog(log_info,"available device(device name: ip address ; description):\n"); + mylog(log_info, "available device(device name: ip address ; description):\n"); - char errbuf[PCAP_ERRBUF_SIZE]; + char errbuf[PCAP_ERRBUF_SIZE]; - int found=0; + 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); - } + 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||a->addr->sa_family == AF_INET6) - { - cnt++; + 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 || a->addr->sa_family == AF_INET6) { + cnt++; - if(a->addr->sa_family ==AF_INET) - { - char s[max_addr_len]; - inet_ntop(AF_INET, &((struct sockaddr_in*)a->addr)->sin_addr, s,max_addr_len); - log_bare(log_warn," [%s]", s); + if (a->addr->sa_family == AF_INET) { + char s[max_addr_len]; + inet_ntop(AF_INET, &((struct sockaddr_in *)a->addr)->sin_addr, s, max_addr_len); + log_bare(log_warn, " [%s]", s); - if(a->addr->sa_family==raw_ip_version) - { - if(((struct sockaddr_in*)a->addr)->sin_addr.s_addr ==tmp_addr.inner.ipv4.sin_addr.s_addr) - { - found++; - strcpy(dev,d->name); - } - } - } - else - { - assert(a->addr->sa_family ==AF_INET6); + if (a->addr->sa_family == raw_ip_version) { + if (((struct sockaddr_in *)a->addr)->sin_addr.s_addr == tmp_addr.inner.ipv4.sin_addr.s_addr) { + found++; + strcpy(dev, d->name); + } + } + } else { + assert(a->addr->sa_family == AF_INET6); - char s[max_addr_len]; - inet_ntop(AF_INET6, &((struct sockaddr_in6*)a->addr)->sin6_addr, s,max_addr_len); - log_bare(log_warn," [%s]", s); + char s[max_addr_len]; + inet_ntop(AF_INET6, &((struct sockaddr_in6 *)a->addr)->sin6_addr, s, max_addr_len); + log_bare(log_warn, " [%s]", s); - if(a->addr->sa_family==raw_ip_version) - { - if( memcmp( &((struct sockaddr_in6*)a->addr)->sin6_addr,&tmp_addr.inner.ipv6.sin6_addr,sizeof(struct in6_addr))==0 ) - { - 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 available)"); - } - else - { - log_bare(log_warn,"; %s", d->description); - } - log_bare(log_warn,"\n"); - } + if (a->addr->sa_family == raw_ip_version) { + if (memcmp(&((struct sockaddr_in6 *)a->addr)->sin6_addr, &tmp_addr.inner.ipv6.sin6_addr, sizeof(struct in6_addr)) == 0) { + 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 available)"); + } 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",tmp_addr.get_ip()); - myexit(-1); - } - else if(found==1) - { - mylog(log_info,"using device:[%s], ip: [%s]\n",dev,tmp_addr.get_ip()); - } - else - { - mylog(log_fatal,"more than one devices found for ip: [%s] , you need to use --dev manually\n",tmp_addr.get_ip()); - myexit(-1); - } - } - else - { - mylog(log_info,"--dev has been manually set, using device:[%s]\n",dev); - } + if (found == 0) { + mylog(log_fatal, "no matched device found for ip: [%s]\n", tmp_addr.get_ip()); + myexit(-1); + } else if (found == 1) { + mylog(log_info, "using device:[%s], ip: [%s]\n", dev, tmp_addr.get_ip()); + } else { + mylog(log_fatal, "more than one devices found for ip: [%s] , you need to use --dev manually\n", tmp_addr.get_ip()); + myexit(-1); + } + } else { + mylog(log_info, "--dev has been manually set, using device:[%s]\n", dev); + } #endif - send_info.src_port=0; - memset(&send_info.new_src_ip,0,sizeof(send_info.new_src_ip)); + send_info.src_port = 0; + memset(&send_info.new_src_ip, 0, sizeof(send_info.new_src_ip)); - int i, j, k;int ret; + int i, j, k; + int ret; + send_info.new_dst_ip.from_address_t(remote_addr); + send_info.dst_port = remote_addr.get_port(); - send_info.new_dst_ip.from_address_t(remote_addr); - send_info.dst_port=remote_addr.get_port(); + udp_fd = socket(local_addr.get_type(), SOCK_DGRAM, IPPROTO_UDP); + set_buf_size(udp_fd, socket_buf_size); + if (::bind(udp_fd, (struct sockaddr *)&local_addr.inner, local_addr.get_len()) == -1) { + mylog(log_fatal, "socket bind error\n"); + // perror("socket bind error"); + myexit(1); + } + setnonblocking(udp_fd); - udp_fd=socket(local_addr.get_type(), SOCK_DGRAM, IPPROTO_UDP); - set_buf_size(udp_fd,socket_buf_size); + // 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); + // } - if (::bind(udp_fd, (struct sockaddr*) &local_addr.inner, local_addr.get_len()) == -1) { - mylog(log_fatal,"socket bind error\n"); - //perror("socket bind error"); - myexit(1); - } - setnonblocking(udp_fd); + struct ev_loop *loop = ev_default_loop(0); + assert(loop != NULL); - //epollfd = epoll_create1(0); + // 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); + // } - //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_io udp_accept_watcher; - 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; + 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; - //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); - //} + // ret = epoll_ctl(epollfd, EPOLL_CTL_ADD, raw_recv_fd, &ev); + // if (ret!= 0) { + // mylog(log_fatal,"add raw_fd error\n"); + // myexit(-1); + // } #ifdef UDP2RAW_LINUX - struct ev_io raw_recv_watcher; + struct ev_io raw_recv_watcher; - raw_recv_watcher.data=&conn_info; + raw_recv_watcher.data = &conn_info; ev_io_init(&raw_recv_watcher, raw_recv_cb, raw_recv_fd, EV_READ); ev_io_start(loop, &raw_recv_watcher); #endif #ifdef UDP2RAW_MP - g_default_loop=loop; - async_watcher.data=&conn_info; - ev_async_init(&async_watcher,async_cb); - ev_async_start(loop,&async_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();//must be put after dev detection + init_raw_socket(); // must be put after dev detection #endif - //set_timer(epollfd,timer_fd); - struct ev_timer clear_timer; + // 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); + 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 %s %d to %s %d\n",send_info.new_src_ip.get_str1(),send_info.src_port,send_info.new_dst_ip.get_str2(),send_info.dst_port); + mylog(log_debug, "send_raw : from %s %d to %s %d\n", send_info.new_src_ip.get_str1(), send_info.src_port, send_info.new_dst_ip.get_str2(), send_info.dst_port); - int fifo_fd=-1; + int fifo_fd = -1; - struct ev_io fifo_watcher; - fifo_watcher.data=&conn_info; + struct ev_io fifo_watcher; + fifo_watcher.data = &conn_info; - if(fifo_file[0]!=0) - { - fifo_fd=create_fifo(fifo_file); + 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); + 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); - } + mylog(log_info, "fifo_file=%s\n", fifo_file); + } - ev_run(loop, 0); - return 0; + ev_run(loop, 0); + return 0; } diff --git a/common.cpp b/common.cpp index 138d41e..ffcddde 100644 --- a/common.cpp +++ b/common.cpp @@ -12,561 +12,470 @@ #include #include -//static int random_number_fd=-1; -int force_socket_buf=0; +// static int random_number_fd=-1; +int force_socket_buf = 0; -int address_t::from_str(char *str) -{ - clear(); +int address_t::from_str(char *str) { + clear(); - char ip_addr_str[100];u32_t port; - mylog(log_info,"parsing address: %s\n",str); - int is_ipv6=0; - if(sscanf(str, "[%[^]]]:%u", ip_addr_str,&port)==2) - { - mylog(log_info,"its an ipv6 adress\n"); - inner.ipv6.sin6_family=AF_INET6; - is_ipv6=1; - } - else if(sscanf(str, "%[^:]:%u", ip_addr_str,&port)==2) - { - mylog(log_info,"its an ipv4 adress\n"); - inner.ipv4.sin_family=AF_INET; - } - else - { - mylog(log_error,"failed to parse\n"); - myexit(-1); - } + char ip_addr_str[100]; + u32_t port; + mylog(log_info, "parsing address: %s\n", str); + int is_ipv6 = 0; + if (sscanf(str, "[%[^]]]:%u", ip_addr_str, &port) == 2) { + mylog(log_info, "its an ipv6 adress\n"); + inner.ipv6.sin6_family = AF_INET6; + is_ipv6 = 1; + } else if (sscanf(str, "%[^:]:%u", ip_addr_str, &port) == 2) { + mylog(log_info, "its an ipv4 adress\n"); + inner.ipv4.sin_family = AF_INET; + } else { + mylog(log_error, "failed to parse\n"); + myexit(-1); + } - mylog(log_info,"ip_address is {%s}, port is {%u}\n",ip_addr_str,port); + mylog(log_info, "ip_address is {%s}, port is {%u}\n", ip_addr_str, port); - if(port>65535) - { - mylog(log_error,"invalid port: %d\n",port); - myexit(-1); - } + if (port > 65535) { + mylog(log_error, "invalid port: %d\n", port); + myexit(-1); + } - int ret=-100; - if(is_ipv6) - { - ret=inet_pton(AF_INET6, ip_addr_str,&(inner.ipv6.sin6_addr)); - inner.ipv6.sin6_port=htons(port); - if(ret==0) // 0 if address type doesnt match - { - mylog(log_error,"ip_addr %s is not an ipv6 address, %d\n",ip_addr_str,ret); - myexit(-1); - } - else if(ret==1) // inet_pton returns 1 on success - { - //okay - } - else - { - mylog(log_error,"ip_addr %s is invalid, %d\n",ip_addr_str,ret); - myexit(-1); - } - } - else - { - ret=inet_pton(AF_INET, ip_addr_str,&(inner.ipv4.sin_addr)); - inner.ipv4.sin_port=htons(port); + int ret = -100; + if (is_ipv6) { + ret = inet_pton(AF_INET6, ip_addr_str, &(inner.ipv6.sin6_addr)); + inner.ipv6.sin6_port = htons(port); + if (ret == 0) // 0 if address type doesnt match + { + mylog(log_error, "ip_addr %s is not an ipv6 address, %d\n", ip_addr_str, ret); + myexit(-1); + } else if (ret == 1) // inet_pton returns 1 on success + { + // okay + } else { + mylog(log_error, "ip_addr %s is invalid, %d\n", ip_addr_str, ret); + myexit(-1); + } + } else { + ret = inet_pton(AF_INET, ip_addr_str, &(inner.ipv4.sin_addr)); + inner.ipv4.sin_port = htons(port); - if(ret==0) - { - mylog(log_error,"ip_addr %s is not an ipv4 address, %d\n",ip_addr_str,ret); - myexit(-1); - } - else if(ret==1) - { - //okay - } - else - { - mylog(log_error,"ip_addr %s is invalid, %d\n",ip_addr_str,ret); - myexit(-1); - } - } + if (ret == 0) { + mylog(log_error, "ip_addr %s is not an ipv4 address, %d\n", ip_addr_str, ret); + myexit(-1); + } else if (ret == 1) { + // okay + } else { + mylog(log_error, "ip_addr %s is invalid, %d\n", ip_addr_str, ret); + myexit(-1); + } + } - return 0; + return 0; } -int address_t::from_str_ip_only(char * str) -{ - clear(); +int address_t::from_str_ip_only(char *str) { + clear(); - u32_t type; + u32_t type; - if(strchr(str,':')==NULL) - type=AF_INET; - else - type=AF_INET6; + if (strchr(str, ':') == NULL) + type = AF_INET; + else + type = AF_INET6; - ((sockaddr*)&inner)->sa_family=type; + ((sockaddr *)&inner)->sa_family = type; - int ret; - if(type==AF_INET) - { - ret=inet_pton(type, str,&inner.ipv4.sin_addr); - } - else - { - ret=inet_pton(type, str,&inner.ipv6.sin6_addr); - } + int ret; + if (type == AF_INET) { + ret = inet_pton(type, str, &inner.ipv4.sin_addr); + } else { + ret = inet_pton(type, str, &inner.ipv6.sin6_addr); + } - if(ret==0) // 0 if address type doesnt match - { - mylog(log_error,"confusion in parsing %s, %d\n",str,ret); - myexit(-1); - } - else if(ret==1) // inet_pton returns 1 on success - { - //okay - } - else - { - mylog(log_error,"ip_addr %s is invalid, %d\n",str,ret); - myexit(-1); - } - return 0; + if (ret == 0) // 0 if address type doesnt match + { + mylog(log_error, "confusion in parsing %s, %d\n", str, ret); + myexit(-1); + } else if (ret == 1) // inet_pton returns 1 on success + { + // okay + } else { + mylog(log_error, "ip_addr %s is invalid, %d\n", str, ret); + myexit(-1); + } + return 0; } -char * address_t::get_str() -{ - static char res[max_addr_len]; - to_str(res); - return res; +char *address_t::get_str() { + static char res[max_addr_len]; + to_str(res); + return res; } -void address_t::to_str(char * s) -{ - //static char res[max_addr_len]; - char ip_addr[max_addr_len]; - u32_t port; - const char * ret=0; - if(get_type()==AF_INET6) - { - ret=inet_ntop(AF_INET6, &inner.ipv6.sin6_addr, ip_addr,max_addr_len); - port=inner.ipv6.sin6_port; - } - else if(get_type()==AF_INET) - { - ret=inet_ntop(AF_INET, &inner.ipv4.sin_addr, ip_addr,max_addr_len); - port=inner.ipv4.sin_port; - } - else - { - assert(0==1); - } +void address_t::to_str(char *s) { + // static char res[max_addr_len]; + char ip_addr[max_addr_len]; + u32_t port; + const char *ret = 0; + if (get_type() == AF_INET6) { + ret = inet_ntop(AF_INET6, &inner.ipv6.sin6_addr, ip_addr, max_addr_len); + port = inner.ipv6.sin6_port; + } else if (get_type() == AF_INET) { + ret = inet_ntop(AF_INET, &inner.ipv4.sin_addr, ip_addr, max_addr_len); + port = inner.ipv4.sin_port; + } else { + assert(0 == 1); + } - if(ret==0) //NULL on failure - { - mylog(log_error,"inet_ntop failed\n"); - myexit(-1); - } + if (ret == 0) // NULL on failure + { + mylog(log_error, "inet_ntop failed\n"); + myexit(-1); + } - port=ntohs(port); + port = ntohs(port); - ip_addr[max_addr_len-1]=0; - if(get_type()==AF_INET6) - { - sprintf(s,"[%s]:%u",ip_addr,(u32_t)port); - }else - { - sprintf(s,"%s:%u",ip_addr,(u32_t)port); - } + ip_addr[max_addr_len - 1] = 0; + if (get_type() == AF_INET6) { + sprintf(s, "[%s]:%u", ip_addr, (u32_t)port); + } else { + sprintf(s, "%s:%u", ip_addr, (u32_t)port); + } - //return res; + // return res; } -char* address_t::get_ip() -{ - char ip_addr[max_addr_len]; - static char s[max_addr_len]; - const char * ret=0; - if(get_type()==AF_INET6) - { - ret=inet_ntop(AF_INET6, &inner.ipv6.sin6_addr, ip_addr,max_addr_len); - } - else if(get_type()==AF_INET) - { - ret=inet_ntop(AF_INET, &inner.ipv4.sin_addr, ip_addr,max_addr_len); - } - else - { - assert(0==1); - } +char *address_t::get_ip() { + char ip_addr[max_addr_len]; + static char s[max_addr_len]; + const char *ret = 0; + if (get_type() == AF_INET6) { + ret = inet_ntop(AF_INET6, &inner.ipv6.sin6_addr, ip_addr, max_addr_len); + } else if (get_type() == AF_INET) { + ret = inet_ntop(AF_INET, &inner.ipv4.sin_addr, ip_addr, max_addr_len); + } else { + assert(0 == 1); + } - if(ret==0) //NULL on failure - { - mylog(log_error,"inet_ntop failed\n"); - myexit(-1); - } + if (ret == 0) // NULL on failure + { + mylog(log_error, "inet_ntop failed\n"); + myexit(-1); + } - ip_addr[max_addr_len-1]=0; - if(get_type()==AF_INET6) - { - sprintf(s,"%s",ip_addr); - }else - { - sprintf(s,"%s",ip_addr); - } + ip_addr[max_addr_len - 1] = 0; + if (get_type() == AF_INET6) { + sprintf(s, "%s", ip_addr); + } else { + sprintf(s, "%s", ip_addr); + } - return s; + return s; } -int address_t::from_sockaddr(sockaddr * addr,socklen_t slen) -{ - clear(); - //memset(&inner,0,sizeof(inner)); - if(addr->sa_family==AF_INET6) - { - assert(slen==sizeof(sockaddr_in6)); - //inner.ipv6= *( (sockaddr_in6*) addr ); - memcpy(&inner,addr,slen); - } - else if(addr->sa_family==AF_INET) - { - assert(slen==sizeof(sockaddr_in)); - //inner.ipv4= *( (sockaddr_in*) addr ); - memcpy(&inner,addr,slen); - } - else - { - assert(0==1); - } - return 0; +int address_t::from_sockaddr(sockaddr *addr, socklen_t slen) { + clear(); + // memset(&inner,0,sizeof(inner)); + if (addr->sa_family == AF_INET6) { + assert(slen == sizeof(sockaddr_in6)); + // inner.ipv6= *( (sockaddr_in6*) addr ); + memcpy(&inner, addr, slen); + } else if (addr->sa_family == AF_INET) { + assert(slen == sizeof(sockaddr_in)); + // inner.ipv4= *( (sockaddr_in*) addr ); + memcpy(&inner, addr, slen); + } else { + assert(0 == 1); + } + return 0; } -int address_t::new_connected_udp_fd() -{ +int address_t::new_connected_udp_fd() { + int new_udp_fd; + new_udp_fd = socket(get_type(), SOCK_DGRAM, IPPROTO_UDP); + if (new_udp_fd < 0) { + mylog(log_warn, "create udp_fd error\n"); + return -1; + } + setnonblocking(new_udp_fd); + set_buf_size(new_udp_fd, socket_buf_size); - int new_udp_fd; - new_udp_fd = socket(get_type(), SOCK_DGRAM, IPPROTO_UDP); - if (new_udp_fd < 0) { - mylog(log_warn, "create udp_fd error\n"); - return -1; - } - setnonblocking(new_udp_fd); - set_buf_size(new_udp_fd,socket_buf_size); + mylog(log_debug, "created new udp_fd %d\n", new_udp_fd); + int ret = connect(new_udp_fd, (struct sockaddr *)&inner, get_len()); + if (ret != 0) { + mylog(log_warn, "udp fd connect fail %d %s\n", ret, strerror(errno)); + // sock_close(new_udp_fd); + close(new_udp_fd); + return -1; + } - mylog(log_debug, "created new udp_fd %d\n", new_udp_fd); - int ret = connect(new_udp_fd, (struct sockaddr *) &inner, get_len()); - if (ret != 0) { - mylog(log_warn, "udp fd connect fail %d %s\n",ret,strerror(errno) ); - //sock_close(new_udp_fd); - close(new_udp_fd); - return -1; - } - - return new_udp_fd; + return new_udp_fd; } -bool my_ip_t::equal (const my_ip_t &b) const -{ - //extern int raw_ip_version; - if(raw_ip_version==AF_INET) - { - return v4==b.v4; - }else if(raw_ip_version==AF_INET6) - { - return memcmp(&v6,&b.v6,sizeof(v6))==0; - } - assert(0==1); - return 0; +bool my_ip_t::equal(const my_ip_t &b) const { + // extern int raw_ip_version; + if (raw_ip_version == AF_INET) { + return v4 == b.v4; + } else if (raw_ip_version == AF_INET6) { + return memcmp(&v6, &b.v6, sizeof(v6)) == 0; + } + assert(0 == 1); + return 0; } -char * my_ip_t::get_str1() const -{ - static char res[max_addr_len]; - if(raw_ip_version==AF_INET6) - { - assert(inet_ntop(AF_INET6, &v6, res,max_addr_len)!=0); - } - else - { - assert(raw_ip_version==AF_INET); - assert(inet_ntop(AF_INET, &v4, res,max_addr_len)!=0); - } - return res; +char *my_ip_t::get_str1() const { + static char res[max_addr_len]; + if (raw_ip_version == AF_INET6) { + assert(inet_ntop(AF_INET6, &v6, res, max_addr_len) != 0); + } else { + assert(raw_ip_version == AF_INET); + assert(inet_ntop(AF_INET, &v4, res, max_addr_len) != 0); + } + return res; } -char * my_ip_t::get_str2() const -{ - static char res[max_addr_len]; - if(raw_ip_version==AF_INET6) - { - assert(inet_ntop(AF_INET6, &v6, res,max_addr_len)!=0); - } - else - { - assert(raw_ip_version==AF_INET); - assert(inet_ntop(AF_INET, &v4, res,max_addr_len)!=0); - } - return res; +char *my_ip_t::get_str2() const { + static char res[max_addr_len]; + if (raw_ip_version == AF_INET6) { + assert(inet_ntop(AF_INET6, &v6, res, max_addr_len) != 0); + } else { + assert(raw_ip_version == AF_INET); + assert(inet_ntop(AF_INET, &v4, res, max_addr_len) != 0); + } + return res; } -int my_ip_t::from_address_t(address_t tmp_addr) -{ - if(tmp_addr.get_type()==raw_ip_version&&raw_ip_version==AF_INET) - { - v4=tmp_addr.inner.ipv4.sin_addr.s_addr; - } - else if(tmp_addr.get_type()==raw_ip_version&&raw_ip_version==AF_INET6) - { - v6=tmp_addr.inner.ipv6.sin6_addr; - } - else - { - assert(0==1); - } - return 0; +int my_ip_t::from_address_t(address_t tmp_addr) { + if (tmp_addr.get_type() == raw_ip_version && raw_ip_version == AF_INET) { + v4 = tmp_addr.inner.ipv4.sin_addr.s_addr; + } else if (tmp_addr.get_type() == raw_ip_version && raw_ip_version == AF_INET6) { + v6 = tmp_addr.inner.ipv6.sin6_addr; + } else { + assert(0 == 1); + } + return 0; } /* int my_ip_t::from_str(char * str) { - u32_t type; - if(strchr(str,':')==NULL) - type=AF_INET; - else - type=AF_INET6; - int ret; - ret=inet_pton(type, str,this); - if(ret==0) // 0 if address type doesnt match - { - mylog(log_error,"confusion in parsing %s, %d\n",str,ret); - myexit(-1); - } - else if(ret==1) // inet_pton returns 1 on success - { - //okay - } - else - { - mylog(log_error,"ip_addr %s is invalid, %d\n",str,ret); - myexit(-1); - } - return 0; -}*/ -#ifdef UDP2RAW_MP - -int init_ws() -{ -#if defined(__MINGW32__) - WORD wVersionRequested; - WSADATA wsaData; - int err; - - /* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */ - wVersionRequested = MAKEWORD(2, 2); - - err = WSAStartup(wVersionRequested, &wsaData); - if (err != 0) { - /* Tell the user that we could not find a usable */ - /* Winsock DLL. */ - printf("WSAStartup failed with error: %d\n", err); - exit(-1); - } - - /* Confirm that the WinSock DLL supports 2.2.*/ - /* Note that if the DLL supports versions greater */ - /* than 2.2 in addition to 2.2, it will still return */ - /* 2.2 in wVersion since that is the version we */ - /* requested. */ - - if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) { - /* Tell the user that we could not find a usable */ - /* WinSock DLL. */ - printf("Could not find a usable version of Winsock.dll\n"); - WSACleanup(); - exit(-1); - } - else - { - printf("The Winsock 2.2 dll was found okay"); - } - - int tmp[]={0,100,200,300,500,800,1000,2000,3000,4000,-1}; - int succ=0; - for(int i=1;tmp[i]!=-1;i++) - { - if(_setmaxstdio(100)==-1) break; - else succ=i; - } - printf(", _setmaxstdio() was set to %d\n",tmp[succ]); -#endif -return 0; -} - -#endif - -#if defined(__MINGW32__) -int inet_pton(int af, const char *src, void *dst) -{ - struct sockaddr_storage ss; - int size = sizeof(ss); - char src_copy[max_addr_len+1]; - - ZeroMemory(&ss, sizeof(ss)); - /* stupid non-const API */ - strncpy (src_copy, src, max_addr_len+1); - src_copy[max_addr_len] = 0; - - if (WSAStringToAddress(src_copy, af, NULL, (struct sockaddr *)&ss, &size) == 0) { - switch(af) { - case AF_INET: - *(struct in_addr *)dst = ((struct sockaddr_in *)&ss)->sin_addr; - return 1; - case AF_INET6: - *(struct in6_addr *)dst = ((struct sockaddr_in6 *)&ss)->sin6_addr; - return 1; - } - } - return 0; -} - -const char *inet_ntop(int af, const void *src, char *dst, socklen_t size) -{ - struct sockaddr_storage ss; - unsigned long s = size; - - ZeroMemory(&ss, sizeof(ss)); - ss.ss_family = af; - - switch(af) { - case AF_INET: - ((struct sockaddr_in *)&ss)->sin_addr = *(struct in_addr *)src; - break; - case AF_INET6: - ((struct sockaddr_in6 *)&ss)->sin6_addr = *(struct in6_addr *)src; - break; - default: - return NULL; - } - /* cannot direclty use &size because of strict aliasing rules */ - return (WSAAddressToString((struct sockaddr *)&ss, sizeof(ss), NULL, dst, &s) == 0)? - dst : NULL; -} -char *get_sock_error() -{ - static char buf[1000]; - int e=WSAGetLastError(); - wchar_t *s = NULL; - FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, e, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPWSTR)&s, 0, NULL); - sprintf(buf, "%d:%S", e,s); - int len=strlen(buf); - while(len>0 && (buf[len-1]=='\r'||buf[len-1]=='\n' )) - { - len--; - buf[len]=0; - } - LocalFree(s); - return buf; -} -int get_sock_errno() -{ - return WSAGetLastError(); -} -#else -char *get_sock_error() -{ - static char buf[1000]; - sprintf(buf, "%d:%s", errno,strerror(errno)); - return buf; -} -int get_sock_errno() -{ - return errno; -} -#endif - - -u64_t get_current_time_us() -{ - static u64_t value_fix=0; - static u64_t largest_value=0; - - u64_t raw_value=(u64_t)(ev_time()*1000*1000); - - u64_t fixed_value=raw_value+value_fix; - - if(fixed_value< largest_value) + u32_t type; + if(strchr(str,':')==NULL) + type=AF_INET; + else + type=AF_INET6; + int ret; + ret=inet_pton(type, str,this); + if(ret==0) // 0 if address type doesnt match { - value_fix+= largest_value- fixed_value; + mylog(log_error,"confusion in parsing %s, %d\n",str,ret); + myexit(-1); + } + else if(ret==1) // inet_pton returns 1 on success + { + //okay } else { - largest_value=fixed_value; + mylog(log_error,"ip_addr %s is invalid, %d\n",str,ret); + myexit(-1); } + return 0; +}*/ +#ifdef UDP2RAW_MP - //printf("<%lld,%lld,%lld>\n",raw_value,value_fix,raw_value + value_fix); - return raw_value + value_fix; //new fixed value +int init_ws() { +#if defined(__MINGW32__) + WORD wVersionRequested; + WSADATA wsaData; + int err; + + /* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */ + wVersionRequested = MAKEWORD(2, 2); + + err = WSAStartup(wVersionRequested, &wsaData); + if (err != 0) { + /* Tell the user that we could not find a usable */ + /* Winsock DLL. */ + printf("WSAStartup failed with error: %d\n", err); + exit(-1); + } + + /* Confirm that the WinSock DLL supports 2.2.*/ + /* Note that if the DLL supports versions greater */ + /* than 2.2 in addition to 2.2, it will still return */ + /* 2.2 in wVersion since that is the version we */ + /* requested. */ + + if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) { + /* Tell the user that we could not find a usable */ + /* WinSock DLL. */ + printf("Could not find a usable version of Winsock.dll\n"); + WSACleanup(); + exit(-1); + } else { + printf("The Winsock 2.2 dll was found okay"); + } + + int tmp[] = {0, 100, 200, 300, 500, 800, 1000, 2000, 3000, 4000, -1}; + int succ = 0; + for (int i = 1; tmp[i] != -1; i++) { + if (_setmaxstdio(100) == -1) + break; + else + succ = i; + } + printf(", _setmaxstdio() was set to %d\n", tmp[succ]); +#endif + return 0; } -u64_t get_current_time() -{ - return get_current_time_us()/1000; +#endif + +#if defined(__MINGW32__) +int inet_pton(int af, const char *src, void *dst) { + struct sockaddr_storage ss; + int size = sizeof(ss); + char src_copy[max_addr_len + 1]; + + ZeroMemory(&ss, sizeof(ss)); + /* stupid non-const API */ + strncpy(src_copy, src, max_addr_len + 1); + src_copy[max_addr_len] = 0; + + if (WSAStringToAddress(src_copy, af, NULL, (struct sockaddr *)&ss, &size) == 0) { + switch (af) { + case AF_INET: + *(struct in_addr *)dst = ((struct sockaddr_in *)&ss)->sin_addr; + return 1; + case AF_INET6: + *(struct in6_addr *)dst = ((struct sockaddr_in6 *)&ss)->sin6_addr; + return 1; + } + } + return 0; } -u64_t pack_u64(u32_t a,u32_t b) -{ - u64_t ret=a; - ret<<=32u; - ret+=b; - return ret; +const char *inet_ntop(int af, const void *src, char *dst, socklen_t size) { + struct sockaddr_storage ss; + unsigned long s = size; + + ZeroMemory(&ss, sizeof(ss)); + ss.ss_family = af; + + switch (af) { + case AF_INET: + ((struct sockaddr_in *)&ss)->sin_addr = *(struct in_addr *)src; + break; + case AF_INET6: + ((struct sockaddr_in6 *)&ss)->sin6_addr = *(struct in6_addr *)src; + break; + default: + return NULL; + } + /* cannot direclty use &size because of strict aliasing rules */ + return (WSAAddressToString((struct sockaddr *)&ss, sizeof(ss), NULL, dst, &s) == 0) ? dst : NULL; } -u32_t get_u64_h(u64_t a) -{ - return a>>32u; +char *get_sock_error() { + static char buf[1000]; + int e = WSAGetLastError(); + wchar_t *s = NULL; + FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, e, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPWSTR)&s, 0, NULL); + sprintf(buf, "%d:%S", e, s); + int len = strlen(buf); + while (len > 0 && (buf[len - 1] == '\r' || buf[len - 1] == '\n')) { + len--; + buf[len] = 0; + } + LocalFree(s); + return buf; } -u32_t get_u64_l(u64_t a) -{ - return (a<<32u)>>32u; +int get_sock_errno() { + return WSAGetLastError(); +} +#else +char *get_sock_error() { + static char buf[1000]; + sprintf(buf, "%d:%s", errno, strerror(errno)); + return buf; +} +int get_sock_errno() { + return errno; +} +#endif + +u64_t get_current_time_us() { + static u64_t value_fix = 0; + static u64_t largest_value = 0; + + u64_t raw_value = (u64_t)(ev_time() * 1000 * 1000); + + u64_t fixed_value = raw_value + value_fix; + + if (fixed_value < largest_value) { + value_fix += largest_value - fixed_value; + } else { + largest_value = fixed_value; + } + + // printf("<%lld,%lld,%lld>\n",raw_value,value_fix,raw_value + value_fix); + return raw_value + value_fix; // new fixed value } -char * my_ntoa(u32_t ip) -{ - in_addr a; - a.s_addr=ip; - return inet_ntoa(a); +u64_t get_current_time() { + return get_current_time_us() / 1000; +} + +u64_t pack_u64(u32_t a, u32_t b) { + u64_t ret = a; + ret <<= 32u; + ret += b; + return ret; +} +u32_t get_u64_h(u64_t a) { + return a >> 32u; +} +u32_t get_u64_l(u64_t a) { + return (a << 32u) >> 32u; +} + +char *my_ntoa(u32_t ip) { + in_addr a; + a.s_addr = ip; + return inet_ntoa(a); } /* void init_random_number_fd() { - random_number_fd=open("/dev/urandom",O_RDONLY); + random_number_fd=open("/dev/urandom",O_RDONLY); - if(random_number_fd==-1) - { - mylog(log_fatal,"error open /dev/urandom\n"); - myexit(-1); - } - setnonblocking(random_number_fd); + if(random_number_fd==-1) + { + mylog(log_fatal,"error open /dev/urandom\n"); + myexit(-1); + } + setnonblocking(random_number_fd); }*/ #if !defined(__MINGW32__) -struct random_fd_t -{ - int random_number_fd; - random_fd_t() - { - random_number_fd=open("/dev/urandom",O_RDONLY); +struct random_fd_t { + int random_number_fd; + random_fd_t() { + random_number_fd = open("/dev/urandom", O_RDONLY); - if(random_number_fd==-1) - { - mylog(log_fatal,"error open /dev/urandom\n"); - myexit(-1); - } - setnonblocking(random_number_fd); - } - int get_fd() - { - return random_number_fd; - } -}random_fd; + if (random_number_fd == -1) { + mylog(log_fatal, "error open /dev/urandom\n"); + myexit(-1); + } + setnonblocking(random_number_fd); + } + int get_fd() { + return random_number_fd; + } +} random_fd; #else -struct my_random_t -{ +struct my_random_t { std::random_device rd; std::mt19937 gen; std::uniform_int_distribution dis64; @@ -574,171 +483,152 @@ struct my_random_t std::uniform_int_distribution dis8; - my_random_t() - { - //std::mt19937 gen_tmp(rd()); //random device is broken on mingw - timespec tmp_time; - clock_gettime(CLOCK_MONOTONIC, &tmp_time); - long long a=((u64_t)tmp_time.tv_sec)*1000000000llu+((u64_t)tmp_time.tv_nsec); - std::mt19937 gen_tmp(a); - gen=gen_tmp; - gen.discard(700000); //magic - } - u64_t gen64() - { - return dis64(gen); + my_random_t() { + // std::mt19937 gen_tmp(rd()); //random device is broken on mingw + timespec tmp_time; + clock_gettime(CLOCK_MONOTONIC, &tmp_time); + long long a = ((u64_t)tmp_time.tv_sec) * 1000000000llu + ((u64_t)tmp_time.tv_nsec); + std::mt19937 gen_tmp(a); + gen = gen_tmp; + gen.discard(700000); // magic } - u32_t gen32() - { - return dis32(gen); + u64_t gen64() { + return dis64(gen); + } + u32_t gen32() { + return dis32(gen); } - unsigned char gen8() - { - return dis8(gen); + unsigned char gen8() { + return dis8(gen); } - /*int random_number_fd; - random_fd_t() - { - random_number_fd=open("/dev/urandom",O_RDONLY); - if(random_number_fd==-1) - { - mylog(log_fatal,"error open /dev/urandom\n"); - myexit(-1); - } - setnonblocking(random_number_fd); - } - int get_fd() - { - return random_number_fd; - }*/ -}my_random; + /*int random_number_fd; + random_fd_t() + { + random_number_fd=open("/dev/urandom",O_RDONLY); + if(random_number_fd==-1) + { + mylog(log_fatal,"error open /dev/urandom\n"); + myexit(-1); + } + setnonblocking(random_number_fd); + } + int get_fd() + { + return random_number_fd; + }*/ +} my_random; #endif -u64_t get_true_random_number_64() -{ +u64_t get_true_random_number_64() { #if !defined(__MINGW32__) - u64_t ret; - int size=read(random_fd.get_fd(),&ret,sizeof(ret)); - if(size!=sizeof(ret)) - { - mylog(log_fatal,"get random number failed %d\n",size); - myexit(-1); - } - return ret; + u64_t ret; + int size = read(random_fd.get_fd(), &ret, sizeof(ret)); + if (size != sizeof(ret)) { + mylog(log_fatal, "get random number failed %d\n", size); + myexit(-1); + } + return ret; #else - return my_random.gen64(); //fake random number + return my_random.gen64(); // fake random number #endif } -u32_t get_true_random_number() -{ +u32_t get_true_random_number() { #if !defined(__MINGW32__) - u32_t ret; - int size=read(random_fd.get_fd(),&ret,sizeof(ret)); - if(size!=sizeof(ret)) - { - mylog(log_fatal,"get random number failed %d\n",size); - myexit(-1); - } - return ret; + u32_t ret; + int size = read(random_fd.get_fd(), &ret, sizeof(ret)); + if (size != sizeof(ret)) { + mylog(log_fatal, "get random number failed %d\n", size); + myexit(-1); + } + return ret; #else - return my_random.gen32(); //fake random number + return my_random.gen32(); // fake random number #endif } -u32_t get_true_random_number_nz() //nz for non-zero +u32_t get_true_random_number_nz() // nz for non-zero { - u32_t ret=0; - while(ret==0) - { - ret=get_true_random_number(); - } - return ret; + u32_t ret = 0; + while (ret == 0) { + ret = get_true_random_number(); + } + return ret; } -inline int is_big_endian() -{ - int i=1; - return ! *((char *)&i); +inline int is_big_endian() { + int i = 1; + return !*((char *)&i); } -u64_t ntoh64(u64_t a) -{ - #ifdef UDP2RAW_LITTLE_ENDIAN - u32_t h=get_u64_h(a); - u32_t l=get_u64_l(a); - return pack_u64(ntohl(l),ntohl(h)); - //return bswap_64( a); - #else - return a; - #endif - +u64_t ntoh64(u64_t a) { +#ifdef UDP2RAW_LITTLE_ENDIAN + u32_t h = get_u64_h(a); + u32_t l = get_u64_l(a); + return pack_u64(ntohl(l), ntohl(h)); + // return bswap_64( a); +#else + return a; +#endif } -u64_t hton64(u64_t a) -{ - return ntoh64(a); +u64_t hton64(u64_t a) { + return ntoh64(a); } -void write_u16(char * p,u16_t w) -{ - *(unsigned char*)(p + 1) = (w & 0xff); - *(unsigned char*)(p + 0) = (w >> 8); +void write_u16(char *p, u16_t w) { + *(unsigned char *)(p + 1) = (w & 0xff); + *(unsigned char *)(p + 0) = (w >> 8); } -u16_t read_u16(char * p) -{ - u16_t res; - res = *(const unsigned char*)(p + 0); - res = *(const unsigned char*)(p + 1) + (res << 8); - return res; +u16_t read_u16(char *p) { + u16_t res; + res = *(const unsigned char *)(p + 0); + res = *(const unsigned char *)(p + 1) + (res << 8); + return res; } -void write_u32(char * p,u32_t l) -{ - *(unsigned char*)(p + 3) = (unsigned char)((l >> 0) & 0xff); - *(unsigned char*)(p + 2) = (unsigned char)((l >> 8) & 0xff); - *(unsigned char*)(p + 1) = (unsigned char)((l >> 16) & 0xff); - *(unsigned char*)(p + 0) = (unsigned char)((l >> 24) & 0xff); +void write_u32(char *p, u32_t l) { + *(unsigned char *)(p + 3) = (unsigned char)((l >> 0) & 0xff); + *(unsigned char *)(p + 2) = (unsigned char)((l >> 8) & 0xff); + *(unsigned char *)(p + 1) = (unsigned char)((l >> 16) & 0xff); + *(unsigned char *)(p + 0) = (unsigned char)((l >> 24) & 0xff); } -u32_t read_u32(char * p) -{ - u32_t res; - res = *(const unsigned char*)(p + 0); - res = *(const unsigned char*)(p + 1) + (res << 8); - res = *(const unsigned char*)(p + 2) + (res << 8); - res = *(const unsigned char*)(p + 3) + (res << 8); - return res; +u32_t read_u32(char *p) { + u32_t res; + res = *(const unsigned char *)(p + 0); + res = *(const unsigned char *)(p + 1) + (res << 8); + res = *(const unsigned char *)(p + 2) + (res << 8); + res = *(const unsigned char *)(p + 3) + (res << 8); + return res; } -void write_u64(char * s,u64_t a) -{ - assert(0==1); +void write_u64(char *s, u64_t a) { + assert(0 == 1); } -u64_t read_u64(char * s) -{ - assert(0==1); - return 0; +u64_t read_u64(char *s) { + assert(0 == 1); + return 0; } void setnonblocking(int sock) { #if !defined(__MINGW32__) - int opts; - opts = fcntl(sock, F_GETFL); + int opts; + opts = fcntl(sock, F_GETFL); - if (opts < 0) { - mylog(log_fatal,"fcntl(sock,GETFL)\n"); - //perror("fcntl(sock,GETFL)"); - myexit(1); - } - opts = opts | O_NONBLOCK; - if (fcntl(sock, F_SETFL, opts) < 0) { - mylog(log_fatal,"fcntl(sock,SETFL,opts)\n"); - //perror("fcntl(sock,SETFL,opts)"); - myexit(1); - } + if (opts < 0) { + mylog(log_fatal, "fcntl(sock,GETFL)\n"); + // perror("fcntl(sock,GETFL)"); + myexit(1); + } + opts = opts | O_NONBLOCK; + if (fcntl(sock, F_SETFL, opts) < 0) { + mylog(log_fatal, "fcntl(sock,SETFL,opts)\n"); + // perror("fcntl(sock,SETFL,opts)"); + myexit(1); + } #else - int iResult; - u_long iMode = 1; - iResult = ioctlsocket(sock, FIONBIO, &iMode); - if (iResult != NO_ERROR) - printf("ioctlsocket failed with error: %d\n", iResult); + int iResult; + u_long iMode = 1; + iResult = ioctlsocket(sock, FIONBIO, &iMode); + if (iResult != NO_ERROR) + printf("ioctlsocket failed with error: %d\n", iResult); #endif } @@ -746,372 +636,327 @@ void setnonblocking(int sock) { /* Generic checksum calculation function */ -unsigned short csum(const unsigned short *ptr,int nbytes) {//works both for big and little endian +unsigned short csum(const unsigned short *ptr, int nbytes) { // works both for big and little endian long sum; unsigned short oddbyte; short answer; - sum=0; - while(nbytes>1) { - sum+=*ptr++; - nbytes-=2; + sum = 0; + while (nbytes > 1) { + sum += *ptr++; + nbytes -= 2; } - if(nbytes==1) { - oddbyte=0; - *((u_char*)&oddbyte)=*(u_char*)ptr; - sum+=oddbyte; + if (nbytes == 1) { + oddbyte = 0; + *((u_char *)&oddbyte) = *(u_char *)ptr; + sum += oddbyte; } - sum = (sum>>16)+(sum & 0xffff); - sum = sum + (sum>>16); - answer=(short)~sum; + sum = (sum >> 16) + (sum & 0xffff); + sum = sum + (sum >> 16); + answer = (short)~sum; - return(answer); + return (answer); } -unsigned short csum_with_header(char* header,int hlen,const unsigned short *ptr,int nbytes) {//works both for big and little endian +unsigned short csum_with_header(char *header, int hlen, const unsigned short *ptr, int nbytes) { // works both for big and little endian long sum; unsigned short oddbyte; short answer; - assert(hlen%2==0); + assert(hlen % 2 == 0); - sum=0; - unsigned short * tmp= (unsigned short *)header; - for(int i=0;i1) { - sum+=*ptr++; - nbytes-=2; - } - if(nbytes==1) { - oddbyte=0; - *((u_char*)&oddbyte)=*(u_char*)ptr; - sum+=oddbyte; + sum = 0; + unsigned short *tmp = (unsigned short *)header; + for (int i = 0; i < hlen / 2; i++) { + sum += *tmp++; } - sum = (sum>>16)+(sum & 0xffff); - sum = sum + (sum>>16); - answer=(short)~sum; + while (nbytes > 1) { + sum += *ptr++; + nbytes -= 2; + } + if (nbytes == 1) { + oddbyte = 0; + *((u_char *)&oddbyte) = *(u_char *)ptr; + sum += oddbyte; + } - return(answer); + sum = (sum >> 16) + (sum & 0xffff); + sum = sum + (sum >> 16); + answer = (short)~sum; + + return (answer); } -int set_buf_size(int fd,int socket_buf_size) -{ - if(force_socket_buf) - { - if(is_udp2raw_mp) - { - mylog(log_fatal,"force_socket_buf not supported in this verion\n"); - myexit(-1); - } - //assert(0==1); +int set_buf_size(int fd, int socket_buf_size) { + if (force_socket_buf) { + if (is_udp2raw_mp) { + mylog(log_fatal, "force_socket_buf not supported in this verion\n"); + myexit(-1); + } + // assert(0==1); #ifdef UDP2RAW_LINUX - if(setsockopt(fd, SOL_SOCKET, SO_SNDBUFFORCE, &socket_buf_size, sizeof(socket_buf_size))<0) - { - mylog(log_fatal,"SO_SNDBUFFORCE fail socket_buf_size=%d errno=%s\n",socket_buf_size,strerror(errno)); - myexit(1); - } - if(setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, &socket_buf_size, sizeof(socket_buf_size))<0) - { - mylog(log_fatal,"SO_RCVBUFFORCE fail socket_buf_size=%d errno=%s\n",socket_buf_size,strerror(errno)); - myexit(1); - } + if (setsockopt(fd, SOL_SOCKET, SO_SNDBUFFORCE, &socket_buf_size, sizeof(socket_buf_size)) < 0) { + mylog(log_fatal, "SO_SNDBUFFORCE fail socket_buf_size=%d errno=%s\n", socket_buf_size, strerror(errno)); + myexit(1); + } + if (setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, &socket_buf_size, sizeof(socket_buf_size)) < 0) { + mylog(log_fatal, "SO_RCVBUFFORCE fail socket_buf_size=%d errno=%s\n", socket_buf_size, strerror(errno)); + myexit(1); + } #endif - } - else - { - if(setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &socket_buf_size, sizeof(socket_buf_size))<0) - { - mylog(log_fatal,"SO_SNDBUF fail socket_buf_size=%d errno=%s\n",socket_buf_size,get_sock_error()); - myexit(1); - } - if(setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &socket_buf_size, sizeof(socket_buf_size))<0) - { - mylog(log_fatal,"SO_RCVBUF fail socket_buf_size=%d errno=%s\n",socket_buf_size,get_sock_error()); - myexit(1); - } - } - return 0; -} - -int numbers_to_char(my_id_t id1,my_id_t id2,my_id_t id3,char * &data,int &len) -{ - static char buf[buf_len]; - data=buf; - my_id_t tmp=htonl(id1); - memcpy(buf,&tmp,sizeof(tmp)); - - tmp=htonl(id2); - memcpy(buf+sizeof(tmp),&tmp,sizeof(tmp)); - - tmp=htonl(id3); - memcpy(buf+sizeof(tmp)*2,&tmp,sizeof(tmp)); - - len=sizeof(my_id_t)*3; - return 0; -} - -int char_to_numbers(const char * data,int len,my_id_t &id1,my_id_t &id2,my_id_t &id3) -{ - if(len doesnt contain a hex\n",a.c_str()); - return -1; -} -int hex_to_u32_with_endian(const string & a,u32_t &output) -{ - //string b="0x"; - //b+=a; - if(sscanf(a.c_str(),"%x",&output)==1) - { - output=htonl(output); - //printf("%s %x\n",a.c_str(),output); - return 0; - } - mylog(log_error,"<%s> doesnt contain a hex\n",a.c_str()); - return -1; -} -bool larger_than_u32(u32_t a,u32_t b) -{ - return ((i32_t(a-b)) >0); -/* - u32_t smaller,bigger; - smaller=min(a,b);//smaller in normal sense - bigger=max(a,b); - u32_t distance=min(bigger-smaller,smaller+(0xffffffff-bigger+1)); - if(distance==bigger-smaller) - { - if(bigger==a) - { - return 1; - } - else - { - return 0; - } - } - else - { - if(smaller==b) - { - return 0; - } - else - { - return 1; - } - } -*/ -} - -bool larger_than_u16(uint16_t a,uint16_t b) -{ - return ((i16_t(a-b)) >0); -/* - uint16_t smaller,bigger; - smaller=min(a,b);//smaller in normal sense - bigger=max(a,b); - uint16_t distance=min(bigger-smaller,smaller+(0xffff-bigger+1)); - if(distance==bigger-smaller) - { - if(bigger==a) - { - return 1; - } - else - { - return 0; - } - } - else - { - if(smaller==b) - { - return 0; - } - else - { - return 1; - } - }*/ -} - -void myexit(int a) -{ - if(enable_log_color) - printf("%s\n",RESET); -#ifdef UDP2RAW_LINUX - if(keep_thread_running) - { - if(pthread_cancel(keep_thread)) - { - mylog(log_warn,"pthread_cancel failed\n"); - } - else - { - mylog(log_info,"pthread_cancel success\n"); - } + } else { + if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &socket_buf_size, sizeof(socket_buf_size)) < 0) { + mylog(log_fatal, "SO_SNDBUF fail socket_buf_size=%d errno=%s\n", socket_buf_size, get_sock_error()); + myexit(1); + } + if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &socket_buf_size, sizeof(socket_buf_size)) < 0) { + mylog(log_fatal, "SO_RCVBUF fail socket_buf_size=%d errno=%s\n", socket_buf_size, get_sock_error()); + myexit(1); + } } - clear_iptables_rule(); + return 0; +} + +int numbers_to_char(my_id_t id1, my_id_t id2, my_id_t id3, char *&data, int &len) { + static char buf[buf_len]; + data = buf; + my_id_t tmp = htonl(id1); + memcpy(buf, &tmp, sizeof(tmp)); + + tmp = htonl(id2); + memcpy(buf + sizeof(tmp), &tmp, sizeof(tmp)); + + tmp = htonl(id3); + memcpy(buf + sizeof(tmp) * 2, &tmp, sizeof(tmp)); + + len = sizeof(my_id_t) * 3; + return 0; +} + +int char_to_numbers(const char *data, int len, my_id_t &id1, my_id_t &id2, my_id_t &id3) { + if (len < int(sizeof(my_id_t) * 3)) return -1; + // id1=ntohl( *((id_t*)(data+0)) ); + memcpy(&id1, data + 0, sizeof(id1)); + id1 = ntohl(id1); + // id2=ntohl( *((id_t*)(data+sizeof(id_t))) ); + memcpy(&id2, data + sizeof(my_id_t), sizeof(id2)); + id2 = ntohl(id2); + // id3=ntohl( *((id_t*)(data+sizeof(id_t)*2)) ); + memcpy(&id3, data + sizeof(my_id_t) * 2, sizeof(id3)); + id3 = ntohl(id3); + return 0; +} +int hex_to_u32(const string &a, u32_t &output) { + // string b="0x"; + // b+=a; + if (sscanf(a.c_str(), "%x", &output) == 1) { + // printf("%s %x\n",a.c_str(),output); + return 0; + } + mylog(log_error, "<%s> doesnt contain a hex\n", a.c_str()); + return -1; +} +int hex_to_u32_with_endian(const string &a, u32_t &output) { + // string b="0x"; + // b+=a; + if (sscanf(a.c_str(), "%x", &output) == 1) { + output = htonl(output); + // printf("%s %x\n",a.c_str(),output); + return 0; + } + mylog(log_error, "<%s> doesnt contain a hex\n", a.c_str()); + return -1; +} +bool larger_than_u32(u32_t a, u32_t b) { + return ((i32_t(a - b)) > 0); + /* + u32_t smaller,bigger; + smaller=min(a,b);//smaller in normal sense + bigger=max(a,b); + u32_t distance=min(bigger-smaller,smaller+(0xffffffff-bigger+1)); + if(distance==bigger-smaller) + { + if(bigger==a) + { + return 1; + } + else + { + return 0; + } + } + else + { + if(smaller==b) + { + return 0; + } + else + { + return 1; + } + } + */ +} + +bool larger_than_u16(uint16_t a, uint16_t b) { + return ((i16_t(a - b)) > 0); + /* + uint16_t smaller,bigger; + smaller=min(a,b);//smaller in normal sense + bigger=max(a,b); + uint16_t distance=min(bigger-smaller,smaller+(0xffff-bigger+1)); + if(distance==bigger-smaller) + { + if(bigger==a) + { + return 1; + } + else + { + return 0; + } + } + else + { + if(smaller==b) + { + return 0; + } + else + { + return 1; + } + }*/ +} + +void myexit(int a) { + if (enable_log_color) + printf("%s\n", RESET); +#ifdef UDP2RAW_LINUX + if (keep_thread_running) { + if (pthread_cancel(keep_thread)) { + mylog(log_warn, "pthread_cancel failed\n"); + } else { + mylog(log_info, "pthread_cancel success\n"); + } + } + clear_iptables_rule(); #endif - exit(a); + exit(a); } -vector string_to_vec(const char * s,const char * sp) { - vector res; - string str=s; - char *p = strtok ((char *)str.c_str(),sp); - while (p != NULL) - { - res.push_back(p); - //printf ("%s\n",p); - p = strtok(NULL, sp); - } +vector string_to_vec(const char *s, const char *sp) { + vector res; + string str = s; + char *p = strtok((char *)str.c_str(), sp); + while (p != NULL) { + res.push_back(p); + // printf ("%s\n",p); + p = strtok(NULL, sp); + } - /* for(int i=0;i<(int)res.size();i++) - { - printf("<<%s>>\n",res[i].c_str()); - }*/ - return res; + /* for(int i=0;i<(int)res.size();i++) + { + printf("<<%s>>\n",res[i].c_str()); + }*/ + return res; } -vector< vector > string_to_vec2(const char * s) -{ - vector< vector > res; - vector lines=string_to_vec(s,"\n"); - for(int i=0;i tmp; - tmp=string_to_vec(lines[i].c_str(),"\t "); - res.push_back(tmp); - } - return res; +vector > string_to_vec2(const char *s) { + vector > res; + vector lines = string_to_vec(s, "\n"); + for (int i = 0; i < int(lines.size()); i++) { + vector tmp; + tmp = string_to_vec(lines[i].c_str(), "\t "); + res.push_back(tmp); + } + return res; } -int read_file(const char * file,string &output) -{ - const int max_len=3*1024*1024; - // static char buf[max_len+100]; - string buf0; - buf0.reserve(max_len+200); - char * buf=(char *)buf0.c_str(); - buf[max_len]=0; - //buf[sizeof(buf)-1]=0; - int fd=open(file,O_RDONLY); - if(fd==-1) - { - mylog(log_error,"read_file %s fail\n",file); - return -1; - } - int len=read(fd,buf,max_len); - if(len==max_len) - { - buf[0]=0; - mylog(log_error,"%s too long,buf not large enough\n",file); +int read_file(const char *file, string &output) { + const int max_len = 3 * 1024 * 1024; + // static char buf[max_len+100]; + string buf0; + buf0.reserve(max_len + 200); + char *buf = (char *)buf0.c_str(); + buf[max_len] = 0; + // buf[sizeof(buf)-1]=0; + int fd = open(file, O_RDONLY); + if (fd == -1) { + mylog(log_error, "read_file %s fail\n", file); + return -1; + } + int len = read(fd, buf, max_len); + if (len == max_len) { + buf[0] = 0; + mylog(log_error, "%s too long,buf not large enough\n", file); return -2; - } - else if(len<0) - { - buf[0]=0; - mylog(log_error,"%s read fail %d\n",file,len); + } else if (len < 0) { + buf[0] = 0; + mylog(log_error, "%s read fail %d\n", file, len); return -3; - } - else - { - buf[len]=0; - output=buf; - } - return 0; -} -int run_command(string command0,char * &output,int flag) { -if(is_udp2raw_mp) -{ - mylog(log_fatal,"run_command not supported in this version\n"); - myexit(-1); + } else { + buf[len] = 0; + output = buf; + } + return 0; } +int run_command(string command0, char *&output, int flag) { + if (is_udp2raw_mp) { + mylog(log_fatal, "run_command not supported in this version\n"); + myexit(-1); + } #ifdef UDP2RAW_LINUX FILE *in; + if ((flag & show_log) == 0) command0 += " 2>&1 "; - if((flag&show_log)==0) command0+=" 2>&1 "; + const char *command = command0.c_str(); - const char * command=command0.c_str(); + int level = (flag & show_log) ? log_warn : log_debug; - int level= (flag&show_log)?log_warn:log_debug; - - if(flag&show_command) - { - mylog(log_info,"run_command %s\n",command); + if (flag & show_command) { + mylog(log_info, "run_command %s\n", command); + } else { + mylog(log_debug, "run_command %s\n", command); } - else - { - mylog(log_debug,"run_command %s\n",command); - } - static __thread char buf[1024*1024+100]; - buf[sizeof(buf)-1]=0; - if(!(in = popen(command, "r"))){ - mylog(level,"command %s popen failed,errno %s\n",command,strerror(errno)); + static __thread char buf[1024 * 1024 + 100]; + buf[sizeof(buf) - 1] = 0; + if (!(in = popen(command, "r"))) { + mylog(level, "command %s popen failed,errno %s\n", command, strerror(errno)); return -1; } - int len =fread(buf, 1024*1024, 1, in); - if(len==1024*1024) - { - buf[0]=0; - mylog(level,"too long,buf not larger enough\n"); + int len = fread(buf, 1024 * 1024, 1, in); + if (len == 1024 * 1024) { + buf[0] = 0; + mylog(level, "too long,buf not larger enough\n"); return -2; - } - else - { - buf[len]=0; + } else { + buf[len] = 0; } int ret; - if(( ret=ferror(in) )) - { - mylog(level,"command %s fread failed,ferror return value %d \n",command,ret); + if ((ret = ferror(in))) { + mylog(level, "command %s fread failed,ferror return value %d \n", command, ret); return -3; } - //if(output!=0) - output=buf; - ret= pclose(in); + // if(output!=0) + output = buf; + ret = pclose(in); - int ret2=WEXITSTATUS(ret); + int ret2 = WEXITSTATUS(ret); - if(ret!=0||ret2!=0) - { - mylog(level,"commnad %s ,pclose returned %d ,WEXITSTATUS %d,errnor :%s \n",command,ret,ret2,strerror(errno)); - return -4; + if (ret != 0 || ret2 != 0) { + mylog(level, "commnad %s ,pclose returned %d ,WEXITSTATUS %d,errnor :%s \n", command, ret, ret2, strerror(errno)); + return -4; } #endif return 0; - } /* int run_command_no_log(string command0,char * &output) { @@ -1129,13 +974,13 @@ int run_command_no_log(string command0,char * &output) { int len =fread(buf, 1024*1024, 1, in); if(len==1024*1024) { - buf[0]=0; + buf[0]=0; mylog(log_debug,"too long,buf not larger enough\n"); return -2; } else { - buf[len]=0; + buf[len]=0; } int ret; if(( ret=ferror(in) )) @@ -1151,8 +996,8 @@ int run_command_no_log(string command0,char * &output) { if(ret!=0||ret2!=0) { - mylog(log_debug,"commnad %s ,pclose returned %d ,WEXITSTATUS %d,errnor :%s \n",command,ret,ret2,strerror(errno)); - return -4; + mylog(log_debug,"commnad %s ,pclose returned %d ,WEXITSTATUS %d,errnor :%s \n",command,ret,ret2,strerror(errno)); + return -4; } return 0; @@ -1160,169 +1005,144 @@ int run_command_no_log(string command0,char * &output) { }*/ // Remove preceding and trailing characters -string trim(const string& str, char c) { - size_t first = str.find_first_not_of(c); - if(string::npos==first) - { - return ""; - } - size_t last = str.find_last_not_of(c); - return str.substr(first,(last-first+1)); +string trim(const string &str, char c) { + size_t first = str.find_first_not_of(c); + if (string::npos == first) { + return ""; + } + size_t last = str.find_last_not_of(c); + return str.substr(first, (last - first + 1)); } -vector parse_conf_line(const string& s0) -{ - string s=s0; - s.reserve(s.length()+200); - char *buf=(char *)s.c_str(); - //char buf[s.length()+200]; - char *p=buf; - int i=int(s.length())-1; - int j; - vectorres; - //strcpy(buf,(char *)s.c_str()); - while(i>=0) - { - if(buf[i]==' ' || buf[i]== '\t') - buf[i]=0; - else break; - i--; - } - while(*p!=0) - { - if(*p==' ' || *p== '\t') - { - p++; - } - else break; - } - int new_len=strlen(p); - if(new_len==0)return res; - if(p[0]=='#') return res; - if(p[0]!='-') - { - mylog(log_fatal,"line :<%s> not begin with '-' ",s.c_str()); - myexit(-1); - } - - for(i=0;i parse_conf_line(const string &s0) { + string s = s0; + s.reserve(s.length() + 200); + char *buf = (char *)s.c_str(); + // char buf[s.length()+200]; + char *p = buf; + int i = int(s.length()) - 1; + int j; + vector res; + // strcpy(buf,(char *)s.c_str()); + while (i >= 0) { + if (buf[i] == ' ' || buf[i] == '\t') + buf[i] = 0; + else + break; + i--; + } + while (*p != 0) { + if (*p == ' ' || *p == '\t') { + p++; + } else + break; + } + int new_len = strlen(p); + if (new_len == 0) return res; + if (p[0] == '#') return res; + if (p[0] != '-') { + mylog(log_fatal, "line :<%s> not begin with '-' ", s.c_str()); myexit(-1); - return 0; + } + + for (i = 0; i < new_len; i++) { + if (p[i] == ' ' || p[i] == '\t') { + break; + } + } + if (i == new_len) { + res.push_back(p); + return res; + } + + j = i; + while (p[j] == ' ' || p[j] == '\t') + j++; + p[i] = 0; + res.push_back(p); + res.push_back(p + j); + return res; +} + +int create_fifo(char *file) { +#if !defined(__MINGW32__) + if (mkfifo(file, 0666) != 0) { + if (errno == EEXIST) { + mylog(log_warn, "warning fifo file %s exist\n", file); + } else { + mylog(log_fatal, "create fifo file %s failed\n", file); + myexit(-1); + } + } + int fifo_fd = open(file, O_RDWR); + if (fifo_fd < 0) { + mylog(log_fatal, "create fifo file %s failed\n", file); + myexit(-1); + } + struct stat st; + if (fstat(fifo_fd, &st) != 0) { + mylog(log_fatal, "fstat failed for fifo file %s\n", file); + myexit(-1); + } + + if (!S_ISFIFO(st.st_mode)) { + mylog(log_fatal, "%s is not a fifo\n", file); + myexit(-1); + } + + setnonblocking(fifo_fd); + return fifo_fd; +#else + mylog(log_fatal, "--fifo not supported in this version\n"); + myexit(-1); + return 0; #endif } /* void ip_port_t::from_u64(u64_t u64) { - ip=get_u64_h(u64); - port=get_u64_l(u64); + ip=get_u64_h(u64); + port=get_u64_l(u64); } u64_t ip_port_t::to_u64() { - return pack_u64(ip,port); + return pack_u64(ip,port); } char * ip_port_t::to_s() { - static char res[40]; - sprintf(res,"%s:%d",my_ntoa(ip),port); - return res; + static char res[40]; + sprintf(res,"%s:%d",my_ntoa(ip),port); + return res; }*/ - - -void print_binary_chars(const char * a,int len) -{ - for(int i=0;i",(int)b); - } - log_bare(log_debug,"\n"); +void print_binary_chars(const char *a, int len) { + for (int i = 0; i < len; i++) { + unsigned char b = a[i]; + log_bare(log_debug, "<%02x>", (int)b); + } + log_bare(log_debug, "\n"); } -u32_t djb2(unsigned char *str,int len) -{ - u32_t hash = 5381; - int c; - int i=0; - while(c = *str++,i++!=len) - { - hash = ((hash << 5) + hash)^c; /* (hash * 33) ^ c */ +u32_t djb2(unsigned char *str, int len) { + u32_t hash = 5381; + int c; + int i = 0; + while (c = *str++, i++ != len) { + hash = ((hash << 5) + hash) ^ c; /* (hash * 33) ^ c */ } - hash=htonl(hash); - return hash; - } + hash = htonl(hash); + return hash; +} -u32_t sdbm(unsigned char *str,int len) -{ - u32_t hash = 0; - int c; - int i=0; - while(c = *str++,i++!=len) - { - hash = c + (hash << 6) + (hash << 16) - hash; - } - //hash=htonl(hash); - return hash; - } +u32_t sdbm(unsigned char *str, int len) { + u32_t hash = 0; + int c; + int i = 0; + while (c = *str++, i++ != len) { + hash = c + (hash << 6) + (hash << 16) - hash; + } + // hash=htonl(hash); + return hash; +} diff --git a/common.h b/common.h index d01e5ca..b6c559f 100644 --- a/common.h +++ b/common.h @@ -10,16 +10,16 @@ #define __STDC_FORMAT_MACROS 1 #include -#include -#include -#include -#include +#include +#include +#include +#include -#include -#include +#include +#include #include -#include //for exit(0); -#include //For errno - the error number +#include //for exit(0); +#include //For errno - the error number #include #include #include @@ -32,7 +32,7 @@ #endif #if defined(UDP2RAW_MP) -const int is_udp2raw_mp=1; +const int is_udp2raw_mp = 1; #if !defined(__CYGWIN__) && !defined(__MINGW32__) #include #else @@ -44,10 +44,9 @@ const int is_udp2raw_mp=1; #include #endif - #else #define UDP2RAW_LINUX -const int is_udp2raw_mp=0; +const int is_udp2raw_mp = 0; //#include #include #include @@ -80,51 +79,47 @@ typedef int socklen_t; #include #endif - -#include +#include #include #include #include #include #include #include -using namespace std; +using namespace std; -#if defined(__BYTE_ORDER) && __BYTE_ORDER == __BIG_ENDIAN || \ +#if defined(__BYTE_ORDER) && __BYTE_ORDER == __BIG_ENDIAN || \ defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ || \ - defined(__BIG_ENDIAN__) || \ - defined(__ARMEB__) || \ - defined(__THUMBEB__) || \ - defined(__AARCH64EB__) || \ + defined(__BIG_ENDIAN__) || \ + defined(__ARMEB__) || \ + defined(__THUMBEB__) || \ + defined(__AARCH64EB__) || \ defined(_MIBSEB) || defined(__MIBSEB) || defined(__MIBSEB__) #define UDP2RAW_BIG_ENDIAN 1 #endif - -#if defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN || \ +#if defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN || \ defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ || \ - defined(__LITTLE_ENDIAN__) || \ - defined(__ARMEL__) || \ - defined(__THUMBEL__) || \ - defined(__AARCH64EL__) || \ + defined(__LITTLE_ENDIAN__) || \ + defined(__ARMEL__) || \ + defined(__THUMBEL__) || \ + defined(__AARCH64EL__) || \ defined(_MIPSEL) || defined(__MIPSEL) || defined(__MIPSEL__) #define UDP2RAW_LITTLE_ENDIAN 1 #endif -#if defined(UDP2RAW_BIG_ENDIAN) &&defined(UDP2RAW_LITTLE_ENDIAN) +#if defined(UDP2RAW_BIG_ENDIAN) && defined(UDP2RAW_LITTLE_ENDIAN) #error "endian detection conflicts" #endif - #if !defined(UDP2RAW_BIG_ENDIAN) && !defined(UDP2RAW_LITTLE_ENDIAN) #error "endian detection failed" #endif - #if defined(__MINGW32__) int inet_pton(int af, const char *src, void *dst); const char *inet_ntop(int af, const void *src, char *dst, socklen_t size); -#define setsockopt(a,b,c,d,e) setsockopt(a,b,c,(const char *)(d),e) +#define setsockopt(a, b, c, d, e) setsockopt(a, b, c, (const char *)(d), e) #endif char *get_sock_error(); @@ -132,21 +127,18 @@ int get_sock_errno(); #if defined(__MINGW32__) typedef SOCKET my_fd_t; -inline int sock_close(my_fd_t fd) -{ - return closesocket(fd); +inline int sock_close(my_fd_t fd) { + return closesocket(fd); } #else typedef int my_fd_t; -inline int sock_close(my_fd_t fd) -{ - return close(fd); +inline int sock_close(my_fd_t fd) { + return close(fd); } #endif - -typedef unsigned long long u64_t; //this works on most platform,avoid using the PRId64 +typedef unsigned long long u64_t; // this works on most platform,avoid using the PRId64 typedef long long i64_t; typedef unsigned int u32_t; @@ -165,7 +157,7 @@ typedef u64_t anti_replay_seq_t; typedef u64_t my_time_t; -const int max_addr_len=100; +const int max_addr_len = 100; extern int force_socket_buf; @@ -174,251 +166,224 @@ extern int g_fix_gro; /* struct ip_port_t { - u32_t ip; - int port; - void from_u64(u64_t u64); - u64_t to_u64(); - char * to_s(); + u32_t ip; + int port; + void from_u64(u64_t u64); + u64_t to_u64(); + char * to_s(); };*/ typedef u64_t fd64_t; -u32_t djb2(unsigned char *str,int len); -u32_t sdbm(unsigned char *str,int len); +u32_t djb2(unsigned char *str, int len); +u32_t sdbm(unsigned char *str, int len); -struct address_t //TODO scope id +struct address_t // TODO scope id { - struct hash_function - { - u32_t operator()(const address_t &key) const - { - return sdbm((unsigned char*)&key.inner,sizeof(key.inner)); - } - }; + struct hash_function { + u32_t operator()(const address_t &key) const { + return sdbm((unsigned char *)&key.inner, sizeof(key.inner)); + } + }; - union storage_t //sockaddr_storage is too huge, we dont use it. - { - sockaddr_in ipv4; - sockaddr_in6 ipv6; - }; - storage_t inner; - - address_t() - { - clear(); - } - void clear() - { - memset(&inner,0,sizeof(inner)); - } - int from_ip_port(u32_t ip, int port) - { - clear(); - inner.ipv4.sin_family=AF_INET; - inner.ipv4.sin_port=htons(port); - inner.ipv4.sin_addr.s_addr=ip; - return 0; - } - - int from_ip_port_new(int type, void * ip, int port) - { - clear(); - if(type==AF_INET) - { - inner.ipv4.sin_family=AF_INET; - inner.ipv4.sin_port=htons(port); - inner.ipv4.sin_addr.s_addr=*((u32_t *)ip); - } - else if(type==AF_INET6) - { - inner.ipv6.sin6_family=AF_INET6; - inner.ipv6.sin6_port=htons(port); - inner.ipv6.sin6_addr=*((in6_addr*)ip); - } - return 0; - } - - int from_str(char * str); - - int from_str_ip_only(char * str); - - int from_sockaddr(sockaddr *,socklen_t); - - char* get_str(); - void to_str(char *); - - inline u32_t get_type() - { - u32_t ret=((sockaddr*)&inner)->sa_family; - assert(ret==AF_INET||ret==AF_INET6); - return ret; - } - - inline u32_t get_len() - { - u32_t type=get_type(); - switch(type) - { - case AF_INET: - return sizeof(sockaddr_in); - case AF_INET6: - return sizeof(sockaddr_in6); - default: - assert(0==1); - } - return -1; - } - - inline u32_t get_port() - { - u32_t type=get_type(); - switch(type) - { - case AF_INET: - return ntohs(inner.ipv4.sin_port); - case AF_INET6: - return ntohs(inner.ipv6.sin6_port); - default: - assert(0==1); - } - return -1; - } - - inline void set_port(int port) - { - u32_t type=get_type(); - switch(type) - { - case AF_INET: - inner.ipv4.sin_port=htons(port); - break; - case AF_INET6: - inner.ipv6.sin6_port=htons(port); - break; - default: - assert(0==1); - } - return ; - } - - bool operator == (const address_t &b) const + union storage_t // sockaddr_storage is too huge, we dont use it. { - //return this->data==b.data; - return memcmp(&this->inner,&b.inner,sizeof(this->inner))==0; + sockaddr_in ipv4; + sockaddr_in6 ipv6; + }; + storage_t inner; + + address_t() { + clear(); + } + void clear() { + memset(&inner, 0, sizeof(inner)); + } + int from_ip_port(u32_t ip, int port) { + clear(); + inner.ipv4.sin_family = AF_INET; + inner.ipv4.sin_port = htons(port); + inner.ipv4.sin_addr.s_addr = ip; + return 0; + } + + int from_ip_port_new(int type, void *ip, int port) { + clear(); + if (type == AF_INET) { + inner.ipv4.sin_family = AF_INET; + inner.ipv4.sin_port = htons(port); + inner.ipv4.sin_addr.s_addr = *((u32_t *)ip); + } else if (type == AF_INET6) { + inner.ipv6.sin6_family = AF_INET6; + inner.ipv6.sin6_port = htons(port); + inner.ipv6.sin6_addr = *((in6_addr *)ip); + } + return 0; + } + + int from_str(char *str); + + int from_str_ip_only(char *str); + + int from_sockaddr(sockaddr *, socklen_t); + + char *get_str(); + void to_str(char *); + + inline u32_t get_type() { + u32_t ret = ((sockaddr *)&inner)->sa_family; + assert(ret == AF_INET || ret == AF_INET6); + return ret; + } + + inline u32_t get_len() { + u32_t type = get_type(); + switch (type) { + case AF_INET: + return sizeof(sockaddr_in); + case AF_INET6: + return sizeof(sockaddr_in6); + default: + assert(0 == 1); + } + return -1; + } + + inline u32_t get_port() { + u32_t type = get_type(); + switch (type) { + case AF_INET: + return ntohs(inner.ipv4.sin_port); + case AF_INET6: + return ntohs(inner.ipv6.sin6_port); + default: + assert(0 == 1); + } + return -1; + } + + inline void set_port(int port) { + u32_t type = get_type(); + switch (type) { + case AF_INET: + inner.ipv4.sin_port = htons(port); + break; + case AF_INET6: + inner.ipv6.sin6_port = htons(port); + break; + default: + assert(0 == 1); + } + return; + } + + bool operator==(const address_t &b) const { + // return this->data==b.data; + return memcmp(&this->inner, &b.inner, sizeof(this->inner)) == 0; } int new_connected_udp_fd(); - char* get_ip(); + char *get_ip(); }; namespace std { template <> - struct hash - { - std::size_t operator()(const address_t& key) const - { +struct hash { + std::size_t operator()(const address_t &key) const { + // return address_t::hash_function(k); + return sdbm((unsigned char *)&key.inner, sizeof(key.inner)); + } +}; +} // namespace std - //return address_t::hash_function(k); - return sdbm((unsigned char*)&key.inner,sizeof(key.inner)); - } - }; -} - -union my_ip_t //just a simple version of address_t,stores ip only +union my_ip_t // just a simple version of address_t,stores ip only { - u32_t v4; - in6_addr v6; + u32_t v4; + in6_addr v6; - bool equal (const my_ip_t &b) const; + bool equal(const my_ip_t &b) const; - //int from_str(char * str); - char * get_str1() const; - char * get_str2() const; + // int from_str(char * str); + char *get_str1() const; + char *get_str2() const; int from_address_t(address_t a); - }; -struct not_copy_able_t -{ - not_copy_able_t() - { - - } - not_copy_able_t(const not_copy_able_t &other) - { - assert(0==1); - } - const not_copy_able_t & operator=(const not_copy_able_t &other) - { - assert(0==1); - return other; - } +struct not_copy_able_t { + not_copy_able_t() { + } + not_copy_able_t(const not_copy_able_t &other) { + assert(0 == 1); + } + const not_copy_able_t &operator=(const not_copy_able_t &other) { + assert(0 == 1); + return other; + } }; -const int huge_data_len=65535+100; //a packet with link level header might be larger than 65535 -const int huge_buf_len=huge_data_len+100; +const int huge_data_len = 65535 + 100; // a packet with link level header might be larger than 65535 +const int huge_buf_len = huge_data_len + 100; -const int max_data_len=1800; -const int buf_len=max_data_len+400; +const int max_data_len = 1800; +const int buf_len = max_data_len + 400; -//const int max_address_len=512; +// const int max_address_len=512; #ifdef UDP2RAW_MP -const int queue_len=200; +const int queue_len = 200; -struct queue_t -{ - char data[queue_len][huge_buf_len]; - int data_len[queue_len]; +struct queue_t { + char data[queue_len][huge_buf_len]; + int data_len[queue_len]; - int head=0; - int tail=0; - void clear() - { - head=tail=0; - } - int empty() - { - if(head==tail) return 1; - else return 0; - } - int full() - { - if( (tail+1)%queue_len==head ) return 1; - else return 0; - } - void peek_front(char * & p,int &len) - { - assert(!empty()); - p=data[head]; - len=data_len[head]; - } - void pop_front() - { - assert(!empty()); - head++;head%=queue_len; - } - void push_back(char * p,int len) - { - assert(!full()); - memcpy(data[tail],p,len); - data_len[tail]=len; - tail++;tail%=queue_len; - } + int head = 0; + int tail = 0; + void clear() { + head = tail = 0; + } + int empty() { + if (head == tail) + return 1; + else + return 0; + } + int full() { + if ((tail + 1) % queue_len == head) + return 1; + else + return 0; + } + void peek_front(char *&p, int &len) { + assert(!empty()); + p = data[head]; + len = data_len[head]; + } + void pop_front() { + assert(!empty()); + head++; + head %= queue_len; + } + void push_back(char *p, int len) { + assert(!full()); + memcpy(data[tail], p, len); + data_len[tail] = len; + tail++; + tail %= queue_len; + } }; int init_ws(); #endif u64_t get_current_time(); -u64_t pack_u64(u32_t a,u32_t b); +u64_t pack_u64(u32_t a, u32_t b); u32_t get_u64_h(u64_t a); u32_t get_u64_l(u64_t a); -char * my_ntoa(u32_t ip); +char *my_ntoa(u32_t ip); void init_random_number_fd(); u64_t get_true_random_number_64(); @@ -427,138 +392,131 @@ u32_t get_true_random_number_nz(); u64_t ntoh64(u64_t a); u64_t hton64(u64_t a); -void write_u16(char *,u16_t a);// network order +void write_u16(char *, u16_t a); // network order u16_t read_u16(char *); -void write_u32(char *,u32_t a);// network order +void write_u32(char *, u32_t a); // network order u32_t read_u32(char *); -void write_u64(char *,u64_t a); +void write_u64(char *, u64_t a); u64_t read_u64(char *); -bool larger_than_u16(uint16_t a,uint16_t b); -bool larger_than_u32(u32_t a,u32_t b); +bool larger_than_u16(uint16_t a, uint16_t b); +bool larger_than_u32(u32_t a, u32_t b); void setnonblocking(int sock); -int set_buf_size(int fd,int socket_buf_size); +int set_buf_size(int fd, int socket_buf_size); void myexit(int a); -unsigned short csum(const unsigned short *ptr,int nbytes); -unsigned short csum_with_header(char* header,int hlen,const unsigned short *ptr,int nbytes); +unsigned short csum(const unsigned short *ptr, int nbytes); +unsigned short csum_with_header(char *header, int hlen, const unsigned short *ptr, int nbytes); -int numbers_to_char(my_id_t id1,my_id_t id2,my_id_t id3,char * &data,int &len); -int char_to_numbers(const char * data,int len,my_id_t &id1,my_id_t &id2,my_id_t &id3); +int numbers_to_char(my_id_t id1, my_id_t id2, my_id_t id3, char *&data, int &len); +int char_to_numbers(const char *data, int len, my_id_t &id1, my_id_t &id2, my_id_t &id3); -const int show_none=0; -const int show_command=0x1; -const int show_log=0x2; -const int show_all=show_command|show_log; +const int show_none = 0; +const int show_command = 0x1; +const int show_log = 0x2; +const int show_all = show_command | show_log; -int run_command(string command,char * &output,int flag=show_all); -//int run_command_no_log(string command,char * &output); -int read_file(const char * file,string &output); +int run_command(string command, char *&output, int flag = show_all); +// int run_command_no_log(string command,char * &output); +int read_file(const char *file, string &output); -vector string_to_vec(const char * s,const char * sp); -vector< vector > string_to_vec2(const char * s); +vector string_to_vec(const char *s, const char *sp); +vector > string_to_vec2(const char *s); -string trim(const string& str, char c); +string trim(const string &str, char c); -string trim_conf_line(const string& str); +string trim_conf_line(const string &str); -vector parse_conf_line(const string& s); +vector parse_conf_line(const string &s); -int hex_to_u32_with_endian(const string & a,u32_t &output); -int hex_to_u32(const string & a,u32_t &output); -//extern string iptables_pattern; +int hex_to_u32_with_endian(const string &a, u32_t &output); +int hex_to_u32(const string &a, u32_t &output); +// extern string iptables_pattern; -int create_fifo(char * file); +int create_fifo(char *file); -void print_binary_chars(const char * a,int len); +void print_binary_chars(const char *a, int len); template -struct lru_collector_t:not_copy_able_t -{ - //typedef void* key_t; -//#define key_t void* - struct lru_pair_t - { - key_t key; - my_time_t ts; - }; +struct lru_collector_t : not_copy_able_t { + // typedef void* key_t; + //#define key_t void* + struct lru_pair_t { + key_t key; + my_time_t ts; + }; - unordered_map::iterator> mp; + unordered_map::iterator> mp; - list q; - int update(key_t key) - { - assert(mp.find(key)!=mp.end()); - auto it=mp[key]; - q.erase(it); + list q; + int update(key_t key) { + assert(mp.find(key) != mp.end()); + auto it = mp[key]; + q.erase(it); - my_time_t value=get_current_time(); - if(!q.empty()) - { - assert(value >=q.front().ts); - } - lru_pair_t tmp; tmp.key=key; tmp.ts=value; - q.push_front( tmp); - mp[key]=q.begin(); + my_time_t value = get_current_time(); + if (!q.empty()) { + assert(value >= q.front().ts); + } + lru_pair_t tmp; + tmp.key = key; + tmp.ts = value; + q.push_front(tmp); + mp[key] = q.begin(); - return 0; - } - int new_key(key_t key) - { - assert(mp.find(key)==mp.end()); + return 0; + } + int new_key(key_t key) { + assert(mp.find(key) == mp.end()); - my_time_t value=get_current_time(); - if(!q.empty()) - { - assert(value >=q.front().ts); - } - lru_pair_t tmp; tmp.key=key; tmp.ts=value; - q.push_front( tmp); - mp[key]=q.begin(); + my_time_t value = get_current_time(); + if (!q.empty()) { + assert(value >= q.front().ts); + } + lru_pair_t tmp; + tmp.key = key; + tmp.ts = value; + q.push_front(tmp); + mp[key] = q.begin(); - return 0; - } - int size() - { - return q.size(); - } - int empty() - { - return q.empty(); - } - void clear() - { - mp.clear(); q.clear(); - } - my_time_t ts_of(key_t key) - { - assert(mp.find(key)!=mp.end()); - return mp[key]->ts; - } + return 0; + } + int size() { + return q.size(); + } + int empty() { + return q.empty(); + } + void clear() { + mp.clear(); + q.clear(); + } + my_time_t ts_of(key_t key) { + assert(mp.find(key) != mp.end()); + return mp[key]->ts; + } - my_time_t peek_back(key_t &key) - { - assert(!q.empty()); - auto it=q.end(); it--; - key=it->key; - return it->ts; - } - void erase(key_t key) - { - assert(mp.find(key)!=mp.end()); - q.erase(mp[key]); - mp.erase(key); - } - /* - void erase_back() - { - assert(!q.empty()); - auto it=q.end(); it--; - key_t key=it->key; - erase(key); - }*/ + my_time_t peek_back(key_t &key) { + assert(!q.empty()); + auto it = q.end(); + it--; + key = it->key; + return it->ts; + } + void erase(key_t key) { + assert(mp.find(key) != mp.end()); + q.erase(mp[key]); + mp.erase(key); + } + /* + void erase_back() + { + assert(!q.empty()); + auto it=q.end(); it--; + key_t key=it->key; + erase(key); + }*/ }; - #endif /* COMMON_H_ */ diff --git a/connection.cpp b/connection.cpp index aac980e..637804a 100644 --- a/connection.cpp +++ b/connection.cpp @@ -9,749 +9,649 @@ #include "encrypt.h" #include "fd_manager.h" -int disable_anti_replay=0;//if anti_replay windows is diabled +int disable_anti_replay = 0; // if anti_replay windows is diabled -const int disable_conn_clear=0;//a raw connection is called conn. +const int disable_conn_clear = 0; // a raw connection is called conn. conn_manager_t conn_manager; - anti_replay_seq_t anti_replay_t::get_new_seq_for_send() - { - return anti_replay_seq++; - } - anti_replay_t::anti_replay_t() - { - max_packet_received=0; - anti_replay_seq=get_true_random_number_64()/10;//random first seq - //memset(window,0,sizeof(window)); //not necessary - } - void anti_replay_t::re_init() - { - max_packet_received=0; - //memset(window,0,sizeof(window)); - } - - int anti_replay_t::is_vaild(u64_t seq) - { - if(disable_anti_replay) return 1; - //if(disabled) return 0; - - if(seq==max_packet_received) return 0; - else if(seq>max_packet_received) - { - if(seq-max_packet_received>=anti_replay_window_size) - { - memset(window,0,sizeof(window)); - window[seq%anti_replay_window_size]=1; - } - else - { - for (u64_t i=max_packet_received+1;i=anti_replay_window_size) return 0; - else - { - if (window[seq%anti_replay_window_size]==1) return 0; - else - { - window[seq%anti_replay_window_size]=1; - return 1; - } - } - } - - - return 0; //for complier check - } - - - - - void conn_info_t::recover(const conn_info_t &conn_info) - { - raw_info=conn_info.raw_info; - - raw_info.rst_received=0; - raw_info.disabled=0; - - last_state_time=conn_info.last_state_time; - last_hb_recv_time=conn_info.last_hb_recv_time; - last_hb_sent_time=conn_info.last_hb_sent_time; - my_id=conn_info.my_id; - oppsite_id=conn_info.oppsite_id; - blob->anti_replay.re_init(); - - my_roller=0;//no need to set,but for easier debug,set it to zero - oppsite_roller=0;//same as above - last_oppsite_roller_time=0; - - } - - void conn_info_t::re_init() - { - //send_packet_info.protocol=g_packet_info_send.protocol; - if(program_mode==server_mode) - state.server_current_state=server_idle; - else - state.client_current_state=client_idle; - last_state_time=0; - oppsite_const_id=0; - - timer_fd64=0; - - my_roller=0; - oppsite_roller=0; - last_oppsite_roller_time=0; - } - conn_info_t::conn_info_t() - { - blob=0; - re_init(); - } - void conn_info_t::prepare() - { - assert(blob==0); - blob=new blob_t; - if(program_mode==server_mode) - { - blob->conv_manager.s.additional_clear_function=server_clear_function; - } - else - { - assert(program_mode==client_mode); - } - } - - conn_info_t::conn_info_t(const conn_info_t&b) - { - assert(0==1); - //mylog(log_error,"called!!!!!!!!!!!!!\n"); - } - - conn_info_t& conn_info_t::operator=(const conn_info_t& b) - { - mylog(log_fatal,"not allowed\n"); - myexit(-1); - return *this; - } - conn_info_t::~conn_info_t() - { - if(program_mode==server_mode) - { - if(state.server_current_state==server_ready) - { - assert(blob!=0); - assert(oppsite_const_id!=0); - //assert(conn_manager.const_id_mp.find(oppsite_const_id)!=conn_manager.const_id_mp.end()); // conn_manager 's deconstuction function erases it - } - else - { - assert(blob==0); - assert(oppsite_const_id==0); - } - } - assert(timer_fd64==0); - //if(oppsite_const_id!=0) //do this at conn_manager 's deconstuction function - //conn_manager.const_id_mp.erase(oppsite_const_id); - if(blob!=0) - delete blob; - - //send_packet_info.protocol=g_packet_info_send.protocol; - } - - - conn_manager_t::conn_manager_t() - { - ready_num=0; - mp.reserve(10007); - //clear_it=mp.begin(); - // timer_fd_mp.reserve(10007); - const_id_mp.reserve(10007); - // udp_fd_mp.reserve(100007); - last_clear_time=0; - //current_ready_ip=0; - // current_ready_port=0; - } - int conn_manager_t::exist(address_t addr) - { - //u64_t u64=0; - //u64=ip; - //u64<<=32u; - //u64|=port; - if(mp.find(addr)!=mp.end()) - { - return 1; - } - return 0; - } - /* - int insert(uint32_t ip,uint16_t port) - { - uint64_t u64=0; - u64=ip; - u64<<=32u; - u64|=port; - mp[u64]; - return 0; - }*/ - conn_info_t *& conn_manager_t::find_insert_p(address_t addr) //be aware,the adress may change after rehash - { - // u64_t u64=0; - //u64=ip; - //u64<<=32u; - //u64|=port; - unordered_map::iterator it=mp.find(addr); - if(it==mp.end()) - { - mp[addr]=new conn_info_t; - //lru.new_key(addr); - } - else - { - //lru.update(addr); - } - return mp[addr]; - } - conn_info_t & conn_manager_t::find_insert(address_t addr) //be aware,the adress may change after rehash - { - //u64_t u64=0; - //u64=ip; - //u64<<=32u; - //u64|=port; - unordered_map::iterator it=mp.find(addr); - if(it==mp.end()) - { - mp[addr]=new conn_info_t; - //lru.new_key(addr); - } - else - { - //lru.update(addr); - } - return *mp[addr]; - } - int conn_manager_t::erase(unordered_map::iterator erase_it) - { - if(erase_it->second->state.server_current_state==server_ready) - { - ready_num--; - assert(i32_t(ready_num)!=-1); - assert(erase_it->second!=0); - - assert(erase_it->second->timer_fd64 !=0); - - assert(fd_manager.exist(erase_it->second->timer_fd64)); - - assert(erase_it->second->oppsite_const_id!=0); - assert(const_id_mp.find(erase_it->second->oppsite_const_id)!=const_id_mp.end()); - - - //assert(timer_fd_mp.find(erase_it->second->timer_fd)!=timer_fd_mp.end()); - - const_id_mp.erase(erase_it->second->oppsite_const_id); - - fd_manager.fd64_close(erase_it->second->timer_fd64); - - erase_it->second->timer_fd64=0; - //timer_fd_mp.erase(erase_it->second->timer_fd); - //close(erase_it->second->timer_fd);// close will auto delte it from epoll - delete(erase_it->second); - mp.erase(erase_it->first); - } - else - { - assert(erase_it->second->blob==0); - assert(erase_it->second->timer_fd64 ==0); - - - assert(erase_it->second->oppsite_const_id==0); - delete(erase_it->second); - mp.erase(erase_it->first); - } - return 0; - } -int conn_manager_t::clear_inactive() -{ - if(get_current_time()-last_clear_time>conn_clear_interval) - { - last_clear_time=get_current_time(); - return clear_inactive0(); - } - return 0; +anti_replay_seq_t anti_replay_t::get_new_seq_for_send() { + return anti_replay_seq++; } -int conn_manager_t::clear_inactive0() -{ - unordered_map::iterator it; - unordered_map::iterator old_it; - - if(disable_conn_clear) return 0; - - //map::iterator it; - int cnt=0; - it=clear_it; - int size=mp.size(); - int num_to_clean=size/conn_clear_ratio+conn_clear_min; //clear 1/10 each time,to avoid latency glitch - - mylog(log_trace,"mp.size() %d\n", size); - - num_to_clean=min(num_to_clean,(int)mp.size()); - u64_t current_time=get_current_time(); - - for(;;) - { - if(cnt>=num_to_clean) break; - if(mp.begin()==mp.end()) break; - - if(it==mp.end()) - { - it=mp.begin(); - } - - if(it->second->state.server_current_state==server_ready &¤t_time - it->second->last_hb_recv_time <=server_conn_timeout) - { - it++; - } - else if(it->second->state.server_current_state!=server_ready&& current_time - it->second->last_state_time <=server_handshake_timeout ) - { - it++; - } - else if(it->second->blob!=0&&it->second->blob->conv_manager.s.get_size() >0) - { - assert(it->second->state.server_current_state==server_ready); - it++; - } - else - { - mylog(log_info,"[%s:%d]inactive conn cleared \n",it->second->raw_info.recv_info.new_src_ip.get_str1(),it->second->raw_info.recv_info.src_port); - old_it=it; - it++; - erase(old_it); - } - cnt++; - } - clear_it=it; - - return 0; +anti_replay_t::anti_replay_t() { + max_packet_received = 0; + anti_replay_seq = get_true_random_number_64() / 10; // random first seq + // memset(window,0,sizeof(window)); //not necessary +} +void anti_replay_t::re_init() { + max_packet_received = 0; + // memset(window,0,sizeof(window)); } +int anti_replay_t::is_vaild(u64_t seq) { + if (disable_anti_replay) return 1; + // if(disabled) return 0; + if (seq == max_packet_received) + return 0; + else if (seq > max_packet_received) { + if (seq - max_packet_received >= anti_replay_window_size) { + memset(window, 0, sizeof(window)); + window[seq % anti_replay_window_size] = 1; + } else { + for (u64_t i = max_packet_received + 1; i < seq; i++) + window[i % anti_replay_window_size] = 0; + window[seq % anti_replay_window_size] = 1; + } + max_packet_received = seq; + return 1; + } else if (seq < max_packet_received) { + if (max_packet_received - seq >= anti_replay_window_size) + return 0; + else { + if (window[seq % anti_replay_window_size] == 1) + return 0; + else { + window[seq % anti_replay_window_size] = 1; + return 1; + } + } + } -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 -//you have to design the protocol carefully, so that you wont be affect by relay attack -{ - if(len<0) - { - mylog(log_debug,"input_len <0\n"); - return -1; - } - packet_info_t &send_info=raw_info.send_info; - packet_info_t &recv_info=raw_info.recv_info; - - char send_data_buf[buf_len]; //buf for send data and send hb - char send_data_buf2[buf_len]; - - - //static send_bare[buf_len]; - iv_t iv=get_true_random_number_64(); - padding_t padding=get_true_random_number_64(); - - memcpy(send_data_buf,&iv,sizeof(iv)); - memcpy(send_data_buf+sizeof(iv),&padding,sizeof(padding)); - - send_data_buf[sizeof(iv)+sizeof(padding)]='b'; - memcpy(send_data_buf+sizeof(iv)+sizeof(padding)+1,data,len); - int new_len=len+sizeof(iv)+sizeof(padding)+1; - - if(my_encrypt(send_data_buf,send_data_buf2,new_len)!=0) - { - return -1; - } - send_raw0(raw_info,send_data_buf2,new_len); - return 0; -} -int reserved_parse_bare(const char *input,int input_len,char* & data,int & len) // a sub function used in recv_bare -{ - static char recv_data_buf[buf_len]; - - if(input_len<0) - { - mylog(log_debug,"input_len <0\n"); - return -1; - } - if(my_decrypt(input,recv_data_buf,input_len)!=0) - { - mylog(log_debug,"decrypt_fail in recv bare\n"); - return -1; - } - if(recv_data_buf[sizeof(iv_t)+sizeof(padding_t)]!='b') - { - mylog(log_debug,"not a bare packet\n"); - return -1; - } - len=input_len; - data=recv_data_buf+sizeof(iv_t)+sizeof(padding_t)+1; - len-=sizeof(iv_t)+sizeof(padding_t)+1; - if(len<0) - { - mylog(log_debug,"len <0\n"); - return -1; - } - return 0; -} -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 -//you have to design the protocol carefully, so that you wont be affect by relay attack -{ - packet_info_t &send_info=raw_info.send_info; - packet_info_t &recv_info=raw_info.recv_info; - - if(recv_raw0(raw_info,data,len)<0) - { - //printf("recv_raw_fail in recv bare\n"); - return -1; - } - - if(len>=max_data_len+1) - { - mylog(log_debug,"data_len=%d >= max_data_len+1,ignored",len); - return -1; - } - - mylog(log_trace,"data len=%d\n",len); - if ((raw_mode == mode_faketcp && (recv_info.syn == 1 || recv_info.ack != 1))) - { - mylog(log_debug,"unexpect packet type recv_info.syn=%d recv_info.ack=%d \n",recv_info.syn,recv_info.ack); - return -1; - } - return reserved_parse_bare(data,len,data,len); + return 0; // for complier check } -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 -{ - packet_info_t &send_info=raw_info.send_info; - packet_info_t &recv_info=raw_info.recv_info; +void conn_info_t::recover(const conn_info_t &conn_info) { + raw_info = conn_info.raw_info; - char * data;int len; - //len=sizeof(id_t)*3; - if(numbers_to_char(id1,id2,id3,data,len)!=0) return -1; - if(send_bare(raw_info,data,len)!=0) {mylog(log_warn,"send bare fail\n");return -1;} - return 0; + raw_info.rst_received = 0; + raw_info.disabled = 0; + + last_state_time = conn_info.last_state_time; + last_hb_recv_time = conn_info.last_hb_recv_time; + last_hb_sent_time = conn_info.last_hb_sent_time; + my_id = conn_info.my_id; + oppsite_id = conn_info.oppsite_id; + blob->anti_replay.re_init(); + + my_roller = 0; // no need to set,but for easier debug,set it to zero + oppsite_roller = 0; // same as above + last_oppsite_roller_time = 0; +} + +void conn_info_t::re_init() { + // send_packet_info.protocol=g_packet_info_send.protocol; + if (program_mode == server_mode) + state.server_current_state = server_idle; + else + state.client_current_state = client_idle; + last_state_time = 0; + oppsite_const_id = 0; + + timer_fd64 = 0; + + my_roller = 0; + oppsite_roller = 0; + last_oppsite_roller_time = 0; +} +conn_info_t::conn_info_t() { + blob = 0; + re_init(); +} +void conn_info_t::prepare() { + assert(blob == 0); + blob = new blob_t; + if (program_mode == server_mode) { + blob->conv_manager.s.additional_clear_function = server_clear_function; + } else { + assert(program_mode == client_mode); + } +} + +conn_info_t::conn_info_t(const conn_info_t &b) { + assert(0 == 1); + // mylog(log_error,"called!!!!!!!!!!!!!\n"); +} + +conn_info_t &conn_info_t::operator=(const conn_info_t &b) { + mylog(log_fatal, "not allowed\n"); + myexit(-1); + return *this; +} +conn_info_t::~conn_info_t() { + if (program_mode == server_mode) { + if (state.server_current_state == server_ready) { + assert(blob != 0); + assert(oppsite_const_id != 0); + // assert(conn_manager.const_id_mp.find(oppsite_const_id)!=conn_manager.const_id_mp.end()); // conn_manager 's deconstuction function erases it + } else { + assert(blob == 0); + assert(oppsite_const_id == 0); + } + } + assert(timer_fd64 == 0); + // if(oppsite_const_id!=0) //do this at conn_manager 's deconstuction function + // conn_manager.const_id_mp.erase(oppsite_const_id); + if (blob != 0) + delete blob; + + // send_packet_info.protocol=g_packet_info_send.protocol; +} + +conn_manager_t::conn_manager_t() { + ready_num = 0; + mp.reserve(10007); + // clear_it=mp.begin(); + // timer_fd_mp.reserve(10007); + const_id_mp.reserve(10007); + // udp_fd_mp.reserve(100007); + last_clear_time = 0; + // current_ready_ip=0; + // current_ready_port=0; +} +int conn_manager_t::exist(address_t addr) { + // u64_t u64=0; + // u64=ip; + // u64<<=32u; + // u64|=port; + if (mp.find(addr) != mp.end()) { + return 1; + } + return 0; +} +/* +int insert(uint32_t ip,uint16_t port) +{ + uint64_t u64=0; + u64=ip; + u64<<=32u; + u64|=port; + mp[u64]; + return 0; +}*/ +conn_info_t *&conn_manager_t::find_insert_p(address_t addr) // be aware,the adress may change after rehash +{ + // u64_t u64=0; + // u64=ip; + // u64<<=32u; + // u64|=port; + unordered_map::iterator it = mp.find(addr); + if (it == mp.end()) { + mp[addr] = new conn_info_t; + // lru.new_key(addr); + } else { + // lru.update(addr); + } + return mp[addr]; +} +conn_info_t &conn_manager_t::find_insert(address_t addr) // be aware,the adress may change after rehash +{ + // u64_t u64=0; + // u64=ip; + // u64<<=32u; + // u64|=port; + unordered_map::iterator it = mp.find(addr); + if (it == mp.end()) { + mp[addr] = new conn_info_t; + // lru.new_key(addr); + } else { + // lru.update(addr); + } + return *mp[addr]; +} +int conn_manager_t::erase(unordered_map::iterator erase_it) { + if (erase_it->second->state.server_current_state == server_ready) { + ready_num--; + assert(i32_t(ready_num) != -1); + assert(erase_it->second != 0); + + assert(erase_it->second->timer_fd64 != 0); + + assert(fd_manager.exist(erase_it->second->timer_fd64)); + + assert(erase_it->second->oppsite_const_id != 0); + assert(const_id_mp.find(erase_it->second->oppsite_const_id) != const_id_mp.end()); + + // assert(timer_fd_mp.find(erase_it->second->timer_fd)!=timer_fd_mp.end()); + + const_id_mp.erase(erase_it->second->oppsite_const_id); + + fd_manager.fd64_close(erase_it->second->timer_fd64); + + erase_it->second->timer_fd64 = 0; + // timer_fd_mp.erase(erase_it->second->timer_fd); + // close(erase_it->second->timer_fd);// close will auto delte it from epoll + delete (erase_it->second); + mp.erase(erase_it->first); + } else { + assert(erase_it->second->blob == 0); + assert(erase_it->second->timer_fd64 == 0); + + assert(erase_it->second->oppsite_const_id == 0); + delete (erase_it->second); + mp.erase(erase_it->first); + } + return 0; +} +int conn_manager_t::clear_inactive() { + if (get_current_time() - last_clear_time > conn_clear_interval) { + last_clear_time = get_current_time(); + return clear_inactive0(); + } + return 0; +} +int conn_manager_t::clear_inactive0() { + unordered_map::iterator it; + unordered_map::iterator old_it; + + if (disable_conn_clear) return 0; + + // map::iterator it; + int cnt = 0; + it = clear_it; + int size = mp.size(); + int num_to_clean = size / conn_clear_ratio + conn_clear_min; // clear 1/10 each time,to avoid latency glitch + + mylog(log_trace, "mp.size() %d\n", size); + + num_to_clean = min(num_to_clean, (int)mp.size()); + u64_t current_time = get_current_time(); + + for (;;) { + if (cnt >= num_to_clean) break; + if (mp.begin() == mp.end()) break; + + if (it == mp.end()) { + it = mp.begin(); + } + + if (it->second->state.server_current_state == server_ready && current_time - it->second->last_hb_recv_time <= server_conn_timeout) { + it++; + } else if (it->second->state.server_current_state != server_ready && current_time - it->second->last_state_time <= server_handshake_timeout) { + it++; + } else if (it->second->blob != 0 && it->second->blob->conv_manager.s.get_size() > 0) { + assert(it->second->state.server_current_state == server_ready); + it++; + } else { + mylog(log_info, "[%s:%d]inactive conn cleared \n", it->second->raw_info.recv_info.new_src_ip.get_str1(), it->second->raw_info.recv_info.src_port); + old_it = it; + it++; + erase(old_it); + } + cnt++; + } + clear_it = it; + + return 0; +} + +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 +// you have to design the protocol carefully, so that you wont be affect by relay attack +{ + if (len < 0) { + mylog(log_debug, "input_len <0\n"); + return -1; + } + packet_info_t &send_info = raw_info.send_info; + packet_info_t &recv_info = raw_info.recv_info; + + char send_data_buf[buf_len]; // buf for send data and send hb + char send_data_buf2[buf_len]; + + // static send_bare[buf_len]; + iv_t iv = get_true_random_number_64(); + padding_t padding = get_true_random_number_64(); + + memcpy(send_data_buf, &iv, sizeof(iv)); + memcpy(send_data_buf + sizeof(iv), &padding, sizeof(padding)); + + send_data_buf[sizeof(iv) + sizeof(padding)] = 'b'; + memcpy(send_data_buf + sizeof(iv) + sizeof(padding) + 1, data, len); + int new_len = len + sizeof(iv) + sizeof(padding) + 1; + + if (my_encrypt(send_data_buf, send_data_buf2, new_len) != 0) { + return -1; + } + send_raw0(raw_info, send_data_buf2, new_len); + return 0; +} +int reserved_parse_bare(const char *input, int input_len, char *&data, int &len) // a sub function used in recv_bare +{ + static char recv_data_buf[buf_len]; + + if (input_len < 0) { + mylog(log_debug, "input_len <0\n"); + return -1; + } + if (my_decrypt(input, recv_data_buf, input_len) != 0) { + mylog(log_debug, "decrypt_fail in recv bare\n"); + return -1; + } + if (recv_data_buf[sizeof(iv_t) + sizeof(padding_t)] != 'b') { + mylog(log_debug, "not a bare packet\n"); + return -1; + } + len = input_len; + data = recv_data_buf + sizeof(iv_t) + sizeof(padding_t) + 1; + len -= sizeof(iv_t) + sizeof(padding_t) + 1; + if (len < 0) { + mylog(log_debug, "len <0\n"); + return -1; + } + return 0; +} +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 +// you have to design the protocol carefully, so that you wont be affect by relay attack +{ + packet_info_t &send_info = raw_info.send_info; + packet_info_t &recv_info = raw_info.recv_info; + + if (recv_raw0(raw_info, data, len) < 0) { + // printf("recv_raw_fail in recv bare\n"); + return -1; + } + + if (len >= max_data_len + 1) { + mylog(log_debug, "data_len=%d >= max_data_len+1,ignored", len); + return -1; + } + + mylog(log_trace, "data len=%d\n", len); + if ((raw_mode == mode_faketcp && (recv_info.syn == 1 || recv_info.ack != 1))) { + mylog(log_debug, "unexpect packet type recv_info.syn=%d recv_info.ack=%d \n", recv_info.syn, recv_info.ack); + return -1; + } + return reserved_parse_bare(data, len, data, len); +} + +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 +{ + packet_info_t &send_info = raw_info.send_info; + packet_info_t &recv_info = raw_info.recv_info; + + char *data; + int len; + // len=sizeof(id_t)*3; + if (numbers_to_char(id1, id2, id3, data, len) != 0) return -1; + if (send_bare(raw_info, data, len) != 0) { + mylog(log_warn, "send bare fail\n"); + return -1; + } + return 0; } /* int recv_handshake(packet_info_t &info,id_t &id1,id_t &id2,id_t &id3) { - char * data;int len; - if(recv_bare(info,data,len)!=0) return -1; + char * data;int len; + if(recv_bare(info,data,len)!=0) return -1; - if(char_to_numbers(data,len,id1,id2,id3)!=0) return -1; + if(char_to_numbers(data,len,id1,id2,id3)!=0) return -1; - return 0; + return 0; }*/ -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. +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. { + packet_info_t &send_info = conn_info.raw_info.send_info; + packet_info_t &recv_info = conn_info.raw_info.recv_info; - packet_info_t &send_info=conn_info.raw_info.send_info; - packet_info_t &recv_info=conn_info.raw_info.recv_info; - - if(type!='h'&&type!='d') - { - mylog(log_warn,"first byte is not h or d ,%x\n",type); - return -1; - } - - - char send_data_buf[buf_len]; //buf for send data and send hb - char send_data_buf2[buf_len]; - - my_id_t n_tmp_id=htonl(conn_info.my_id); - - memcpy(send_data_buf,&n_tmp_id,sizeof(n_tmp_id)); - - n_tmp_id=htonl(conn_info.oppsite_id); - - memcpy(send_data_buf+sizeof(n_tmp_id),&n_tmp_id,sizeof(n_tmp_id)); - - anti_replay_seq_t n_seq=hton64(conn_info.blob->anti_replay.get_new_seq_for_send()); - - memcpy(send_data_buf+sizeof(n_tmp_id)*2,&n_seq,sizeof(n_seq)); - - - send_data_buf[sizeof(n_tmp_id)*2+sizeof(n_seq)]=type; - send_data_buf[sizeof(n_tmp_id)*2+sizeof(n_seq)+1]=conn_info.my_roller; - - memcpy(send_data_buf+2+sizeof(n_tmp_id)*2+sizeof(n_seq),data,len);//data; - - int new_len=len+sizeof(n_seq)+sizeof(n_tmp_id)*2+2; - - if(g_fix_gro==0) - { - if (my_encrypt(send_data_buf, send_data_buf2, new_len) != 0) - { - return -1; - } - } - else - { - if (my_encrypt(send_data_buf, send_data_buf2+2, new_len) != 0) - { - return -1; - } - write_u16(send_data_buf2,new_len); - new_len+=2; - if(cipher_mode==cipher_xor) - { - send_data_buf2[0]^=gro_xor[0]; - send_data_buf2[1]^=gro_xor[1]; - } - else if(cipher_mode==cipher_aes128cbc||cipher_mode==cipher_aes128cbc) - { - aes_ecb_encrypt1(send_data_buf2); - } + if (type != 'h' && type != 'd') { + mylog(log_warn, "first byte is not h or d ,%x\n", type); + return -1; } + char send_data_buf[buf_len]; // buf for send data and send hb + char send_data_buf2[buf_len]; - if(send_raw0(conn_info.raw_info,send_data_buf2,new_len)!=0) return -1; + my_id_t n_tmp_id = htonl(conn_info.my_id); - if(after_send_raw0(conn_info.raw_info)!=0) return -1; + memcpy(send_data_buf, &n_tmp_id, sizeof(n_tmp_id)); - return 0; + n_tmp_id = htonl(conn_info.oppsite_id); + + memcpy(send_data_buf + sizeof(n_tmp_id), &n_tmp_id, sizeof(n_tmp_id)); + + anti_replay_seq_t n_seq = hton64(conn_info.blob->anti_replay.get_new_seq_for_send()); + + memcpy(send_data_buf + sizeof(n_tmp_id) * 2, &n_seq, sizeof(n_seq)); + + send_data_buf[sizeof(n_tmp_id) * 2 + sizeof(n_seq)] = type; + send_data_buf[sizeof(n_tmp_id) * 2 + sizeof(n_seq) + 1] = conn_info.my_roller; + + memcpy(send_data_buf + 2 + sizeof(n_tmp_id) * 2 + sizeof(n_seq), data, len); // data; + + int new_len = len + sizeof(n_seq) + sizeof(n_tmp_id) * 2 + 2; + + if (g_fix_gro == 0) { + if (my_encrypt(send_data_buf, send_data_buf2, new_len) != 0) { + return -1; + } + } else { + if (my_encrypt(send_data_buf, send_data_buf2 + 2, new_len) != 0) { + return -1; + } + write_u16(send_data_buf2, new_len); + new_len += 2; + if (cipher_mode == cipher_xor) { + send_data_buf2[0] ^= gro_xor[0]; + send_data_buf2[1] ^= gro_xor[1]; + } else if (cipher_mode == cipher_aes128cbc || cipher_mode == cipher_aes128cbc) { + aes_ecb_encrypt1(send_data_buf2); + } + } + + if (send_raw0(conn_info.raw_info, send_data_buf2, new_len) != 0) return -1; + + if (after_send_raw0(conn_info.raw_info) != 0) return -1; + + return 0; } -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. +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. { - packet_info_t &send_info=conn_info.raw_info.send_info; - packet_info_t &recv_info=conn_info.raw_info.recv_info; + packet_info_t &send_info = conn_info.raw_info.send_info; + packet_info_t &recv_info = conn_info.raw_info.recv_info; - char send_data_buf[buf_len]; - //send_data_buf[0]='d'; - u32_t n_conv_num=htonl(conv_num); - memcpy(send_data_buf,&n_conv_num,sizeof(n_conv_num)); - - memcpy(send_data_buf+sizeof(n_conv_num),data,len); - int new_len=len+sizeof(n_conv_num); - send_safer(conn_info,'d',send_data_buf,new_len); - return 0; + char send_data_buf[buf_len]; + // send_data_buf[0]='d'; + u32_t n_conv_num = htonl(conv_num); + memcpy(send_data_buf, &n_conv_num, sizeof(n_conv_num)); + memcpy(send_data_buf + sizeof(n_conv_num), data, len); + int new_len = len + sizeof(n_conv_num); + send_safer(conn_info, 'd', send_data_buf, new_len); + return 0; } -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 +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 { - static char recv_data_buf[buf_len]; + static char recv_data_buf[buf_len]; - // char *recv_data_buf=recv_data_buf0; //fix strict alias warning - if(my_decrypt(input,recv_data_buf,input_len)!=0) - { - //printf("decrypt fail\n"); - return -1; - } + // char *recv_data_buf=recv_data_buf0; //fix strict alias warning + if (my_decrypt(input, recv_data_buf, input_len) != 0) { + // printf("decrypt fail\n"); + return -1; + } + // char *a=recv_data_buf; + // id_t h_oppiste_id= ntohl ( *((id_t * )(recv_data_buf)) ); + my_id_t h_oppsite_id; + memcpy(&h_oppsite_id, recv_data_buf, sizeof(h_oppsite_id)); + h_oppsite_id = ntohl(h_oppsite_id); + // id_t h_my_id= ntohl ( *((id_t * )(recv_data_buf+sizeof(id_t))) ); + my_id_t h_my_id; + memcpy(&h_my_id, recv_data_buf + sizeof(my_id_t), sizeof(h_my_id)); + h_my_id = ntohl(h_my_id); - //char *a=recv_data_buf; - //id_t h_oppiste_id= ntohl ( *((id_t * )(recv_data_buf)) ); - my_id_t h_oppsite_id; - memcpy(&h_oppsite_id,recv_data_buf,sizeof(h_oppsite_id)); - h_oppsite_id=ntohl(h_oppsite_id); + // anti_replay_seq_t h_seq= ntoh64 ( *((anti_replay_seq_t * )(recv_data_buf +sizeof(id_t) *2 )) ); + anti_replay_seq_t h_seq; + memcpy(&h_seq, recv_data_buf + sizeof(my_id_t) * 2, sizeof(h_seq)); + h_seq = ntoh64(h_seq); - //id_t h_my_id= ntohl ( *((id_t * )(recv_data_buf+sizeof(id_t))) ); - my_id_t h_my_id; - memcpy(&h_my_id,recv_data_buf+sizeof(my_id_t),sizeof(h_my_id)); - h_my_id=ntohl(h_my_id); + if (h_oppsite_id != conn_info.oppsite_id || h_my_id != conn_info.my_id) { + mylog(log_debug, "id and oppsite_id verification failed %x %x %x %x \n", h_oppsite_id, conn_info.oppsite_id, h_my_id, conn_info.my_id); + return -1; + } - //anti_replay_seq_t h_seq= ntoh64 ( *((anti_replay_seq_t * )(recv_data_buf +sizeof(id_t) *2 )) ); - anti_replay_seq_t h_seq; - memcpy(&h_seq,recv_data_buf +sizeof(my_id_t) *2 ,sizeof(h_seq)); - h_seq=ntoh64(h_seq); + if (conn_info.blob->anti_replay.is_vaild(h_seq) != 1) { + mylog(log_debug, "dropped replay packet\n"); + return -1; + } - if(h_oppsite_id!=conn_info.oppsite_id||h_my_id!=conn_info.my_id) - { - mylog(log_debug,"id and oppsite_id verification failed %x %x %x %x \n",h_oppsite_id,conn_info.oppsite_id,h_my_id,conn_info.my_id); - return -1; - } + // printf("recv _len %d\n ",recv_len); + data = recv_data_buf + sizeof(anti_replay_seq_t) + sizeof(my_id_t) * 2; + len = input_len - (sizeof(anti_replay_seq_t) + sizeof(my_id_t) * 2); - if (conn_info.blob->anti_replay.is_vaild(h_seq) != 1) { - mylog(log_debug,"dropped replay packet\n"); - return -1; - } + if (data[0] != 'h' && data[0] != 'd') { + mylog(log_debug, "first byte is not h or d ,%x\n", data[0]); + return -1; + } - //printf("recv _len %d\n ",recv_len); - data=recv_data_buf+sizeof(anti_replay_seq_t)+sizeof(my_id_t)*2; - len=input_len-(sizeof(anti_replay_seq_t)+sizeof(my_id_t)*2 ); + uint8_t roller = data[1]; + type = data[0]; + data += 2; + len -= 2; - if(data[0]!='h'&&data[0]!='d') - { - mylog(log_debug,"first byte is not h or d ,%x\n",data[0]); - return -1; - } + if (len < 0) { + mylog(log_debug, "len <0 ,%d\n", len); + return -1; + } - uint8_t roller=data[1]; + if (roller != conn_info.oppsite_roller) { + conn_info.oppsite_roller = roller; + conn_info.last_oppsite_roller_time = get_current_time(); + } + if (hb_mode == 0) + conn_info.my_roller++; // increase on a successful recv + else if (hb_mode == 1) { + if (type == 'h') + conn_info.my_roller++; + } else { + mylog(log_fatal, "unknow hb_mode\n"); + myexit(-1); + } + if (after_recv_raw0(conn_info.raw_info) != 0) return -1; // TODO might need to move this function to somewhere else after --fix-gro is introduced - type=data[0]; - data+=2; - len-=2; - - if(len<0) - { - mylog(log_debug,"len <0 ,%d\n",len); - return -1; - } - - if(roller!=conn_info.oppsite_roller) - { - conn_info.oppsite_roller=roller; - conn_info.last_oppsite_roller_time=get_current_time(); - } - if(hb_mode==0) - conn_info.my_roller++;//increase on a successful recv - else if(hb_mode==1) - { - if(type=='h') - conn_info.my_roller++; - } - else - { - mylog(log_fatal,"unknow hb_mode\n"); - myexit(-1); - } - - - if(after_recv_raw0(conn_info.raw_info)!=0) return -1; //TODO might need to move this function to somewhere else after --fix-gro is introduced - - return 0; + return 0; } -int recv_safer_notused(conn_info_t &conn_info,char &type,char* &data,int &len)///safer transfer function with anti-replay,when mutually verification is done. +int recv_safer_notused(conn_info_t &conn_info, char &type, char *&data, int &len) /// safer transfer function with anti-replay,when mutually verification is done. { - packet_info_t &send_info=conn_info.raw_info.send_info; - packet_info_t &recv_info=conn_info.raw_info.recv_info; + packet_info_t &send_info = conn_info.raw_info.send_info; + packet_info_t &recv_info = conn_info.raw_info.recv_info; - char * recv_data;int recv_len; - //static char recv_data_buf[buf_len]; + char *recv_data; + int recv_len; + // static char recv_data_buf[buf_len]; - if(recv_raw0(conn_info.raw_info,recv_data,recv_len)!=0) return -1; + if (recv_raw0(conn_info.raw_info, recv_data, recv_len) != 0) return -1; - return reserved_parse_safer(conn_info,recv_data,recv_len,type,data,len); + return reserved_parse_safer(conn_info, recv_data, recv_len, type, data, len); } -int recv_safer_multi(conn_info_t &conn_info,vector &type_arr,vector &data_arr)///safer transfer function with anti-replay,when mutually verification is done. +int recv_safer_multi(conn_info_t &conn_info, vector &type_arr, vector &data_arr) /// safer transfer function with anti-replay,when mutually verification is done. { - packet_info_t &send_info=conn_info.raw_info.send_info; - packet_info_t &recv_info=conn_info.raw_info.recv_info; + packet_info_t &send_info = conn_info.raw_info.send_info; + packet_info_t &recv_info = conn_info.raw_info.recv_info; - char * recv_data;int recv_len; + char *recv_data; + int recv_len; assert(type_arr.empty()); assert(data_arr.empty()); - if(recv_raw0(conn_info.raw_info,recv_data,recv_len)!=0) return -1; + if (recv_raw0(conn_info.raw_info, recv_data, recv_len) != 0) return -1; char type; char *data; int len; - if(g_fix_gro==0) - { + if (g_fix_gro == 0) { int ret = reserved_parse_safer(conn_info, recv_data, recv_len, type, data, len); - if(ret==0) - { + if (ret == 0) { type_arr.push_back(type); - data_arr.emplace_back(data,data+len); - //std::copy(data,data+len,data_arr[0]); + data_arr.emplace_back(data, data + len); + // std::copy(data,data+len,data_arr[0]); } return 0; - } else - { - char *ori_recv_data=recv_data; - int ori_recv_len=recv_len; - //mylog(log_debug,"recv_len:%d\n",recv_len); - int cnt=0; - while(recv_len>=16) - { + } else { + char *ori_recv_data = recv_data; + int ori_recv_len = recv_len; + // mylog(log_debug,"recv_len:%d\n",recv_len); + int cnt = 0; + while (recv_len >= 16) { cnt++; int single_len_no_xor; - single_len_no_xor=read_u16(recv_data); + single_len_no_xor = read_u16(recv_data); int single_len; - if(cipher_mode==cipher_xor) - { - recv_data[0]^=gro_xor[0]; - recv_data[1]^=gro_xor[1]; - } - else if(cipher_mode==cipher_aes128cbc||cipher_mode==cipher_aes128cbc) - { - aes_ecb_decrypt1(recv_data); - } - single_len=read_u16(recv_data); - recv_len-=2; - recv_data+=2; - if(single_len > recv_len) - { - mylog(log_debug,"illegal single_len %d(%d), recv_len %d left,dropped\n",single_len,single_len_no_xor,recv_len); + if (cipher_mode == cipher_xor) { + recv_data[0] ^= gro_xor[0]; + recv_data[1] ^= gro_xor[1]; + } else if (cipher_mode == cipher_aes128cbc || cipher_mode == cipher_aes128cbc) { + aes_ecb_decrypt1(recv_data); + } + single_len = read_u16(recv_data); + recv_len -= 2; + recv_data += 2; + if (single_len > recv_len) { + mylog(log_debug, "illegal single_len %d(%d), recv_len %d left,dropped\n", single_len, single_len_no_xor, recv_len); break; } - if(single_len> max_data_len ) - { - mylog(log_warn,"single_len %d(%d) > %d, maybe you need to turn down mtu at upper level\n",single_len,single_len_no_xor,max_data_len); - break; + if (single_len > max_data_len) { + mylog(log_warn, "single_len %d(%d) > %d, maybe you need to turn down mtu at upper level\n", single_len, single_len_no_xor, max_data_len); + break; } int ret = reserved_parse_safer(conn_info, recv_data, single_len, type, data, len); - if(ret!=0) - { - mylog(log_debug,"parse failed, offset= %d,single_len=%d(%d)\n",(int)(recv_data-ori_recv_data),single_len,single_len_no_xor); - } else{ + if (ret != 0) { + mylog(log_debug, "parse failed, offset= %d,single_len=%d(%d)\n", (int)(recv_data - ori_recv_data), single_len, single_len_no_xor); + } else { type_arr.push_back(type); - data_arr.emplace_back(data,data+len); - //std::copy(data,data+len,data_arr[data_arr.size()-1]); + data_arr.emplace_back(data, data + len); + // std::copy(data,data+len,data_arr[data_arr.size()-1]); } - recv_data+=single_len; - recv_len-=single_len; + recv_data += single_len; + recv_len -= single_len; } - if(cnt>1) - { - mylog(log_debug,"got a suspected gro packet, %d packets recovered, recv_len=%d, loop_cnt=%d\n",(int)data_arr.size(),ori_recv_len,cnt); + if (cnt > 1) { + mylog(log_debug, "got a suspected gro packet, %d packets recovered, recv_len=%d, loop_cnt=%d\n", (int)data_arr.size(), ori_recv_len, cnt); } return 0; } } - -void server_clear_function(u64_t u64)//used in conv_manager in server mode.for server we have to use one udp fd for one conv(udp connection), -//so we have to close the fd when conv expires +void server_clear_function(u64_t u64) // used in conv_manager in server mode.for server we have to use one udp fd for one conv(udp connection), +// so we have to close the fd when conv expires { - //int fd=int(u64); -// int ret; - //assert(fd!=0); - /* - epoll_event ev; + // int fd=int(u64); + // int ret; + // assert(fd!=0); + /* + epoll_event ev; - ev.events = EPOLLIN; - ev.data.u64 = u64; + ev.events = EPOLLIN; + ev.data.u64 = u64; - ret = epoll_ctl(epollfd, EPOLL_CTL_DEL, fd, &ev); - if (ret!=0) - { - mylog(log_fatal,"fd:%d epoll delete failed!!!!\n",fd); - myexit(-1); //this shouldnt happen - }*/ //no need + ret = epoll_ctl(epollfd, EPOLL_CTL_DEL, fd, &ev); + if (ret!=0) + { + mylog(log_fatal,"fd:%d epoll delete failed!!!!\n",fd); + myexit(-1); //this shouldnt happen + }*/ + // no need - /*ret= close(fd); //closed fd should be auto removed from epoll + /*ret= close(fd); //closed fd should be auto removed from epoll - if (ret!=0) - { - mylog(log_fatal,"close fd %d failed !!!!\n",fd); - myexit(-1); //this shouldnt happen - }*/ - //mylog(log_fatal,"size:%d !!!!\n",conn_manager.udp_fd_mp.size()); - fd64_t fd64=u64; - assert(fd_manager.exist(fd64)); - fd_manager.fd64_close(fd64); + if (ret!=0) + { + mylog(log_fatal,"close fd %d failed !!!!\n",fd); + myexit(-1); //this shouldnt happen + }*/ + // mylog(log_fatal,"size:%d !!!!\n",conn_manager.udp_fd_mp.size()); + fd64_t fd64 = u64; + assert(fd_manager.exist(fd64)); + fd_manager.fd64_close(fd64); - //assert(conn_manager.udp_fd_mp.find(fd)!=conn_manager.udp_fd_mp.end()); - //conn_manager.udp_fd_mp.erase(fd); + // assert(conn_manager.udp_fd_mp.find(fd)!=conn_manager.udp_fd_mp.end()); + // conn_manager.udp_fd_mp.erase(fd); } diff --git a/connection.h b/connection.h index b581993..5529a3f 100644 --- a/connection.h +++ b/connection.h @@ -16,336 +16,298 @@ extern int disable_anti_replay; #include "network.h" #include "misc.h" -const int disable_conv_clear=0;//a udp connection in the multiplexer is called conversation in this program,conv for short. +const int disable_conv_clear = 0; // a udp connection in the multiplexer is called conversation in this program,conv for short. -struct anti_replay_t //its for anti replay attack,similar to openvpn/ipsec 's anti replay window +struct anti_replay_t // its for anti replay attack,similar to openvpn/ipsec 's anti replay window { - u64_t max_packet_received; - char window[anti_replay_window_size]; - anti_replay_seq_t anti_replay_seq; - anti_replay_seq_t get_new_seq_for_send(); - anti_replay_t(); - void re_init(); + u64_t max_packet_received; + char window[anti_replay_window_size]; + anti_replay_seq_t anti_replay_seq; + anti_replay_seq_t get_new_seq_for_send(); + anti_replay_t(); + void re_init(); - int is_vaild(u64_t seq); -};//anti_replay; + int is_vaild(u64_t seq); +}; // anti_replay; void server_clear_function(u64_t u64); #include -template +template struct conv_manager_t // manage the udp connections { - //typedef hash_map map; - unordered_map data_to_conv; //conv and u64 are both supposed to be uniq - unordered_map conv_to_data; + // typedef hash_map map; + unordered_map data_to_conv; // conv and u64 are both supposed to be uniq + unordered_map conv_to_data; - lru_collector_t lru; - //unordered_map conv_last_active_time; + lru_collector_t lru; + // unordered_map conv_last_active_time; - //unordered_map::iterator clear_it; + // unordered_map::iterator clear_it; - void (*additional_clear_function)(T data) =0; + void (*additional_clear_function)(T data) = 0; - long long last_clear_time; + long long last_clear_time; - conv_manager_t() - { - //clear_it=conv_last_active_time.begin(); - long long last_clear_time=0; - additional_clear_function=0; - } - ~conv_manager_t() - { - clear(); - } - int get_size() - { - return conv_to_data.size(); - } - void reserve() - { - data_to_conv.reserve(10007); - conv_to_data.reserve(10007); - //conv_last_active_time.reserve(10007); + conv_manager_t() { + // clear_it=conv_last_active_time.begin(); + long long last_clear_time = 0; + additional_clear_function = 0; + } + ~conv_manager_t() { + clear(); + } + int get_size() { + return conv_to_data.size(); + } + void reserve() { + data_to_conv.reserve(10007); + conv_to_data.reserve(10007); + // conv_last_active_time.reserve(10007); - lru.mp.reserve(10007); - } - void clear() - { - if(disable_conv_clear) return ; + lru.mp.reserve(10007); + } + void clear() { + if (disable_conv_clear) return; - if(additional_clear_function!=0) - { - for(auto it=conv_to_data.begin();it!=conv_to_data.end();it++) - { - //int fd=int((it->second<<32u)>>32u); - additional_clear_function( it->second); - } - } - data_to_conv.clear(); - conv_to_data.clear(); + if (additional_clear_function != 0) { + for (auto it = conv_to_data.begin(); it != conv_to_data.end(); it++) { + // int fd=int((it->second<<32u)>>32u); + additional_clear_function(it->second); + } + } + data_to_conv.clear(); + conv_to_data.clear(); - lru.clear(); - //conv_last_active_time.clear(); + lru.clear(); + // conv_last_active_time.clear(); - //clear_it=conv_last_active_time.begin(); + // clear_it=conv_last_active_time.begin(); + } + u32_t get_new_conv() { + u32_t conv = get_true_random_number_nz(); + while (conv_to_data.find(conv) != conv_to_data.end()) { + conv = get_true_random_number_nz(); + } + return conv; + } + int is_conv_used(u32_t conv) { + return conv_to_data.find(conv) != conv_to_data.end(); + } + int is_data_used(T data) { + return data_to_conv.find(data) != data_to_conv.end(); + } + u32_t find_conv_by_data(T data) { + return data_to_conv[data]; + } + T find_data_by_conv(u32_t conv) { + return conv_to_data[conv]; + } + int update_active_time(u32_t conv) { + // return conv_last_active_time[conv]=get_current_time(); + lru.update(conv); + return 0; + } + int insert_conv(u32_t conv, T data) { + data_to_conv[data] = conv; + conv_to_data[conv] = data; + // conv_last_active_time[conv]=get_current_time(); + lru.new_key(conv); + return 0; + } + int erase_conv(u32_t conv) { + if (disable_conv_clear) return 0; + T data = conv_to_data[conv]; + if (additional_clear_function != 0) { + additional_clear_function(data); + } + conv_to_data.erase(conv); + data_to_conv.erase(data); + // conv_last_active_time.erase(conv); + lru.erase(conv); + return 0; + } + int clear_inactive(char *info = 0) { + if (get_current_time() - last_clear_time > conv_clear_interval) { + last_clear_time = get_current_time(); + return clear_inactive0(info); + } + return 0; + } + int clear_inactive0(char *info) { + if (disable_conv_clear) return 0; - } - u32_t get_new_conv() - { - u32_t conv=get_true_random_number_nz(); - while(conv_to_data.find(conv)!=conv_to_data.end()) - { - conv=get_true_random_number_nz(); - } - return conv; - } - int is_conv_used(u32_t conv) - { - return conv_to_data.find(conv)!=conv_to_data.end(); - } - int is_data_used(T data) - { - return data_to_conv.find(data)!=data_to_conv.end(); - } - u32_t find_conv_by_data(T data) - { - return data_to_conv[data]; - } - T find_data_by_conv(u32_t conv) - { - return conv_to_data[conv]; - } - int update_active_time(u32_t conv) - { - //return conv_last_active_time[conv]=get_current_time(); - lru.update(conv); - return 0; - } - int insert_conv(u32_t conv,T data) - { - data_to_conv[data]=conv; - conv_to_data[conv]=data; - //conv_last_active_time[conv]=get_current_time(); - lru.new_key(conv); - return 0; - } - int erase_conv(u32_t conv) - { - if(disable_conv_clear) return 0; - T data=conv_to_data[conv]; - if(additional_clear_function!=0) - { - additional_clear_function(data); - } - conv_to_data.erase(conv); - data_to_conv.erase(data); - //conv_last_active_time.erase(conv); - lru.erase(conv); - return 0; - } - int clear_inactive(char * info=0) - { - if(get_current_time()-last_clear_time>conv_clear_interval) - { - last_clear_time=get_current_time(); - return clear_inactive0(info); - } - return 0; - } - int clear_inactive0(char * info) - { - if(disable_conv_clear) return 0; + unordered_map::iterator it; + unordered_map::iterator old_it; + // map::iterator it; + int cnt = 0; + // it=clear_it; + int size = lru.size(); + int num_to_clean = size / conv_clear_ratio + conv_clear_min; // clear 1/10 each time,to avoid latency glitch - unordered_map::iterator it; - unordered_map::iterator old_it; + num_to_clean = min(num_to_clean, size); - //map::iterator it; - int cnt=0; - //it=clear_it; - int size=lru.size(); - int num_to_clean=size/conv_clear_ratio+conv_clear_min; //clear 1/10 each time,to avoid latency glitch + my_time_t current_time = get_current_time(); + for (;;) { + if (cnt >= num_to_clean) break; + if (lru.empty()) break; - num_to_clean=min(num_to_clean,size); + u32_t conv; + my_time_t ts = lru.peek_back(conv); - my_time_t current_time=get_current_time(); - for(;;) - { - if(cnt>=num_to_clean) break; - if(lru.empty()) break; + if (current_time - ts < conv_timeout) break; - u32_t conv; - my_time_t ts=lru.peek_back(conv); + erase_conv(conv); + if (info == 0) { + mylog(log_info, "conv %x cleared\n", conv); + } else { + mylog(log_info, "[%s]conv %x cleared\n", info, conv); + } + cnt++; + } + return 0; + } - if(current_time- ts < conv_timeout) break; + /* +conv_manager_t(); +~conv_manager_t(); +int get_size(); +void reserve(); +void clear(); +u32_t get_new_conv(); +int is_conv_used(u32_t conv); +int is_u64_used(T u64); +u32_t find_conv_by_u64(T u64); +T find_u64_by_conv(u32_t conv); +int update_active_time(u32_t conv); +int insert_conv(u32_t conv,T u64); +int erase_conv(u32_t conv); +int clear_inactive(char * ip_port=0); +int clear_inactive0(char * ip_port);*/ +}; // g_conv_manager; - erase_conv(conv); - if(info==0) - { - mylog(log_info,"conv %x cleared\n",conv); - } - else - { - mylog(log_info,"[%s]conv %x cleared\n",info,conv); - } - cnt++; - } - return 0; - } - - - /* - conv_manager_t(); - ~conv_manager_t(); - int get_size(); - void reserve(); - void clear(); - u32_t get_new_conv(); - int is_conv_used(u32_t conv); - int is_u64_used(T u64); - u32_t find_conv_by_u64(T u64); - T find_u64_by_conv(u32_t conv); - int update_active_time(u32_t conv); - int insert_conv(u32_t conv,T u64); - int erase_conv(u32_t conv); - int clear_inactive(char * ip_port=0); - int clear_inactive0(char * ip_port);*/ -};//g_conv_manager; - -struct blob_t:not_copy_able_t //used in conn_info_t. +struct blob_t : not_copy_able_t // used in conn_info_t. { - union tmp_union_t//conv_manager_t is here to avoid copying when a connection is recovered - { - conv_manager_t c; - conv_manager_t s; - //avoid templates here and there, avoid pointer and type cast - tmp_union_t() - { - if(program_mode==client_mode) - { - new( &c ) conv_manager_t(); - } - else - { - assert(program_mode==server_mode); - new( &s ) conv_manager_t(); - } - } - ~tmp_union_t() - { - if(program_mode==client_mode) - { - c.~conv_manager_t(); - } - else - { - assert(program_mode==server_mode); - s.~conv_manager_t(); - } - } - }conv_manager; + union tmp_union_t // conv_manager_t is here to avoid copying when a connection is recovered + { + conv_manager_t c; + conv_manager_t s; + // avoid templates here and there, avoid pointer and type cast + tmp_union_t() { + if (program_mode == client_mode) { + new (&c) conv_manager_t(); + } else { + assert(program_mode == server_mode); + new (&s) conv_manager_t(); + } + } + ~tmp_union_t() { + if (program_mode == client_mode) { + c.~conv_manager_t(); + } else { + assert(program_mode == server_mode); + s.~conv_manager_t(); + } + } + } conv_manager; - anti_replay_t anti_replay;//anti_replay_t is here bc its huge,its allocation is delayed. + anti_replay_t anti_replay; // anti_replay_t is here bc its huge,its allocation is delayed. }; -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 -//handle multiple clients +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 +// handle multiple clients { - current_state_t state; + current_state_t state; - raw_info_t raw_info; - u64_t last_state_time; - u64_t last_hb_sent_time; //client re-use this for retry - u64_t last_hb_recv_time; - //long long last_resent_time; + raw_info_t raw_info; + u64_t last_state_time; + u64_t last_hb_sent_time; // client re-use this for retry + u64_t last_hb_recv_time; + // long long last_resent_time; - my_id_t my_id; - my_id_t oppsite_id; + my_id_t my_id; + my_id_t oppsite_id; + fd64_t timer_fd64; + fd64_t udp_fd64; - fd64_t timer_fd64; - fd64_t udp_fd64; + my_id_t oppsite_const_id; - my_id_t oppsite_const_id; + blob_t *blob; - blob_t *blob; + uint8_t my_roller; + uint8_t oppsite_roller; + u64_t last_oppsite_roller_time; - uint8_t my_roller; - uint8_t oppsite_roller; - u64_t last_oppsite_roller_time; + // ip_port_t ip_port; -// ip_port_t ip_port; + /* + const uint32_t &ip=raw_info.recv_info.src_ip; + const uint16_t &port=raw_info.recv_info.src_port; -/* - const uint32_t &ip=raw_info.recv_info.src_ip; - const uint16_t &port=raw_info.recv_info.src_port; + */ + void recover(const conn_info_t &conn_info); + void re_init(); + conn_info_t(); + void prepare(); + conn_info_t(const conn_info_t &b); + conn_info_t &operator=(const conn_info_t &b); + ~conn_info_t(); +}; // g_conn_info; -*/ - void recover(const conn_info_t &conn_info); - void re_init(); - conn_info_t(); - void prepare(); - conn_info_t(const conn_info_t&b); - conn_info_t& operator=(const conn_info_t& b); - ~conn_info_t(); -};//g_conn_info; - -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 +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 { + u32_t ready_num; - u32_t ready_num; + // unordered_map udp_fd_mp; //a bit dirty to used pointer,but can void unordered_map search + // unordered_map timer_fd_mp;//we can use pointer here since unordered_map.rehash() uses shallow copy - //unordered_map udp_fd_mp; //a bit dirty to used pointer,but can void unordered_map search - //unordered_map timer_fd_mp;//we can use pointer here since unordered_map.rehash() uses shallow copy + unordered_map const_id_mp; - unordered_map const_id_mp; + unordered_map mp; // put it at end so that it de-consturcts first - unordered_map mp; //put it at end so that it de-consturcts first + // lru_collector_t lru; - //lru_collector_t lru; + unordered_map::iterator clear_it; - unordered_map::iterator clear_it; + long long last_clear_time; - long long last_clear_time; - - conn_manager_t(); - int exist(address_t addr); - /* - int insert(uint32_t ip,uint16_t port) - { - uint64_t u64=0; - u64=ip; - u64<<=32u; - u64|=port; - mp[u64]; - return 0; - }*/ - conn_info_t *& find_insert_p(address_t addr); //be aware,the adress may change after rehash //not true? - conn_info_t & find_insert(address_t addr) ; //be aware,the adress may change after rehash - - int erase(unordered_map::iterator erase_it); -int clear_inactive(); -int clear_inactive0(); + conn_manager_t(); + int exist(address_t addr); + /* + int insert(uint32_t ip,uint16_t port) + { + uint64_t u64=0; + u64=ip; + u64<<=32u; + u64|=port; + mp[u64]; + return 0; + }*/ + conn_info_t *&find_insert_p(address_t addr); // be aware,the adress may change after rehash //not true? + conn_info_t &find_insert(address_t addr); // be aware,the adress may change after rehash + int erase(unordered_map::iterator erase_it); + int clear_inactive(); + int clear_inactive0(); }; extern conn_manager_t conn_manager; void server_clear_function(u64_t u64); -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 -//you have to design the protocol carefully, so that you wont be affect by relay attack -//int reserved_parse_bare(const char *input,int input_len,char* & data,int & len); // a sub function used in recv_bare -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 -//you have to design the protocol carefully, so that you wont be affect by relay attack -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 -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. -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. -//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 +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 +// you have to design the protocol carefully, so that you wont be affect by relay attack +// int reserved_parse_bare(const char *input,int input_len,char* & data,int & len); // a sub function used in recv_bare +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 +// you have to design the protocol carefully, so that you wont be affect by relay attack +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 +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. +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. +// 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 -//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. +// 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. -int recv_safer_multi(conn_info_t &conn_info,vector &type_arr,vector &data_arr);//new api for handle gro -#endif /* CONNECTION_H_ */ +int recv_safer_multi(conn_info_t &conn_info, vector &type_arr, vector &data_arr); // new api for handle gro +#endif /* CONNECTION_H_ */ diff --git a/encrypt.cpp b/encrypt.cpp old mode 100755 new mode 100644 index e0e5243..8fea0e4 --- a/encrypt.cpp +++ b/encrypt.cpp @@ -10,119 +10,128 @@ #include "common.h" #include "log.h" -//static uint64_t seq=1; +// static uint64_t seq=1; -static int8_t zero_iv[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0};//this prog use zero iv,you should make sure first block of data contains a random/nonce data +static int8_t zero_iv[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // this prog use zero iv,you should make sure first block of data contains a random/nonce data /**** * security of zero_iv + nonce first data block * https://crypto.stackexchange.com/questions/5421/using-cbc-with-a-fixed-iv-and-a-random-first-plaintext-block -****/ + ****/ -char normal_key[16 + 100];//generated from key_string by md5. reserved for compatiblity -const int hmac_key_len=64;//generate 512bit long keys, use first n chars when needed -const int cipher_key_len=64; -unsigned char hmac_key_encrypt[hmac_key_len + 100]; //key for hmac -unsigned char hmac_key_decrypt[hmac_key_len + 100]; //key for hmac -unsigned char cipher_key_encrypt[cipher_key_len + 100]; //key for aes etc. -unsigned char cipher_key_decrypt[cipher_key_len + 100]; //key for aes etc. +char normal_key[16 + 100]; // generated from key_string by md5. reserved for compatiblity +const int hmac_key_len = 64; // generate 512bit long keys, use first n chars when needed +const int cipher_key_len = 64; +unsigned char hmac_key_encrypt[hmac_key_len + 100]; // key for hmac +unsigned char hmac_key_decrypt[hmac_key_len + 100]; // key for hmac +unsigned char cipher_key_encrypt[cipher_key_len + 100]; // key for aes etc. +unsigned char cipher_key_decrypt[cipher_key_len + 100]; // key for aes etc. -char gro_xor[256+100];//dirty fix for gro +char gro_xor[256 + 100]; // dirty fix for gro -unordered_map auth_mode_tostring = {{auth_none, "none"}, {auth_md5, "md5"}, {auth_crc32, "crc32"},{auth_simple,"simple"},{auth_hmac_sha1,"hmac_sha1"},}; +unordered_map auth_mode_tostring = { + {auth_none, "none"}, + {auth_md5, "md5"}, + {auth_crc32, "crc32"}, + {auth_simple, "simple"}, + {auth_hmac_sha1, "hmac_sha1"}, +}; -unordered_map cipher_mode_tostring={{cipher_none,"none"},{cipher_aes128cfb,"aes128cfb"},{cipher_aes128cbc,"aes128cbc"},{cipher_xor,"xor"},}; -//TODO aes-gcm +unordered_map cipher_mode_tostring = { + {cipher_none, "none"}, + {cipher_aes128cfb, "aes128cfb"}, + {cipher_aes128cbc, "aes128cbc"}, + {cipher_xor, "xor"}, +}; +// TODO aes-gcm -auth_mode_t auth_mode=auth_md5; -cipher_mode_t cipher_mode=cipher_aes128cbc; -int is_hmac_used=0; +auth_mode_t auth_mode = auth_md5; +cipher_mode_t cipher_mode = cipher_aes128cbc; +int is_hmac_used = 0; -int aes128cfb_old=0; +int aes128cfb_old = 0; -//TODO key negotiation and forward secrecy +// TODO key negotiation and forward secrecy -int my_init_keys(const char * user_passwd,int is_client) -{ - char tmp[1000]=""; - int len=strlen(user_passwd); +int my_init_keys(const char *user_passwd, int is_client) { + char tmp[1000] = ""; + int len = strlen(user_passwd); - strcat(tmp,user_passwd); + strcat(tmp, user_passwd); - strcat(tmp,"key1"); + strcat(tmp, "key1"); - md5((uint8_t*)tmp,strlen(tmp),(uint8_t*)normal_key); + md5((uint8_t *)tmp, strlen(tmp), (uint8_t *)normal_key); + if (auth_mode == auth_hmac_sha1) + is_hmac_used = 1; + if (is_hmac_used || g_fix_gro || 1) { + unsigned char salt[400] = ""; + char salt_text[400] = "udp2raw_salt1"; + md5((uint8_t *)(salt_text), strlen(salt_text), salt); // TODO different salt per session - if(auth_mode==auth_hmac_sha1) - is_hmac_used=1; - if(is_hmac_used||g_fix_gro||1) - { - unsigned char salt[400]=""; - char salt_text[400]="udp2raw_salt1"; - md5((uint8_t*)(salt_text),strlen(salt_text),salt); //TODO different salt per session + unsigned char pbkdf2_output1[400] = ""; + PKCS5_PBKDF2_HMAC_SHA256((uint8_t *)user_passwd, len, salt, 16, 10000, 32, pbkdf2_output1); // TODO argon2 ? - unsigned char pbkdf2_output1[400]=""; - PKCS5_PBKDF2_HMAC_SHA256((uint8_t*)user_passwd,len,salt,16,10000, 32,pbkdf2_output1); //TODO argon2 ? + // unsigned char pbkdf2_output2[400]=""; + // PKCS5_PBKDF2_HMAC_SHA256(pbkdf2_output1,32,0,0,1, hmac_key_len*2+cipher_key_len*2,pbkdf2_output2); //stretch it - //unsigned char pbkdf2_output2[400]=""; - //PKCS5_PBKDF2_HMAC_SHA256(pbkdf2_output1,32,0,0,1, hmac_key_len*2+cipher_key_len*2,pbkdf2_output2); //stretch it + const char *info_hmac_encrypt = "hmac_key server-->client"; + const char *info_hmac_decrypt = "hmac_key client-->server"; + const char *info_cipher_encrypt = "cipher_key server-->client"; + const char *info_cipher_decrypt = "cipher_key client-->server"; - const char *info_hmac_encrypt="hmac_key server-->client"; - const char *info_hmac_decrypt="hmac_key client-->server"; - const char *info_cipher_encrypt="cipher_key server-->client"; - const char *info_cipher_decrypt="cipher_key client-->server"; + if (is_client) { + const char *tmp; + tmp = info_hmac_encrypt; + info_hmac_encrypt = info_hmac_decrypt; + info_hmac_decrypt = tmp; + tmp = info_cipher_encrypt; + info_cipher_encrypt = info_cipher_decrypt; + info_cipher_decrypt = tmp; + } else { + // nop + } - if(is_client) - { - const char *tmp; - tmp=info_hmac_encrypt; info_hmac_encrypt=info_hmac_decrypt;info_hmac_decrypt=tmp; - tmp=info_cipher_encrypt; info_cipher_encrypt=info_cipher_decrypt;info_cipher_decrypt=tmp; - } - else - { - //nop - } + assert(hkdf_sha256_expand(pbkdf2_output1, 32, (unsigned char *)info_cipher_encrypt, strlen(info_cipher_encrypt), cipher_key_encrypt, cipher_key_len) == 0); + assert(hkdf_sha256_expand(pbkdf2_output1, 32, (unsigned char *)info_cipher_decrypt, strlen(info_cipher_decrypt), cipher_key_decrypt, cipher_key_len) == 0); + assert(hkdf_sha256_expand(pbkdf2_output1, 32, (unsigned char *)info_hmac_encrypt, strlen(info_hmac_encrypt), hmac_key_encrypt, hmac_key_len) == 0); + assert(hkdf_sha256_expand(pbkdf2_output1, 32, (unsigned char *)info_hmac_decrypt, strlen(info_hmac_decrypt), hmac_key_decrypt, hmac_key_len) == 0); - assert( hkdf_sha256_expand( pbkdf2_output1,32, (unsigned char *)info_cipher_encrypt,strlen(info_cipher_encrypt), cipher_key_encrypt, cipher_key_len ) ==0); - assert( hkdf_sha256_expand( pbkdf2_output1,32, (unsigned char *)info_cipher_decrypt,strlen(info_cipher_decrypt), cipher_key_decrypt, cipher_key_len ) ==0); - assert( hkdf_sha256_expand( pbkdf2_output1,32, (unsigned char *)info_hmac_encrypt,strlen(info_hmac_encrypt), hmac_key_encrypt, hmac_key_len ) ==0); - assert( hkdf_sha256_expand( pbkdf2_output1,32, (unsigned char *)info_hmac_decrypt,strlen(info_hmac_decrypt), hmac_key_decrypt, hmac_key_len ) ==0); + const char *gro_info = "gro"; + assert(hkdf_sha256_expand(pbkdf2_output1, 32, (unsigned char *)gro_info, strlen(gro_info), (unsigned char *)gro_xor, 256) == 0); + } - const char *gro_info="gro"; - assert( hkdf_sha256_expand( pbkdf2_output1,32, (unsigned char *)gro_info,strlen(gro_info), (unsigned char *)gro_xor, 256 ) ==0); - } - - print_binary_chars(normal_key,16); - print_binary_chars((char *)hmac_key_encrypt,hmac_key_len); - print_binary_chars((char *)hmac_key_decrypt,hmac_key_len); - print_binary_chars((char *)cipher_key_encrypt,cipher_key_len); - print_binary_chars((char *)cipher_key_decrypt,cipher_key_len); + print_binary_chars(normal_key, 16); + print_binary_chars((char *)hmac_key_encrypt, hmac_key_len); + print_binary_chars((char *)hmac_key_decrypt, hmac_key_len); + print_binary_chars((char *)cipher_key_encrypt, cipher_key_len); + print_binary_chars((char *)cipher_key_decrypt, cipher_key_len); - return 0; + return 0; } /* * this function comes from http://www.hackersdelight.org/hdcodetxt/crc.c.txt */ -unsigned int crc32h(unsigned char *message,int len) { - int i, crc; - unsigned int byte, c; - const unsigned int g0 = 0xEDB88320, g1 = g0>>1, - g2 = g0>>2, g3 = g0>>3, g4 = g0>>4, g5 = g0>>5, - g6 = (g0>>6)^g0, g7 = ((g0>>6)^g0)>>1; +unsigned int crc32h(unsigned char *message, int len) { + int i, crc; + unsigned int byte, c; + const unsigned int g0 = 0xEDB88320, g1 = g0 >> 1, + g2 = g0 >> 2, g3 = g0 >> 3, g4 = g0 >> 4, g5 = g0 >> 5, + g6 = (g0 >> 6) ^ g0, g7 = ((g0 >> 6) ^ g0) >> 1; - i = 0; - crc = 0xFFFFFFFF; - while (i!=len) { // Get next byte. - byte = message[i]; - crc = crc ^ byte; - c = ((crc<<31>>31) & g7) ^ ((crc<<30>>31) & g6) ^ - ((crc<<29>>31) & g5) ^ ((crc<<28>>31) & g4) ^ - ((crc<<27>>31) & g3) ^ ((crc<<26>>31) & g2) ^ - ((crc<<25>>31) & g1) ^ ((crc<<24>>31) & g0); - crc = ((unsigned)crc >> 8) ^ c; - i = i + 1; - } - return ~crc; + i = 0; + crc = 0xFFFFFFFF; + while (i != len) { // Get next byte. + byte = message[i]; + crc = crc ^ byte; + c = ((crc << 31 >> 31) & g7) ^ ((crc << 30 >> 31) & g6) ^ + ((crc << 29 >> 31) & g5) ^ ((crc << 28 >> 31) & g4) ^ + ((crc << 27 >> 31) & g3) ^ ((crc << 26 >> 31) & g2) ^ + ((crc << 25 >> 31) & g1) ^ ((crc << 24 >> 31) & g0); + crc = ((unsigned)crc >> 8) ^ c; + i = i + 1; + } + return ~crc; } /* @@ -130,440 +139,450 @@ unsigned int crc32h(unsigned char *message,int len) { memset(res,0,sizeof(int)); for(int i=0,j=0;ipadding_num) return -1; - data_len-=(uint8_t)data[data_len-1]; - if(data_len<0) - { - return -1; - } - return 0; +int padding(char *data, int &data_len, int padding_num) { + int old_len = data_len; + data_len += 1; + if (data_len % padding_num != 0) { + data_len = (data_len / padding_num) * padding_num + padding_num; + } + unsigned char *p = (unsigned char *)&data[data_len - 1]; + *p = (data_len - old_len); + return 0; } -void aes_ecb_encrypt(const char *data,char *output) -{ - static int first_time=1; - char *key=(char*)cipher_key_encrypt; - if(aes_key_optimize) - { - if(first_time==0) key=0; - else first_time=0; - } - AES_ECB_encrypt_buffer((uint8_t*)data,(uint8_t*)key,(uint8_t*)output); + +int de_padding(const char *data, int &data_len, int padding_num) { + if (data_len == 0) return -1; + if ((uint8_t)data[data_len - 1] > padding_num) return -1; + data_len -= (uint8_t)data[data_len - 1]; + if (data_len < 0) { + return -1; + } + return 0; } -void aes_ecb_encrypt1(char *data) -{ +void aes_ecb_encrypt(const char *data, char *output) { + static int first_time = 1; + char *key = (char *)cipher_key_encrypt; + if (aes_key_optimize) { + if (first_time == 0) + key = 0; + else + first_time = 0; + } + AES_ECB_encrypt_buffer((uint8_t *)data, (uint8_t *)key, (uint8_t *)output); +} +void aes_ecb_encrypt1(char *data) { char buf[16]; - memcpy(buf,data,16); - aes_ecb_encrypt(buf,data); + memcpy(buf, data, 16); + aes_ecb_encrypt(buf, data); } -void aes_ecb_decrypt(const char *data,char *output) -{ - static int first_time=1; - char *key=(char*)cipher_key_decrypt; - if(aes_key_optimize) - { - if(first_time==0) key=0; - else first_time=0; - } - AES_ECB_decrypt_buffer((uint8_t*)data,(uint8_t*)key,(uint8_t*)output); +void aes_ecb_decrypt(const char *data, char *output) { + static int first_time = 1; + char *key = (char *)cipher_key_decrypt; + if (aes_key_optimize) { + if (first_time == 0) + key = 0; + else + first_time = 0; + } + AES_ECB_decrypt_buffer((uint8_t *)data, (uint8_t *)key, (uint8_t *)output); } -void aes_ecb_decrypt1(char *data) -{ +void aes_ecb_decrypt1(char *data) { char buf[16]; - memcpy(buf,data,16); - aes_ecb_decrypt(buf,data); + memcpy(buf, data, 16); + aes_ecb_decrypt(buf, data); } -int cipher_aes128cbc_encrypt(const char *data,char *output,int &len,char * key) -{ - static int first_time=1; +int cipher_aes128cbc_encrypt(const char *data, char *output, int &len, char *key) { + static int first_time = 1; - char buf[buf_len]; - memcpy(buf,data,len);//TODO inefficient code + char buf[buf_len]; + memcpy(buf, data, len); // TODO inefficient code - if(padding(buf,len,16)<0) return -1; + if (padding(buf, len, 16) < 0) return -1; - if(aes_key_optimize) - { - if(first_time==0) key=0; - else first_time=0; - } + if (aes_key_optimize) { + if (first_time == 0) + key = 0; + else + first_time = 0; + } - AES_CBC_encrypt_buffer((unsigned char *)output,(unsigned char *)buf,len,(unsigned char *)key,(unsigned char *)zero_iv); - return 0; + AES_CBC_encrypt_buffer((unsigned char *)output, (unsigned char *)buf, len, (unsigned char *)key, (unsigned char *)zero_iv); + return 0; } -int cipher_aes128cfb_encrypt(const char *data,char *output,int &len,char * key) -{ - static int first_time=1; - assert(len>=16); +int cipher_aes128cfb_encrypt(const char *data, char *output, int &len, char *key) { + static int first_time = 1; + assert(len >= 16); - char buf[buf_len]; - memcpy(buf,data,len);//TODO inefficient code - if(aes_key_optimize) - { - if(first_time==0) key=0; - else first_time=0; - } - if(!aes128cfb_old) - { - aes_ecb_encrypt(data,buf); //encrypt the first block - } + char buf[buf_len]; + memcpy(buf, data, len); // TODO inefficient code + if (aes_key_optimize) { + if (first_time == 0) + key = 0; + else + first_time = 0; + } + if (!aes128cfb_old) { + aes_ecb_encrypt(data, buf); // encrypt the first block + } - AES_CFB_encrypt_buffer((unsigned char *)output,(unsigned char *)buf,len,(unsigned char *)key,(unsigned char *)zero_iv); - return 0; + AES_CFB_encrypt_buffer((unsigned char *)output, (unsigned char *)buf, len, (unsigned char *)key, (unsigned char *)zero_iv); + return 0; } -int auth_crc32_verify(const char *data,int &len) -{ - if(lenmax_data_len) {mylog(log_warn,"len>max_data_len");return -1;} +int my_encrypt(const char *data, char *output, int &len /*,char * key*/) { + if (len < 0) { + mylog(log_trace, "len<0"); + return -1; + } + if (len > max_data_len) { + mylog(log_warn, "len>max_data_len"); + return -1; + } - if(is_hmac_used) - return encrypt_AE(data,output,len); - - - char buf[buf_len]; - char buf2[buf_len]; - memcpy(buf,data,len); - if(auth_cal(buf,buf2,len)!=0) {mylog(log_debug,"auth_cal failed ");return -1;} - if(cipher_encrypt(buf2,output,len,normal_key) !=0) {mylog(log_debug,"cipher_encrypt failed ");return -1;} - return 0; + if (is_hmac_used) + return encrypt_AE(data, output, len); + char buf[buf_len]; + char buf2[buf_len]; + memcpy(buf, data, len); + if (auth_cal(buf, buf2, len) != 0) { + mylog(log_debug, "auth_cal failed "); + return -1; + } + if (cipher_encrypt(buf2, output, len, normal_key) != 0) { + mylog(log_debug, "cipher_encrypt failed "); + return -1; + } + return 0; } -int my_decrypt(const char *data,char *output,int &len /*,char * key*/) -{ - if(len<0) return -1; - if(len>max_data_len) {mylog(log_warn,"len>max_data_len");return -1;} +int my_decrypt(const char *data, char *output, int &len /*,char * key*/) { + if (len < 0) return -1; + if (len > max_data_len) { + mylog(log_warn, "len>max_data_len"); + return -1; + } - if(is_hmac_used) - return decrypt_AE(data,output,len); + if (is_hmac_used) + return decrypt_AE(data, output, len); - if(cipher_decrypt(data,output,len,normal_key) !=0) {mylog(log_debug,"cipher_decrypt failed \n"); return -1;} - if(auth_verify(output,len)!=0) {mylog(log_debug,"auth_verify failed\n");return -1;} + if (cipher_decrypt(data, output, len, normal_key) != 0) { + mylog(log_debug, "cipher_decrypt failed \n"); + return -1; + } + if (auth_verify(output, len) != 0) { + mylog(log_debug, "auth_verify failed\n"); + return -1; + } - return 0; + return 0; } - -int encrypt_AEAD(uint8_t *data,uint8_t *output,int &len,uint8_t * key,uint8_t *header,int hlen) -{ - //TODO - return -1; +int encrypt_AEAD(uint8_t *data, uint8_t *output, int &len, uint8_t *key, uint8_t *header, int hlen) { + // TODO + return -1; } -int decrypt_AEAD(uint8_t *data,uint8_t *output,int &len,uint8_t * key,uint8_t *header,int hlen) -{ - //TODO - return -1; +int decrypt_AEAD(uint8_t *data, uint8_t *output, int &len, uint8_t *key, uint8_t *header, int hlen) { + // TODO + return -1; } - diff --git a/encrypt.h b/encrypt.h old mode 100755 new mode 100644 index 079fc07..db677c2 --- a/encrypt.h +++ b/encrypt.h @@ -1,33 +1,35 @@ #ifndef UDP2RAW_ENCRYPTION_H_ #define UDP2RAW_ENCRYPTION_H_ - - //#include "aes.h" //#include "md5.h" #include "common.h" +// using namespace std; +// extern char key[16]; -//using namespace std; -//extern char key[16]; - -const int aes_key_optimize=1; //if enabled,once you used a key for aes,you cant change it anymore +const int aes_key_optimize = 1; // if enabled,once you used a key for aes,you cant change it anymore extern int aes128cfb_old; -int my_init_keys(const char *,int); +int my_init_keys(const char *, int); -int my_encrypt(const char *data,char *output,int &len); -int my_decrypt(const char *data,char *output,int &len); +int my_encrypt(const char *data, char *output, int &len); +int my_decrypt(const char *data, char *output, int &len); +unsigned short csum(const unsigned short *ptr, int nbytes); -unsigned short csum(const unsigned short *ptr,int nbytes) ; - - -enum auth_mode_t {auth_none=0,auth_md5,auth_crc32,auth_simple,auth_hmac_sha1,auth_end}; - - -enum cipher_mode_t {cipher_none=0,cipher_aes128cbc,cipher_xor,cipher_aes128cfb,cipher_end}; +enum auth_mode_t { auth_none = 0, + auth_md5, + auth_crc32, + auth_simple, + auth_hmac_sha1, + auth_end }; +enum cipher_mode_t { cipher_none = 0, + cipher_aes128cbc, + cipher_xor, + cipher_aes128cfb, + cipher_end }; extern auth_mode_t auth_mode; extern cipher_mode_t cipher_mode; @@ -35,13 +37,13 @@ extern cipher_mode_t cipher_mode; extern unordered_map auth_mode_tostring; extern unordered_map cipher_mode_tostring; -extern char gro_xor[256+100]; +extern char gro_xor[256 + 100]; -int cipher_decrypt(const char *data,char *output,int &len,char * key);//internal interface ,exposed for test only -int cipher_encrypt(const char *data,char *output,int &len,char * key);//internal interface ,exposed for test only +int cipher_decrypt(const char *data, char *output, int &len, char *key); // internal interface ,exposed for test only +int cipher_encrypt(const char *data, char *output, int &len, char *key); // internal interface ,exposed for test only -void aes_ecb_encrypt(const char *data,char *output); -void aes_ecb_decrypt(const char *data,char *output); +void aes_ecb_encrypt(const char *data, char *output); +void aes_ecb_decrypt(const char *data, char *output); void aes_ecb_encrypt1(char *data); void aes_ecb_decrypt1(char *data); diff --git a/fd_manager.cpp b/fd_manager.cpp index c9472d7..7d0dfa4 100644 --- a/fd_manager.cpp +++ b/fd_manager.cpp @@ -5,60 +5,49 @@ * Author: root */ - #include "fd_manager.h" -int fd_manager_t::fd_exist(int fd) -{ - return fd_to_fd64_mp.find(fd)!=fd_to_fd64_mp.end(); +int fd_manager_t::fd_exist(int fd) { + return fd_to_fd64_mp.find(fd) != fd_to_fd64_mp.end(); } -int fd_manager_t::exist(fd64_t fd64) -{ - return fd64_to_fd_mp.find(fd64)!=fd64_to_fd_mp.end(); +int fd_manager_t::exist(fd64_t fd64) { + return fd64_to_fd_mp.find(fd64) != fd64_to_fd_mp.end(); } -int fd_manager_t::to_fd(fd64_t fd64) -{ - assert(exist(fd64)); - return fd64_to_fd_mp[fd64]; +int fd_manager_t::to_fd(fd64_t fd64) { + assert(exist(fd64)); + return fd64_to_fd_mp[fd64]; } -void fd_manager_t::fd64_close(fd64_t fd64) -{ - assert(exist(fd64)); - int fd=fd64_to_fd_mp[fd64]; - fd64_to_fd_mp.erase(fd64); - fd_to_fd64_mp.erase(fd); - if(exist_info(fd64)) - { - fd_info_mp.erase(fd64); - } - //assert(close(fd)==0); - sock_close(fd); +void fd_manager_t::fd64_close(fd64_t fd64) { + assert(exist(fd64)); + int fd = fd64_to_fd_mp[fd64]; + fd64_to_fd_mp.erase(fd64); + fd_to_fd64_mp.erase(fd); + if (exist_info(fd64)) { + fd_info_mp.erase(fd64); + } + // assert(close(fd)==0); + sock_close(fd); } -void fd_manager_t::reserve(int n) -{ - fd_to_fd64_mp.reserve(n); - fd64_to_fd_mp.reserve(n); - fd_info_mp.reserve(n); +void fd_manager_t::reserve(int n) { + fd_to_fd64_mp.reserve(n); + fd64_to_fd_mp.reserve(n); + fd_info_mp.reserve(n); } -u64_t fd_manager_t::create(int fd) -{ - assert(!fd_exist(fd)); - fd64_t fd64=counter++; - fd_to_fd64_mp[fd]=fd64; - fd64_to_fd_mp[fd64]=fd; - return fd64; +u64_t fd_manager_t::create(int fd) { + assert(!fd_exist(fd)); + fd64_t fd64 = counter++; + fd_to_fd64_mp[fd] = fd64; + fd64_to_fd_mp[fd64] = fd; + return fd64; } -fd_manager_t::fd_manager_t() -{ - counter=u32_t(-1); - counter+=100; - reserve(10007); +fd_manager_t::fd_manager_t() { + counter = u32_t(-1); + counter += 100; + reserve(10007); } -fd_info_t & fd_manager_t::get_info(fd64_t fd64) -{ - assert(exist(fd64)); - return fd_info_mp[fd64]; +fd_info_t& fd_manager_t::get_info(fd64_t fd64) { + assert(exist(fd64)); + return fd_info_mp[fd64]; } -int fd_manager_t::exist_info(fd64_t fd64) -{ - return fd_info_mp.find(fd64)!=fd_info_mp.end(); +int fd_manager_t::exist_info(fd64_t fd64) { + return fd_info_mp.find(fd64) != fd_info_mp.end(); } diff --git a/fd_manager.h b/fd_manager.h index 20cea91..786f7ae 100644 --- a/fd_manager.h +++ b/fd_manager.h @@ -12,31 +12,31 @@ //#include "packet.h" #include "connection.h" -struct fd_info_t -{ - //ip_port_t ip_port; - conn_info_t *p_conn_info; +struct fd_info_t { + // ip_port_t ip_port; + conn_info_t *p_conn_info; }; -struct fd_manager_t //conver fd to a uniq 64bit number,avoid fd value conflict caused by close and re-create -//this class is not strictly necessary,it just makes epoll fd handling easier +struct fd_manager_t // conver fd to a uniq 64bit number,avoid fd value conflict caused by close and re-create +// this class is not strictly necessary,it just makes epoll fd handling easier { - fd_info_t & get_info(fd64_t fd64); - int exist_info(fd64_t); - int exist(fd64_t fd64); - int to_fd(fd64_t); - void fd64_close(fd64_t fd64); - void reserve(int n); - u64_t create(int fd); - fd_manager_t(); -private: - u64_t counter; - unordered_map fd_to_fd64_mp; - unordered_map fd64_to_fd_mp; - unordered_map fd_info_mp; - int fd_exist(int fd); - //void remove_fd(int fd); - //fd64_t fd_to_fd64(int fd); + fd_info_t &get_info(fd64_t fd64); + int exist_info(fd64_t); + int exist(fd64_t fd64); + int to_fd(fd64_t); + void fd64_close(fd64_t fd64); + void reserve(int n); + u64_t create(int fd); + fd_manager_t(); + + private: + u64_t counter; + unordered_map fd_to_fd64_mp; + unordered_map fd64_to_fd_mp; + unordered_map fd_info_mp; + int fd_exist(int fd); + // void remove_fd(int fd); + // fd64_t fd_to_fd64(int fd); }; extern fd_manager_t fd_manager; diff --git a/log.cpp b/log.cpp old mode 100755 new mode 100644 index 89862f7..baee525 --- a/log.cpp +++ b/log.cpp @@ -1,62 +1,57 @@ #include "log.h" #include "misc.h" -int log_level=log_info; +int log_level = log_info; -int enable_log_position=0; -int enable_log_color=1; +int enable_log_position = 0; +int enable_log_color = 1; -void log0(const char * file,const char * function,int line,int level,const char* str, ...) { +void log0(const char* file, const char* function, int line, int level, const char* str, ...) { + if (level > log_level) return; + if (level > log_trace || level < 0) return; - if(level>log_level) return ; - if(level>log_trace||level<0) return ; + time_t timer; + char buffer[100]; + struct tm* tm_info; + time(&timer); + tm_info = localtime(&timer); - time_t timer; - char buffer[100]; - struct tm* tm_info; + if (enable_log_color) + printf("%s", log_color[level]); - time(&timer); - tm_info = localtime(&timer); + strftime(buffer, 100, "%Y-%m-%d %H:%M:%S", tm_info); + printf("[%s][%s]", buffer, log_text[level]); - if(enable_log_color) - printf("%s",log_color[level]); + if (enable_log_position) printf("[%s,func:%s,line:%d]", file, function, line); - strftime(buffer, 100, "%Y-%m-%d %H:%M:%S", tm_info); - printf("[%s][%s]",buffer,log_text[level]); + va_list vlist; + va_start(vlist, str); + vfprintf(stdout, str, vlist); + va_end(vlist); + if (enable_log_color) + printf("%s", RESET); - if(enable_log_position)printf("[%s,func:%s,line:%d]",file,function,line); + // printf("\n"); + // if(enable_log_color) + // printf(log_color[level]); + fflush(stdout); - va_list vlist; - va_start(vlist, str); - vfprintf(stdout, str, vlist); - va_end(vlist); - if(enable_log_color) - printf("%s",RESET); - - //printf("\n"); - //if(enable_log_color) - //printf(log_color[level]); - fflush(stdout); - - if(log_level==log_fatal) - { - about_to_exit=1; - } + if (log_level == log_fatal) { + about_to_exit = 1; + } } -void log_bare(int level,const char* str, ...) -{ - if(level>log_level) return ; - if(level>log_trace||level<0) return ; - if(enable_log_color) - printf("%s",log_color[level]); - va_list vlist; - va_start(vlist, str); - vfprintf(stdout, str, vlist); - va_end(vlist); - if(enable_log_color) - printf("%s",RESET); - fflush(stdout); - +void log_bare(int level, const char* str, ...) { + if (level > log_level) return; + if (level > log_trace || level < 0) return; + if (enable_log_color) + printf("%s", log_color[level]); + va_list vlist; + va_start(vlist, str); + vfprintf(stdout, str, vlist); + va_end(vlist); + if (enable_log_color) + printf("%s", RESET); + fflush(stdout); } diff --git a/log.h b/log.h old mode 100755 new mode 100644 index 341a558..9498ed1 --- a/log.h +++ b/log.h @@ -2,53 +2,46 @@ #ifndef UDP2RAW_LOG_MYLOG_H_ #define UDP2RAW_LOG_MYLOG_H_ - #include "common.h" - using namespace std; - -#define RED "\x1B[31m" -#define GRN "\x1B[32m" -#define YEL "\x1B[33m" -#define BLU "\x1B[34m" -#define MAG "\x1B[35m" -#define CYN "\x1B[36m" -#define WHT "\x1B[37m" +#define RED "\x1B[31m" +#define GRN "\x1B[32m" +#define YEL "\x1B[33m" +#define BLU "\x1B[34m" +#define MAG "\x1B[35m" +#define CYN "\x1B[36m" +#define WHT "\x1B[37m" #define RESET "\x1B[0m" +const int log_never = 0; +const int log_fatal = 1; +const int log_error = 2; +const int log_warn = 3; +const int log_info = 4; +const int log_debug = 5; +const int log_trace = 6; +const int log_end = 7; -const int log_never=0; -const int log_fatal=1; -const int log_error=2; -const int log_warn=3; -const int log_info=4; -const int log_debug=5; -const int log_trace=6; -const int log_end=7; - -const char log_text[][20]={"NEVER","FATAL","ERROR","WARN","INFO","DEBUG","TRACE",""}; -const char log_color[][20]={RED,RED,RED,YEL,GRN,MAG,""}; +const char log_text[][20] = {"NEVER", "FATAL", "ERROR", "WARN", "INFO", "DEBUG", "TRACE", ""}; +const char log_color[][20] = {RED, RED, RED, YEL, GRN, MAG, ""}; extern int log_level; extern int enable_log_position; extern int enable_log_color; - #ifdef MY_DEBUG -#define mylog(__first_argu__dummy_abcde__,...) printf(__VA_ARGS__) +#define mylog(__first_argu__dummy_abcde__, ...) printf(__VA_ARGS__) #else -#define mylog(...) log0(__FILE__,__FUNCTION__,__LINE__,__VA_ARGS__) +#define mylog(...) log0(__FILE__, __FUNCTION__, __LINE__, __VA_ARGS__) #endif - //#define mylog(__first_argu__dummy_abcde__,...) {;} -void log0(const char * file,const char * function,int line,int level,const char* str, ...); - -void log_bare(int level,const char* str, ...); +void log0(const char* file, const char* function, int line, int level, const char* str, ...); +void log_bare(int level, const char* str, ...); #endif diff --git a/main.cpp b/main.cpp old mode 100755 new mode 100644 index 62ec321..d40ca56 --- a/main.cpp +++ b/main.cpp @@ -7,114 +7,100 @@ #include "encrypt.h" #include "fd_manager.h" -void sigpipe_cb(struct ev_loop *l, ev_signal *w, int revents) -{ - mylog(log_info, "got sigpipe, ignored"); +void sigpipe_cb(struct ev_loop *l, ev_signal *w, int revents) { + mylog(log_info, "got sigpipe, ignored"); } -void sigterm_cb(struct ev_loop *l, ev_signal *w, int revents) -{ - mylog(log_info, "got sigterm, exit"); - myexit(0); +void sigterm_cb(struct ev_loop *l, ev_signal *w, int revents) { + mylog(log_info, "got sigterm, exit"); + myexit(0); } -void sigint_cb(struct ev_loop *l, ev_signal *w, int revents) -{ - mylog(log_info, "got sigint, exit"); - myexit(0); +void sigint_cb(struct ev_loop *l, ev_signal *w, int revents) { + mylog(log_info, "got sigint, exit"); + myexit(0); } int client_event_loop(); int server_event_loop(); -int main(int argc, char *argv[]) -{ - assert(sizeof(unsigned short)==2); - assert(sizeof(unsigned int)==4); - assert(sizeof(unsigned long long)==8); +int main(int argc, char *argv[]) { + assert(sizeof(unsigned short) == 2); + assert(sizeof(unsigned int) == 4); + assert(sizeof(unsigned long long) == 8); #ifdef UDP2RAW_MP - init_ws(); + init_ws(); #endif - dup2(1, 2);//redirect stderr to stdout + dup2(1, 2); // redirect stderr to stdout #if defined(__MINGW32__) - enable_log_color=0; + enable_log_color = 0; #endif - pre_process_arg(argc,argv); + pre_process_arg(argc, argv); - if(program_mode==client_mode) - { - struct ev_loop* loop=ev_default_loop(0); + if (program_mode == client_mode) { + struct ev_loop *loop = ev_default_loop(0); #if !defined(__MINGW32__) - ev_signal signal_watcher_sigpipe; - ev_signal_init(&signal_watcher_sigpipe, sigpipe_cb, SIGPIPE); - ev_signal_start(loop, &signal_watcher_sigpipe); + ev_signal signal_watcher_sigpipe; + ev_signal_init(&signal_watcher_sigpipe, sigpipe_cb, SIGPIPE); + ev_signal_start(loop, &signal_watcher_sigpipe); #endif - ev_signal signal_watcher_sigterm; - ev_signal_init(&signal_watcher_sigterm, sigterm_cb, SIGTERM); - ev_signal_start(loop, &signal_watcher_sigterm); + ev_signal signal_watcher_sigterm; + ev_signal_init(&signal_watcher_sigterm, sigterm_cb, SIGTERM); + ev_signal_start(loop, &signal_watcher_sigterm); - ev_signal signal_watcher_sigint; - ev_signal_init(&signal_watcher_sigint, sigint_cb, SIGINT); - ev_signal_start(loop, &signal_watcher_sigint); - } - else - { + ev_signal signal_watcher_sigint; + ev_signal_init(&signal_watcher_sigint, sigint_cb, SIGINT); + ev_signal_start(loop, &signal_watcher_sigint); + } else { #ifdef UDP2RAW_LINUX - signal(SIGINT, signal_handler); - signal(SIGHUP, signal_handler); - signal(SIGKILL, signal_handler); - signal(SIGTERM, signal_handler); - signal(SIGQUIT, signal_handler); + signal(SIGINT, signal_handler); + signal(SIGHUP, signal_handler); + signal(SIGKILL, signal_handler); + signal(SIGTERM, signal_handler); + signal(SIGQUIT, signal_handler); #else - mylog(log_fatal,"server mode not supported in multi-platform version\n"); - myexit(-1); + mylog(log_fatal, "server mode not supported in multi-platform version\n"); + myexit(-1); #endif - - } + } #if !defined(__MINGW32__) - if(geteuid() != 0) - { - mylog(log_warn,"root check failed, it seems like you are using a non-root account. we can try to continue, but it may fail. If you want to run udp2raw as non-root, you have to add iptables rule manually, and grant udp2raw CAP_NET_RAW capability, check README.md in repo for more info.\n"); - } - else - { - mylog(log_warn,"you can run udp2raw with non-root account for better security. check README.md in repo for more info.\n"); - } + if (geteuid() != 0) { + mylog(log_warn, "root check failed, it seems like you are using a non-root account. we can try to continue, but it may fail. If you want to run udp2raw as non-root, you have to add iptables rule manually, and grant udp2raw CAP_NET_RAW capability, check README.md in repo for more info.\n"); + } else { + mylog(log_warn, "you can run udp2raw with non-root account for better security. check README.md in repo for more info.\n"); + } #endif - mylog(log_info,"remote_ip=[%s], make sure this is a vaild IP address\n",remote_addr.get_ip()); + mylog(log_info, "remote_ip=[%s], make sure this is a vaild IP address\n", remote_addr.get_ip()); - //init_random_number_fd(); - srand(get_true_random_number_nz()); - const_id=get_true_random_number_nz(); + // init_random_number_fd(); + srand(get_true_random_number_nz()); + const_id = get_true_random_number_nz(); - mylog(log_info,"const_id:%x\n",const_id); + mylog(log_info, "const_id:%x\n", const_id); - my_init_keys(key_string,program_mode==client_mode?1:0); + my_init_keys(key_string, program_mode == client_mode ? 1 : 0); + + iptables_rule(); - iptables_rule(); - #ifdef UDP2RAW_LINUX - init_raw_socket(); + init_raw_socket(); #endif - if(program_mode==client_mode) - { - client_event_loop(); - } - else - { + if (program_mode == client_mode) { + client_event_loop(); + } else { #ifdef UDP2RAW_LINUX - server_event_loop(); + server_event_loop(); #else - mylog(log_fatal,"server mode not supported in multi-platform version\n"); - myexit(-1); + mylog(log_fatal, "server mode not supported in multi-platform version\n"); + myexit(-1); #endif - } + } - return 0; + return 0; } diff --git a/misc.cpp b/misc.cpp index 10656ed..737c9be 100644 --- a/misc.cpp +++ b/misc.cpp @@ -12,1565 +12,1312 @@ #include "connection.h" #include "fd_manager.h" - -int hb_mode=1; -int hb_len=1200; +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 +int mtu_warn = 1375; // if a packet larger than mtu warn is receviced,there will be a warning -int max_rst_to_show=15; +int max_rst_to_show = 15; -int max_rst_allowed=-1; +int max_rst_allowed = -1; -int enable_dns_resolve=0; +int enable_dns_resolve = 0; -int ttl_value=64; +int ttl_value = 64; fd_manager_t fd_manager; -//char remote_address[max_address_len]=""; -//char local_ip[100]="0.0.0.0", remote_ip[100]="255.255.255.255",source_ip[100]="0.0.0.0";//local_ip is for -l option,remote_ip for -r option,source for --source-ip -//u32_t local_ip_uint32,remote_ip_uint32,source_ip_uint32;//convert from last line. -//int local_port = -1, remote_port=-1,source_port=0;//similiar to local_ip remote_ip,buf for port.source_port=0 indicates --source-port is not enabled -address_t local_addr,remote_addr,source_addr; +// char remote_address[max_address_len]=""; +// char local_ip[100]="0.0.0.0", remote_ip[100]="255.255.255.255",source_ip[100]="0.0.0.0";//local_ip is for -l option,remote_ip for -r option,source for --source-ip +// u32_t local_ip_uint32,remote_ip_uint32,source_ip_uint32;//convert from last line. +// int local_port = -1, remote_port=-1,source_port=0;//similiar to local_ip remote_ip,buf for port.source_port=0 indicates --source-port is not enabled +address_t local_addr, remote_addr, source_addr; my_ip_t bind_addr; -int source_port=-1; +int source_port = -1; -int bind_addr_used=0; -int force_source_ip=0; //if --source-ip is enabled -int force_source_port=0; +int bind_addr_used = 0; +int force_source_ip = 0; // if --source-ip is enabled +int force_source_port = 0; -my_id_t const_id=0;//an id used for connection recovery,its generated randomly,it never change since its generated +my_id_t const_id = 0; // an id used for connection recovery,its generated randomly,it never change since its generated -int udp_fd=-1; //for client only. client use this fd to listen and handle udp connection -int bind_fd=-1; //bind only,never send or recv. its just a dummy fd for bind,so that other program wont occupy the same port +int udp_fd = -1; // for client only. client use this fd to listen and handle udp connection +int bind_fd = -1; // bind only,never send or recv. its just a dummy fd for bind,so that other program wont occupy the same port #ifdef UDP2RAW_LINUX -int epollfd=-1; //fd for epoll -int timer_fd=-1; //the general timer fd for client and server.for server this is not the only timer find,every connection has a timer fd. +int epollfd = -1; // fd for epoll +int timer_fd = -1; // the general timer fd for client and server.for server this is not the only timer find,every connection has a timer fd. #endif -int fail_time_counter=0;//determine if the max_fail_time is reached -int epoll_trigger_counter=0;//for debug only -int debug_flag=0;//for debug only +int fail_time_counter = 0; // determine if the max_fail_time is reached +int epoll_trigger_counter = 0; // for debug only +int debug_flag = 0; // for debug only +int simple_rule = 0; // deprecated. +int keep_rule = 0; // whether to monitor the iptables rule periodly,re-add if losted +int auto_add_iptables_rule = 0; // if -a is set +int generate_iptables_rule = 0; // if -g is set +int generate_iptables_rule_add = 0; // if --gen-add is set -int simple_rule=0; //deprecated. -int keep_rule=0; //whether to monitor the iptables rule periodly,re-add if losted -int auto_add_iptables_rule=0;//if -a is set -int generate_iptables_rule=0;//if -g is set -int generate_iptables_rule_add=0;// if --gen-add is set +int retry_on_error = 0; -int retry_on_error=0; +int debug_resend = 0; // debug only -int debug_resend=0; // debug only +char key_string[1000] = "secret key"; // -k option -char key_string[1000]= "secret key";// -k option +char fifo_file[1000] = ""; -char fifo_file[1000]=""; - -int clear_iptables=0; -int wait_xtables_lock=0; +int clear_iptables = 0; +int wait_xtables_lock = 0; #ifdef UDP2RAW_LINUX -string iptables_command0="iptables/ip6tables "; -string iptables_command=""; -string iptables_pattern=""; -int iptables_rule_added=0; -int iptables_rule_keeped=0; -int iptables_rule_keep_index=0; +string iptables_command0 = "iptables/ip6tables "; +string iptables_command = ""; +string iptables_pattern = ""; +int iptables_rule_added = 0; +int iptables_rule_keeped = 0; +int iptables_rule_keep_index = 0; #endif -program_mode_t program_mode=unset_mode;//0 unset; 1client 2server -raw_mode_t raw_mode=mode_faketcp; -u32_t raw_ip_version=(u32_t)-1; -unordered_map raw_mode_tostring = {{mode_faketcp, "faketcp"}, {mode_udp, "udp"}, {mode_icmp, "icmp"}}; +program_mode_t program_mode = unset_mode; // 0 unset; 1client 2server +raw_mode_t raw_mode = mode_faketcp; +u32_t raw_ip_version = (u32_t)-1; +unordered_map raw_mode_tostring = {{mode_faketcp, "faketcp"}, {mode_udp, "udp"}, {mode_icmp, "icmp"}}; -int about_to_exit=0; +int about_to_exit = 0; +int socket_buf_size = 1024 * 1024; +// int force_socket_buf=0; - - - -int socket_buf_size=1024*1024; -//int force_socket_buf=0; - - - -//char lower_level_arg[1000]; +// char lower_level_arg[1000]; #ifdef UDP2RAW_LINUX -int process_lower_level_arg()//handle --lower-level option +int process_lower_level_arg() // handle --lower-level option { - lower_level=1; - if(strcmp(optarg,"auto")==0) - { - return 0; - } + lower_level = 1; + if (strcmp(optarg, "auto") == 0) { + return 0; + } - lower_level_manual=1; - if (strchr(optarg, '#') == 0) { - mylog(log_fatal, - "lower-level parameter invaild,check help page for format\n"); - myexit(-1); - } - lower_level = 1; - u32_t hw[6]; - memset(hw, 0, sizeof(hw)); - sscanf(optarg, "%[^#]#%x:%x:%x:%x:%x:%x", if_name, &hw[0], &hw[1], &hw[2], - &hw[3], &hw[4], &hw[5]); + lower_level_manual = 1; + if (strchr(optarg, '#') == 0) { + mylog(log_fatal, + "lower-level parameter invaild,check help page for format\n"); + myexit(-1); + } + lower_level = 1; + u32_t hw[6]; + memset(hw, 0, sizeof(hw)); + sscanf(optarg, "%[^#]#%x:%x:%x:%x:%x:%x", if_name, &hw[0], &hw[1], &hw[2], + &hw[3], &hw[4], &hw[5]); - mylog(log_warn, - "make sure this is correct: if_name=<%s> dest_mac_adress=<%02x:%02x:%02x:%02x:%02x:%02x> \n", - if_name, hw[0], hw[1], hw[2], hw[3], hw[4], hw[5]); - for (int i = 0; i < 6; i++) { - dest_hw_addr[i] = uint8_t(hw[i]); - } - return 0; + mylog(log_warn, + "make sure this is correct: if_name=<%s> dest_mac_adress=<%02x:%02x:%02x:%02x:%02x:%02x> \n", + if_name, hw[0], hw[1], hw[2], hw[3], hw[4], hw[5]); + for (int i = 0; i < 6; i++) { + dest_hw_addr[i] = uint8_t(hw[i]); + } + return 0; } #endif -void print_help() -{ - char git_version_buf[100]={0}; - strncpy(git_version_buf,gitversion,10); - printf("udp2raw-tunnel\n"); - printf("git version:%s ",git_version_buf); - printf("build date:%s %s\n",__DATE__,__TIME__); - printf("repository: https://github.com/wangyu-/udp2raw-tunnel\n"); - printf("\n"); +void print_help() { + char git_version_buf[100] = {0}; + strncpy(git_version_buf, gitversion, 10); + printf("udp2raw-tunnel\n"); + printf("git version:%s ", git_version_buf); + printf("build date:%s %s\n", __DATE__, __TIME__); + printf("repository: https://github.com/wangyu-/udp2raw-tunnel\n"); + printf("\n"); #ifdef UDP2RAW_MP #ifdef NO_LIBNET - printf("libnet is disabled at compile time\n"); - printf("\n"); + printf("libnet is disabled at compile time\n"); + printf("\n"); #endif #endif - printf("usage:\n"); - printf(" run as client : ./this_program -c -l local_listen_ip:local_port -r server_address:server_port [options]\n"); - printf(" run as server : ./this_program -s -l server_listen_ip:server_port -r remote_address:remote_port [options]\n"); - printf("\n"); - printf("common options,these options must be same on both side:\n"); - printf(" --raw-mode available values:faketcp(default),udp,icmp and easy-faketcp\n"); - printf(" -k,--key password to gen symetric key,default:\"secret key\"\n"); - printf(" --cipher-mode available values:aes128cfb,aes128cbc(default),xor,none\n"); - printf(" --auth-mode available values:hmac_sha1,md5(default),crc32,simple,none\n"); - printf(" -a,--auto-rule auto add (and delete) iptables rule\n"); - printf(" -g,--gen-rule generate iptables rule then exit,so that you can copy and\n"); - printf(" add it manually.overrides -a\n"); - printf(" --disable-anti-replay disable anti-replay,not suggested\n"); - printf(" --fix-gro try to fix huge packet caused by GRO. this option is at an early stage.\n"); - printf(" make sure client and server are at same version.\n"); + printf("usage:\n"); + printf(" run as client : ./this_program -c -l local_listen_ip:local_port -r server_address:server_port [options]\n"); + printf(" run as server : ./this_program -s -l server_listen_ip:server_port -r remote_address:remote_port [options]\n"); + printf("\n"); + printf("common options,these options must be same on both side:\n"); + printf(" --raw-mode available values:faketcp(default),udp,icmp and easy-faketcp\n"); + printf(" -k,--key password to gen symetric key,default:\"secret key\"\n"); + printf(" --cipher-mode available values:aes128cfb,aes128cbc(default),xor,none\n"); + printf(" --auth-mode available values:hmac_sha1,md5(default),crc32,simple,none\n"); + printf(" -a,--auto-rule auto add (and delete) iptables rule\n"); + printf(" -g,--gen-rule generate iptables rule then exit,so that you can copy and\n"); + printf(" add it manually.overrides -a\n"); + printf(" --disable-anti-replay disable anti-replay,not suggested\n"); + printf(" --fix-gro try to fix huge packet caused by GRO. this option is at an early stage.\n"); + printf(" make sure client and server are at same version.\n"); - //printf("\n"); - printf("client options:\n"); - printf(" --source-ip force source-ip for raw socket\n"); - printf(" --source-port force source-port for raw socket,tcp/udp only\n"); - printf(" this option disables port changing while re-connecting\n"); -// printf(" \n"); - printf("other options:\n"); - printf(" --conf-file read options from a configuration file instead of command line.\n"); - printf(" check example.conf in repo for format\n"); - printf(" --fifo use a fifo(named pipe) for sending commands to the running program,\n"); - printf(" check readme.md in repository for supported commands.\n"); - printf(" --log-level 0:never 1:fatal 2:error 3:warn \n"); - printf(" 4:info (default) 5:debug 6:trace\n"); -// printf("\n"); - printf(" --log-position enable file name,function name,line number in log\n"); - printf(" --disable-color disable log color\n"); - printf(" --disable-bpf disable the kernel space filter,most time its not necessary\n"); - printf(" unless you suspect there is a bug\n"); + // printf("\n"); + printf("client options:\n"); + printf(" --source-ip force source-ip for raw socket\n"); + printf(" --source-port force source-port for raw socket,tcp/udp only\n"); + printf(" this option disables port changing while re-connecting\n"); + // printf(" \n"); + printf("other options:\n"); + printf(" --conf-file read options from a configuration file instead of command line.\n"); + printf(" check example.conf in repo for format\n"); + printf(" --fifo use a fifo(named pipe) for sending commands to the running program,\n"); + printf(" check readme.md in repository for supported commands.\n"); + printf(" --log-level 0:never 1:fatal 2:error 3:warn \n"); + printf(" 4:info (default) 5:debug 6:trace\n"); + // printf("\n"); + printf(" --log-position enable file name,function name,line number in log\n"); + printf(" --disable-color disable log color\n"); + printf(" --disable-bpf disable the kernel space filter,most time its not necessary\n"); + printf(" unless you suspect there is a bug\n"); // printf("\n"); #ifdef UDP2RAW_LINUX - printf(" --dev bind raw socket to a device, not necessary but improves performance\n"); + printf(" --dev bind raw socket to a device, not necessary but improves performance\n"); #endif - printf(" --sock-buf buf size for socket,>=10 and <=10240,unit:kbyte,default:1024\n"); - printf(" --force-sock-buf bypass system limitation while setting sock-buf\n"); - printf(" --seq-mode seq increase mode for faketcp:\n"); - printf(" 0:static header,do not increase seq and ack_seq\n"); - printf(" 1:increase seq for every packet,simply ack last seq\n"); - printf(" 2:increase seq randomly, about every 3 packets,simply ack last seq\n"); - printf(" 3:simulate an almost real seq/ack procedure(default)\n"); - printf(" 4:similiar to 3,but do not consider TCP Option Window_Scale,\n"); - printf(" maybe useful when firewall doesnt support TCP Option \n"); -// printf("\n"); - printf(" --lower-level send packets at OSI level 2, format:'if_name#dest_mac_adress'\n"); - printf(" ie:'eth0#00:23:45:67:89:b9'.or try '--lower-level auto' to obtain\n"); - printf(" the parameter automatically,specify it manually if 'auto' failed\n"); - printf(" --wait-lock wait for xtables lock while invoking iptables, need iptables v1.4.20+\n"); - printf(" --gen-add generate iptables rule and add it permanently,then exit.overrides -g\n"); - printf(" --keep-rule monitor iptables and auto re-add if necessary.implys -a\n"); - printf(" --hb-len length of heart-beat packet, >=0 and <=1500\n"); - printf(" --mtu-warn mtu warning threshold, unit:byte, default:1375\n"); - printf(" --clear clear any iptables rules added by this program.overrides everything\n"); - printf(" --retry-on-error retry on error, allow to start udp2raw before network is initialized\n"); - printf(" -h,--help print this help message\n"); - //printf("common options,these options must be same on both side\n"); + printf(" --sock-buf buf size for socket,>=10 and <=10240,unit:kbyte,default:1024\n"); + printf(" --force-sock-buf bypass system limitation while setting sock-buf\n"); + printf(" --seq-mode seq increase mode for faketcp:\n"); + printf(" 0:static header,do not increase seq and ack_seq\n"); + printf(" 1:increase seq for every packet,simply ack last seq\n"); + printf(" 2:increase seq randomly, about every 3 packets,simply ack last seq\n"); + printf(" 3:simulate an almost real seq/ack procedure(default)\n"); + printf(" 4:similiar to 3,but do not consider TCP Option Window_Scale,\n"); + printf(" maybe useful when firewall doesnt support TCP Option \n"); + // printf("\n"); + printf(" --lower-level send packets at OSI level 2, format:'if_name#dest_mac_adress'\n"); + printf(" ie:'eth0#00:23:45:67:89:b9'.or try '--lower-level auto' to obtain\n"); + printf(" the parameter automatically,specify it manually if 'auto' failed\n"); + printf(" --wait-lock wait for xtables lock while invoking iptables, need iptables v1.4.20+\n"); + printf(" --gen-add generate iptables rule and add it permanently,then exit.overrides -g\n"); + printf(" --keep-rule monitor iptables and auto re-add if necessary.implys -a\n"); + printf(" --hb-len length of heart-beat packet, >=0 and <=1500\n"); + printf(" --mtu-warn mtu warning threshold, unit:byte, default:1375\n"); + printf(" --clear clear any iptables rules added by this program.overrides everything\n"); + printf(" --retry-on-error retry on error, allow to start udp2raw before network is initialized\n"); + printf(" -h,--help print this help message\n"); + // printf("common options,these options must be same on both side\n"); } -int load_config(char *file_name, int &argc, vector &argv) //load conf file and append to argv +int load_config(char *file_name, int &argc, vector &argv) // load conf file and append to argv { - // Load configurations from config_file instead of the command line. - // See config.example for example configurations - std::ifstream conf_file(file_name); - std::string line; - if(conf_file.fail()) - { - mylog(log_fatal,"conf_file %s open failed,reason :%s\n",file_name,get_sock_error()); - myexit(-1); - } - while(std::getline(conf_file,line)) - { - auto res=parse_conf_line(line); + // Load configurations from config_file instead of the command line. + // See config.example for example configurations + std::ifstream conf_file(file_name); + std::string line; + if (conf_file.fail()) { + mylog(log_fatal, "conf_file %s open failed,reason :%s\n", file_name, get_sock_error()); + myexit(-1); + } + while (std::getline(conf_file, line)) { + auto res = parse_conf_line(line); - argc+=res.size(); - for(int i=0;i<(int)res.size();i++) - { - argv.push_back(res[i]); - } - } - conf_file.close(); + argc += res.size(); + for (int i = 0; i < (int)res.size(); i++) { + argv.push_back(res[i]); + } + } + conf_file.close(); - return 0; + return 0; } -int process_log_level(int argc,char *argv[])//process --log-level and --disable-cloer --log-postion options +int process_log_level(int argc, char *argv[]) // process --log-level and --disable-cloer --log-postion options { - int i,j,k; - for (i = 0; i < argc; i++) - { - if(strcmp(argv[i],"--log-level")==0) - { - if(i all_options; - map shortcut_map; - - all_options.insert("--help"); - all_options.insert("-h"); - string dummy=""; - for(i=0;i<(int)strlen(options);i++) - { - - char val=options[i]; - if( ( val>='0'&&val<='9') ||( val>='a'&&val<='z')||(val>='A'&&val<='Z')) - { - all_options.insert(dummy+'-'+val); - } - } - for(i=0;i='0'&&val<='9') ||( val>='a'&&val<='z')||(val>='A'&&val<='Z')) - { - shortcut_map[dummy+"--"+long_options[i].name]= dummy+"-"+ char(val); - } - all_options.insert(dummy+"--"+long_options[i].name); - } - - for (i = 0; i < argc; i++) - { - int len=strlen(argv[i]); - if(len==0) - { - mylog(log_fatal,"found an empty string in options\n"); - myexit(-1); - } - if(len==1&&argv[i][0]=='-' ) - { - mylog(log_fatal,"invaild option '-' in argv\n"); - myexit(-1); - } - if(len==2&&argv[i][0]=='-'&&argv[i][1]=='-' ) - { - mylog(log_fatal,"invaild option '--' in argv\n"); - myexit(-1); - } - } - - mylog(log_info,"argc=%d ", argc); - - for (i = 0; i < argc; i++) { - log_bare(log_info, "%s ", argv[i]); - } - log_bare(log_info, "\n"); - - //string dummy=""; - for(i=+1;i10000) - { - mylog(log_fatal,"random_drop must be between 0 10000 \n"); - myexit(-1); - } - mylog(log_info,"random_drop =%d \n",random_drop); - } - else if(strcmp(long_options[option_index].name,"fifo")==0) - { -if(is_udp2raw_mp) -{ - mylog(log_fatal,"--fifo not supported in this version\n"); - myexit(-1); -} - sscanf(optarg,"%s",fifo_file); - - mylog(log_info,"fifo_file =%s \n",fifo_file); - } - else if(strcmp(long_options[option_index].name,"conf-file")==0) - { - mylog(log_info,"configuration loaded from %s\n",optarg); - } - else if(strcmp(long_options[option_index].name,"hb-mode")==0) - { - sscanf(optarg,"%d",&hb_mode); - assert(hb_mode==0||hb_mode==1); - mylog(log_info,"hb_mode =%d \n",hb_mode); - } - else if(strcmp(long_options[option_index].name,"hb-len")==0) - { - sscanf(optarg,"%d",&hb_len); - assert(hb_len>=0&&hb_len<=1500); - mylog(log_info,"hb_len =%d \n",hb_len); - } - else if(strcmp(long_options[option_index].name,"mtu-warn")==0) - { - sscanf(optarg,"%d",&mtu_warn); - assert(mtu_warn>0); - mylog(log_info,"mtu_warn=%d \n",mtu_warn); - } - else if(strcmp(long_options[option_index].name,"max-rst-to-show")==0) - { - sscanf(optarg,"%d",&max_rst_to_show); - assert(max_rst_to_show>=-1); - mylog(log_info,"max_rst_to_show=%d \n",max_rst_to_show); - } - else if(strcmp(long_options[option_index].name,"max-rst-allowed")==0) - { - sscanf(optarg,"%d",&max_rst_allowed); - assert(max_rst_allowed>=-1); - mylog(log_info,"max_rst_allowed=%d \n",max_rst_allowed); - } - else if(strcmp(long_options[option_index].name,"set-ttl")==0) - { - sscanf(optarg,"%d",&ttl_value); - assert(ttl_value>=0&&ttl_value<=255); - mylog(log_info,"ttl_value=%d\n",ttl_value); - } - - else if(strcmp(long_options[option_index].name,"dns-resolve")==0) // currently not used - { - enable_dns_resolve=1; - mylog(log_info,"dns-resolve enabled\n"); - } -#ifdef UDP2RAW_MP - else if(strcmp(long_options[option_index].name,"pcap-send")==0) - { - send_with_pcap=1; - mylog(log_info,"--pcap-send enabled, now pcap will be used for sending packet instead of libnet\n"); - } - else if(strcmp(long_options[option_index].name,"no-pcap-mutex")==0) - { - use_pcap_mutex=0; - mylog(log_warn,"--no-pcap-mutex enabled, we will assume the underlying pcap calls are threadsafe\n"); - } -#endif - else if(strcmp(long_options[option_index].name,"easy-tcp")==0) - { - use_tcp_dummy_socket=1; - mylog(log_info,"--easy-tcp enabled, now a dummy tcp socket will be created for handshake and block rst\n"); - } - else if(strcmp(long_options[option_index].name,"fix-gro")==0) - { - mylog(log_info,"--fix-gro enabled\n"); - g_fix_gro=1; + int i, j, k; + for (i = 0; i < argc; i++) { + if (strcmp(argv[i], "--log-level") == 0) { + if (i < argc - 1) { + sscanf(argv[i + 1], "%d", &log_level); + if (0 <= log_level && log_level < log_end) { + } else { + log_bare(log_fatal, "invalid log_level\n"); + myexit(-1); + } } - else - { - mylog(log_warn,"ignored unknown long option ,option_index:%d code:<%x>\n",option_index, optopt); - } - break; - default: - mylog(log_fatal,"unknown option ,code:<%c>,<%x>\n",optopt, optopt); - myexit(-1); - } - } + } + if (strcmp(argv[i], "--enable-color") == 0) { + enable_log_color = 1; + } + if (strcmp(argv[i], "--disable-color") == 0) { + enable_log_color = 0; + } + if (strcmp(argv[i], "--log-position") == 0) { + enable_log_position = 1; + } + } + return 0; +} +void process_arg(int argc, char *argv[]) // process all options +{ + int i, j, k, opt; - if (no_l) - mylog(log_fatal,"error: -l not found\n"); - if (no_r) - mylog(log_fatal,"error: -r not found\n"); - if(program_mode==0) - mylog(log_fatal,"error: -c /-s hasnt been set\n"); - if (no_l || no_r||program_mode==0) - { - print_help(); - myexit(-1); - } - if(program_mode==client_mode) - { - raw_ip_version=remote_addr.get_type(); - } - else - { - raw_ip_version=local_addr.get_type(); - } + int option_index = 0; - if(auto_add_iptables_rule&& use_tcp_dummy_socket) - { - mylog(log_error,"-a,--auto-rule is not supposed to be used with easyfaketcp mode, you are likely making a mistake, but we can try to continue\n"); - } + char options[] = "l:r:schk:ag"; + static struct option long_options[] = + { + /* These options set a flag. */ + {"source-ip", required_argument, 0, 1}, + {"source-port", required_argument, 0, 1}, + {"log-level", required_argument, 0, 1}, + {"key", required_argument, 0, 'k'}, + {"auth-mode", required_argument, 0, 1}, + {"cipher-mode", required_argument, 0, 1}, + {"raw-mode", required_argument, 0, 1}, + {"disable-color", no_argument, 0, 1}, + {"enable-color", no_argument, 0, 1}, + {"log-position", no_argument, 0, 1}, + {"disable-bpf", no_argument, 0, 1}, + {"disable-anti-replay", no_argument, 0, 1}, + {"auto-rule", no_argument, 0, 'a'}, + {"gen-rule", no_argument, 0, 'g'}, + {"gen-add", no_argument, 0, 1}, + {"debug", no_argument, 0, 1}, + {"retry-on-error", no_argument, 0, 1}, + {"clear", no_argument, 0, 1}, + {"simple-rule", no_argument, 0, 1}, + {"keep-rule", no_argument, 0, 1}, + {"lower-level", required_argument, 0, 1}, + {"sock-buf", required_argument, 0, 1}, + {"seq-mode", required_argument, 0, 1}, + {"conf-file", required_argument, 0, 1}, + {"force-sock-buf", no_argument, 0, 1}, + {"wait-lock", no_argument, 0, 1}, + {"random-drop", required_argument, 0, 1}, + {"fifo", required_argument, 0, 1}, + {"hb-mode", required_argument, 0, 1}, + {"hb-len", required_argument, 0, 1}, + {"mtu-warn", required_argument, 0, 1}, + {"max-rst-to-show", required_argument, 0, 1}, + {"max-rst-allowed", required_argument, 0, 1}, + {"set-ttl", required_argument, 0, 1}, + {"dev", required_argument, 0, 1}, + {"dns-resolve", no_argument, 0, 1}, + {"easy-tcp", no_argument, 0, 1}, +#ifdef UDP2RAW_MP + {"pcap-send", no_argument, 0, 1}, + {"no-pcap-mutex", no_argument, 0, 1}, +#endif + {"fix-gro", no_argument, 0, 1}, + {NULL, 0, 0, 0}}; - if(keep_rule&& use_tcp_dummy_socket) - { - mylog(log_error,"--keep-rule is not supposed to be used with easyfaketcp mode, you are likely making a mistake, but we can try to continue\n"); - } + process_log_level(argc, argv); - mylog(log_info,"important variables: "); + set all_options; + map shortcut_map; - log_bare(log_info,"log_level=%d:%s ",log_level,log_text[log_level]); - log_bare(log_info,"raw_mode=%s ",raw_mode_tostring[raw_mode]); - log_bare(log_info,"cipher_mode=%s ",cipher_mode_tostring[cipher_mode]); - log_bare(log_info,"auth_mode=%s ",auth_mode_tostring[auth_mode]); + all_options.insert("--help"); + all_options.insert("-h"); + string dummy = ""; + for (i = 0; i < (int)strlen(options); i++) { + char val = options[i]; + if ((val >= '0' && val <= '9') || (val >= 'a' && val <= 'z') || (val >= 'A' && val <= 'Z')) { + all_options.insert(dummy + '-' + val); + } + } + for (i = 0; i < int(sizeof(long_options) / sizeof(long_options[0])); i++) { + if (long_options[i].name == NULL) break; + int val = long_options[i].val; + if ((val >= '0' && val <= '9') || (val >= 'a' && val <= 'z') || (val >= 'A' && val <= 'Z')) { + shortcut_map[dummy + "--" + long_options[i].name] = dummy + "-" + char(val); + } + all_options.insert(dummy + "--" + long_options[i].name); + } - log_bare(log_info,"key=%s ",key_string); + for (i = 0; i < argc; i++) { + int len = strlen(argv[i]); + if (len == 0) { + mylog(log_fatal, "found an empty string in options\n"); + myexit(-1); + } + if (len == 1 && argv[i][0] == '-') { + mylog(log_fatal, "invaild option '-' in argv\n"); + myexit(-1); + } + if (len == 2 && argv[i][0] == '-' && argv[i][1] == '-') { + mylog(log_fatal, "invaild option '--' in argv\n"); + myexit(-1); + } + } - log_bare(log_info,"local_addr=%s ",local_addr.get_str()); - log_bare(log_info,"remote_addr=%s ",remote_addr.get_str()); + mylog(log_info, "argc=%d ", argc); - if(force_source_ip) - log_bare(log_info,"source_addr=%s ",source_addr.get_ip()); + for (i = 0; i < argc; i++) { + log_bare(log_info, "%s ", argv[i]); + } + log_bare(log_info, "\n"); - if(force_source_port) - log_bare(log_info,"source_port=%d ",source_port); + // string dummy=""; + for (i = +1; i < argc; i++) { + if (argv[i][0] != '-') continue; + string a = argv[i]; + if (a[0] == '-' && a[1] != '-') + a = dummy + a[0] + a[1]; - log_bare(log_info,"socket_buf_size=%d ",socket_buf_size); + if (all_options.find(a.c_str()) == all_options.end()) { + mylog(log_fatal, "invaild option %s\n", a.c_str()); + myexit(-1); + } + for (j = i + 1; j < argc; j++) { + if (argv[j][0] != '-') continue; - log_bare(log_info,"\n"); + string b = argv[j]; + if (b[0] == '-' && b[1] != '-') + b = dummy + b[0] + b[1]; + + if (shortcut_map.find(a) != shortcut_map.end()) + a = shortcut_map[a]; + if (shortcut_map.find(b) != shortcut_map.end()) + b = shortcut_map[b]; + if (a == b) { + mylog(log_fatal, "%s duplicates with %s\n", argv[i], argv[j]); + myexit(-1); + } + } + } + + int no_l = 1, no_r = 1; + while ((opt = getopt_long(argc, argv, options, long_options, &option_index)) != -1) { + // string opt_key; + // opt_key+=opt; + switch (opt) { + case 'l': + no_l = 0; + local_addr.from_str(optarg); + if (local_addr.get_port() == 22) { + mylog(log_fatal, "port 22 not allowed\n"); + myexit(-1); + } + /* + if (strchr(optarg, ':') != 0) { + sscanf(optarg, "%[^:]:%d", local_ip, &local_port); + if(local_port==22) + { + mylog(log_fatal,"port 22 not allowed\n"); + myexit(-1); + } + } else { + mylog(log_fatal,"invalid parameter for -l ,%s,should be ip:port\n",optarg); + myexit(-1); + }*/ + break; + case 'r': + no_r = 0; + remote_addr.from_str(optarg); + if (remote_addr.get_port() == 22) { + mylog(log_fatal, "port 22 not allowed\n"); + myexit(-1); + } + /* + if (strchr(optarg, ':') != 0) { + sscanf(optarg, "%[^:]:%d", remote_address, &remote_port); + if(remote_port==22) + { + mylog(log_fatal,"port 22 not allowed\n"); + myexit(-1); + } + } else { + mylog(log_fatal,"invalid parameter for -r ,%s,should be ip:port\n",optarg); + myexit(-1); + }*/ + break; + case 's': + if (program_mode == 0) { + program_mode = server_mode; + } else { + mylog(log_fatal, "-s /-c has already been set,conflict\n"); + myexit(-1); + } + break; + case 'c': + if (program_mode == 0) { + program_mode = client_mode; + } else { + mylog(log_fatal, "-s /-c has already been set,conflict\n"); + myexit(-1); + } + break; + case 'h': + break; + case 'a': + if (is_udp2raw_mp) { + mylog(log_fatal, "-a not supported in this version, check -g or --raw-mode easyfaketcp\n"); + myexit(-1); + } + auto_add_iptables_rule = 1; + break; + case 'g': + generate_iptables_rule = 1; + break; + case 'k': + mylog(log_debug, "parsing key option\n"); + sscanf(optarg, "%s", key_string); + break; + case 1: + mylog(log_debug, "option_index: %d\n", option_index); + if (strcmp(long_options[option_index].name, "clear") == 0) { + if (is_udp2raw_mp) { + mylog(log_fatal, "--clear not supported in this version\n"); + myexit(-1); + } + + clear_iptables = 1; + } else if (strcmp(long_options[option_index].name, "source-ip") == 0) { + mylog(log_debug, "parsing long option :source-ip\n"); + // sscanf(optarg, "%s", source_ip); + source_addr.from_str_ip_only(optarg); + mylog(log_debug, "source: %s\n", source_addr.get_ip()); + force_source_ip = 1; + } else if (strcmp(long_options[option_index].name, "source-port") == 0) { + mylog(log_debug, "parsing long option :source-port\n"); + sscanf(optarg, "%d", &source_port); + mylog(log_info, "source: %d\n", source_port); + force_source_port = 1; + } else if (strcmp(long_options[option_index].name, "raw-mode") == 0) { + /* + for(i=0;i 10000) { + mylog(log_fatal, "random_drop must be between 0 10000 \n"); + myexit(-1); + } + mylog(log_info, "random_drop =%d \n", random_drop); + } else if (strcmp(long_options[option_index].name, "fifo") == 0) { + if (is_udp2raw_mp) { + mylog(log_fatal, "--fifo not supported in this version\n"); + myexit(-1); + } + sscanf(optarg, "%s", fifo_file); + + mylog(log_info, "fifo_file =%s \n", fifo_file); + } else if (strcmp(long_options[option_index].name, "conf-file") == 0) { + mylog(log_info, "configuration loaded from %s\n", optarg); + } else if (strcmp(long_options[option_index].name, "hb-mode") == 0) { + sscanf(optarg, "%d", &hb_mode); + assert(hb_mode == 0 || hb_mode == 1); + mylog(log_info, "hb_mode =%d \n", hb_mode); + } else if (strcmp(long_options[option_index].name, "hb-len") == 0) { + sscanf(optarg, "%d", &hb_len); + assert(hb_len >= 0 && hb_len <= 1500); + mylog(log_info, "hb_len =%d \n", hb_len); + } else if (strcmp(long_options[option_index].name, "mtu-warn") == 0) { + sscanf(optarg, "%d", &mtu_warn); + assert(mtu_warn > 0); + mylog(log_info, "mtu_warn=%d \n", mtu_warn); + } else if (strcmp(long_options[option_index].name, "max-rst-to-show") == 0) { + sscanf(optarg, "%d", &max_rst_to_show); + assert(max_rst_to_show >= -1); + mylog(log_info, "max_rst_to_show=%d \n", max_rst_to_show); + } else if (strcmp(long_options[option_index].name, "max-rst-allowed") == 0) { + sscanf(optarg, "%d", &max_rst_allowed); + assert(max_rst_allowed >= -1); + mylog(log_info, "max_rst_allowed=%d \n", max_rst_allowed); + } else if (strcmp(long_options[option_index].name, "set-ttl") == 0) { + sscanf(optarg, "%d", &ttl_value); + assert(ttl_value >= 0 && ttl_value <= 255); + mylog(log_info, "ttl_value=%d\n", ttl_value); + } + + else if (strcmp(long_options[option_index].name, "dns-resolve") == 0) // currently not used + { + enable_dns_resolve = 1; + mylog(log_info, "dns-resolve enabled\n"); + } +#ifdef UDP2RAW_MP + else if (strcmp(long_options[option_index].name, "pcap-send") == 0) { + send_with_pcap = 1; + mylog(log_info, "--pcap-send enabled, now pcap will be used for sending packet instead of libnet\n"); + } else if (strcmp(long_options[option_index].name, "no-pcap-mutex") == 0) { + use_pcap_mutex = 0; + mylog(log_warn, "--no-pcap-mutex enabled, we will assume the underlying pcap calls are threadsafe\n"); + } +#endif + else if (strcmp(long_options[option_index].name, "easy-tcp") == 0) { + use_tcp_dummy_socket = 1; + mylog(log_info, "--easy-tcp enabled, now a dummy tcp socket will be created for handshake and block rst\n"); + } else if (strcmp(long_options[option_index].name, "fix-gro") == 0) { + mylog(log_info, "--fix-gro enabled\n"); + g_fix_gro = 1; + } else { + mylog(log_warn, "ignored unknown long option ,option_index:%d code:<%x>\n", option_index, optopt); + } + break; + default: + mylog(log_fatal, "unknown option ,code:<%c>,<%x>\n", optopt, optopt); + myexit(-1); + } + } + + if (no_l) + mylog(log_fatal, "error: -l not found\n"); + if (no_r) + mylog(log_fatal, "error: -r not found\n"); + if (program_mode == 0) + mylog(log_fatal, "error: -c /-s hasnt been set\n"); + if (no_l || no_r || program_mode == 0) { + print_help(); + myexit(-1); + } + if (program_mode == client_mode) { + raw_ip_version = remote_addr.get_type(); + } else { + raw_ip_version = local_addr.get_type(); + } + + if (auto_add_iptables_rule && use_tcp_dummy_socket) { + mylog(log_error, "-a,--auto-rule is not supposed to be used with easyfaketcp mode, you are likely making a mistake, but we can try to continue\n"); + } + + if (keep_rule && use_tcp_dummy_socket) { + mylog(log_error, "--keep-rule is not supposed to be used with easyfaketcp mode, you are likely making a mistake, but we can try to continue\n"); + } + + mylog(log_info, "important variables: "); + + log_bare(log_info, "log_level=%d:%s ", log_level, log_text[log_level]); + log_bare(log_info, "raw_mode=%s ", raw_mode_tostring[raw_mode]); + log_bare(log_info, "cipher_mode=%s ", cipher_mode_tostring[cipher_mode]); + log_bare(log_info, "auth_mode=%s ", auth_mode_tostring[auth_mode]); + + log_bare(log_info, "key=%s ", key_string); + + log_bare(log_info, "local_addr=%s ", local_addr.get_str()); + log_bare(log_info, "remote_addr=%s ", remote_addr.get_str()); + + if (force_source_ip) + log_bare(log_info, "source_addr=%s ", source_addr.get_ip()); + + if (force_source_port) + log_bare(log_info, "source_port=%d ", source_port); + + log_bare(log_info, "socket_buf_size=%d ", socket_buf_size); + + log_bare(log_info, "\n"); } -void pre_process_arg(int argc, char *argv[])//mainly for load conf file +void pre_process_arg(int argc, char *argv[]) // mainly for load conf file { - int i,j,k; - for (i = 0; i < argc; i++) - { - if(strcmp(argv[i],"--unit-test")==0) - { - unit_test(); - myexit(0); - } + int i, j, k; + for (i = 0; i < argc; i++) { + if (strcmp(argv[i], "--unit-test") == 0) { + unit_test(); + myexit(0); + } + } - } + for (i = 0; i < argc; i++) { + if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) { + print_help(); + myexit(0); + } + } - for (i = 0; i < argc; i++) - { - if(strcmp(argv[i],"-h")==0||strcmp(argv[i],"--help")==0) - { - print_help(); - myexit(0); - } + if (argc == 1) { + print_help(); + myexit(-1); + } - } + process_log_level(argc, argv); - if (argc == 1) - { - print_help(); - myexit(-1); - } + int new_argc = 0; + vector new_argv; - process_log_level(argc,argv); + int count = 0; + int pos = -1; - int new_argc=0; - vector new_argv; + for (i = 0; i < argc; i++) { + if (strcmp(argv[i], "--conf-file") == 0) { + count++; + pos = i; + if (i == argc) { + mylog(log_fatal, "--conf-file need a parameter\n"); + myexit(-1); + } + if (argv[i + 1][0] == '-') { + mylog(log_fatal, "--conf-file need a parameter\n"); + myexit(-1); + } + i++; + } else { + // printf("<%s>",argv[i]); + new_argc++; + new_argv.push_back(argv[i]); + } + } + if (count > 1) { + mylog(log_fatal, "duplicated --conf-file option\n"); + myexit(-1); + } - int count=0; - int pos=-1; - - for (i = 0; i < argc; i++) - { - if(strcmp(argv[i],"--conf-file")==0) - { - count++; - pos=i; - if(i==argc) - { - mylog(log_fatal,"--conf-file need a parameter\n"); - myexit(-1); - } - if(argv[i+1][0]=='-') - { - mylog(log_fatal,"--conf-file need a parameter\n"); - myexit(-1); - } - i++; - } - else - { - //printf("<%s>",argv[i]); - new_argc++; - new_argv.push_back(argv[i]); - } - } - if(count>1) - { - mylog(log_fatal,"duplicated --conf-file option\n"); - myexit(-1); - } - - if(count>0) - { - load_config(argv[pos+1],new_argc,new_argv); - } - char* new_argv_char[new_argv.size()]; - - new_argc=0; - for(i=0;i<(int)new_argv.size();i++) - { - if(strcmp(new_argv[i].c_str(),"--conf-file")==0) - { - mylog(log_fatal,"cant have --conf-file in a config file\n"); - myexit(-1); - } - new_argv_char[new_argc++]=(char *)new_argv[i].c_str(); - } - process_arg(new_argc,new_argv_char); + if (count > 0) { + load_config(argv[pos + 1], new_argc, new_argv); + } + char *new_argv_char[new_argv.size()]; + new_argc = 0; + for (i = 0; i < (int)new_argv.size(); i++) { + if (strcmp(new_argv[i].c_str(), "--conf-file") == 0) { + mylog(log_fatal, "cant have --conf-file in a config file\n"); + myexit(-1); + } + new_argv_char[new_argc++] = (char *)new_argv[i].c_str(); + } + process_arg(new_argc, new_argv_char); } #ifdef UDP2RAW_LINUX -void *run_keep(void *none) //called in a new thread for --keep-rule option +void *run_keep(void *none) // called in a new thread for --keep-rule option { - - while(1) - { - sleep(iptables_rule_keep_interval); - keep_iptables_rule(); - if(about_to_exit) //just incase it runs forever if there is some bug,not necessary - { - sleep(10); - keep_thread_running=0; //not thread safe ,but wont cause problem - break; - } - } - return NULL; - + while (1) { + sleep(iptables_rule_keep_interval); + keep_iptables_rule(); + if (about_to_exit) // just incase it runs forever if there is some bug,not necessary + { + sleep(10); + keep_thread_running = 0; // not thread safe ,but wont cause problem + break; + } + } + return NULL; } void iptables_rule() // handles -a -g --gen-add --keep-rule --clear --wait-lock { - assert(raw_ip_version==AF_INET||raw_ip_version==AF_INET6); + assert(raw_ip_version == AF_INET || raw_ip_version == AF_INET6); - if(raw_ip_version==AF_INET) - { - iptables_command0="iptables "; - } - else - iptables_command0="ip6tables "; - if(!wait_xtables_lock) - { - iptables_command=iptables_command0; - } - else - { - iptables_command=iptables_command0+"-w "; - } + if (raw_ip_version == AF_INET) { + iptables_command0 = "iptables "; + } else + iptables_command0 = "ip6tables "; + if (!wait_xtables_lock) { + iptables_command = iptables_command0; + } else { + iptables_command = iptables_command0 + "-w "; + } - if(clear_iptables) - { - char *output; - //int ret =system("iptables-save |grep udp2raw_dWRwMnJhdw|sed -n 's/^-A/iptables -D/p'|sh"); - int ret =run_command(iptables_command+"-S|sed -n '/udp2rawDwrW/p'|sed -n 's/^-A/"+iptables_command+"-D/p'|sh",output); + if (clear_iptables) { + char *output; + // int ret =system("iptables-save |grep udp2raw_dWRwMnJhdw|sed -n 's/^-A/iptables -D/p'|sh"); + int ret = run_command(iptables_command + "-S|sed -n '/udp2rawDwrW/p'|sed -n 's/^-A/" + iptables_command + "-D/p'|sh", output); - int ret2 =run_command(iptables_command+"-S|sed -n '/udp2rawDwrW/p'|sed -n 's/^-N/"+iptables_command+"-X/p'|sh",output); - //system("iptables-save |grep udp2raw_dWRwMnJhdw|sed 's/^-A/iptables -D/'|sh"); - //system("iptables-save|grep -v udp2raw_dWRwMnJhdw|iptables-restore"); - mylog(log_info,"tried to clear all iptables rule created previously,return value %d %d\n",ret,ret2); - myexit(-1); - } + int ret2 = run_command(iptables_command + "-S|sed -n '/udp2rawDwrW/p'|sed -n 's/^-N/" + iptables_command + "-X/p'|sh", output); + // system("iptables-save |grep udp2raw_dWRwMnJhdw|sed 's/^-A/iptables -D/'|sh"); + // system("iptables-save|grep -v udp2raw_dWRwMnJhdw|iptables-restore"); + mylog(log_info, "tried to clear all iptables rule created previously,return value %d %d\n", ret, ret2); + myexit(-1); + } - if(auto_add_iptables_rule&&generate_iptables_rule) - { - mylog(log_warn," -g overrides -a\n"); - auto_add_iptables_rule=0; - //myexit(-1); - } - if(generate_iptables_rule_add&&generate_iptables_rule) - { - mylog(log_warn," --gen-add overrides -g\n"); - generate_iptables_rule=0; - //myexit(-1); - } + if (auto_add_iptables_rule && generate_iptables_rule) { + mylog(log_warn, " -g overrides -a\n"); + auto_add_iptables_rule = 0; + // myexit(-1); + } + if (generate_iptables_rule_add && generate_iptables_rule) { + mylog(log_warn, " --gen-add overrides -g\n"); + generate_iptables_rule = 0; + // myexit(-1); + } - if(keep_rule&&auto_add_iptables_rule==0) - { - auto_add_iptables_rule=1; - mylog(log_warn," --keep_rule implys -a\n"); - generate_iptables_rule=0; - //myexit(-1); - } - char tmp_pattern[200]; - string pattern=""; + if (keep_rule && auto_add_iptables_rule == 0) { + auto_add_iptables_rule = 1; + mylog(log_warn, " --keep_rule implys -a\n"); + generate_iptables_rule = 0; + // myexit(-1); + } + char tmp_pattern[200]; + string pattern = ""; - if(program_mode==client_mode) - { - tmp_pattern[0]=0; - if(raw_mode==mode_faketcp) - { - sprintf(tmp_pattern,"-s %s -p tcp -m tcp --sport %d",remote_addr.get_ip(),remote_addr.get_port()); - } - if(raw_mode==mode_udp) - { - sprintf(tmp_pattern,"-s %s -p udp -m udp --sport %d",remote_addr.get_ip(),remote_addr.get_port()); - } - if(raw_mode==mode_icmp) - { - if(raw_ip_version==AF_INET) - sprintf(tmp_pattern,"-s %s -p icmp --icmp-type 0",remote_addr.get_ip()); - else - sprintf(tmp_pattern,"-s %s -p icmpv6 --icmpv6-type 129",remote_addr.get_ip()); - } - pattern+=tmp_pattern; - } - if(program_mode==server_mode) - { - tmp_pattern[0]=0; - if(raw_ip_version==AF_INET) - { - if(local_addr.inner.ipv4.sin_addr.s_addr!=0) - { - sprintf(tmp_pattern,"-d %s ",local_addr.get_ip()); - } - } - else - { - char zero_arr[16]={0}; - if(memcmp(&local_addr.inner.ipv6.sin6_addr,zero_arr,16)!=0) - { - sprintf(tmp_pattern,"-d %s ",local_addr.get_ip()); - } - } - pattern+=tmp_pattern; + if (program_mode == client_mode) { + tmp_pattern[0] = 0; + if (raw_mode == mode_faketcp) { + sprintf(tmp_pattern, "-s %s -p tcp -m tcp --sport %d", remote_addr.get_ip(), remote_addr.get_port()); + } + if (raw_mode == mode_udp) { + sprintf(tmp_pattern, "-s %s -p udp -m udp --sport %d", remote_addr.get_ip(), remote_addr.get_port()); + } + if (raw_mode == mode_icmp) { + if (raw_ip_version == AF_INET) + sprintf(tmp_pattern, "-s %s -p icmp --icmp-type 0", remote_addr.get_ip()); + else + sprintf(tmp_pattern, "-s %s -p icmpv6 --icmpv6-type 129", remote_addr.get_ip()); + } + pattern += tmp_pattern; + } + if (program_mode == server_mode) { + tmp_pattern[0] = 0; + if (raw_ip_version == AF_INET) { + if (local_addr.inner.ipv4.sin_addr.s_addr != 0) { + sprintf(tmp_pattern, "-d %s ", local_addr.get_ip()); + } + } else { + char zero_arr[16] = {0}; + if (memcmp(&local_addr.inner.ipv6.sin6_addr, zero_arr, 16) != 0) { + sprintf(tmp_pattern, "-d %s ", local_addr.get_ip()); + } + } + pattern += tmp_pattern; - tmp_pattern[0]=0; - if(raw_mode==mode_faketcp) - { - sprintf(tmp_pattern,"-p tcp -m tcp --dport %d",local_addr.get_port()); - } - if(raw_mode==mode_udp) - { - sprintf(tmp_pattern,"-p udp -m udp --dport %d",local_addr.get_port()); - } - if(raw_mode==mode_icmp) - { - if(raw_ip_version==AF_INET) - sprintf(tmp_pattern,"-p icmp --icmp-type 8"); - else - sprintf(tmp_pattern,"-p icmpv6 --icmpv6-type 128"); - } - pattern+=tmp_pattern; - } -/* - if(!simple_rule) - { - pattern += " -m comment --comment udp2rawDwrW_"; + tmp_pattern[0] = 0; + if (raw_mode == mode_faketcp) { + sprintf(tmp_pattern, "-p tcp -m tcp --dport %d", local_addr.get_port()); + } + if (raw_mode == mode_udp) { + sprintf(tmp_pattern, "-p udp -m udp --dport %d", local_addr.get_port()); + } + if (raw_mode == mode_icmp) { + if (raw_ip_version == AF_INET) + sprintf(tmp_pattern, "-p icmp --icmp-type 8"); + else + sprintf(tmp_pattern, "-p icmpv6 --icmpv6-type 128"); + } + pattern += tmp_pattern; + } + /* + if(!simple_rule) + { + pattern += " -m comment --comment udp2rawDwrW_"; - char const_id_str[100]; - sprintf(const_id_str, "%x_", const_id); + char const_id_str[100]; + sprintf(const_id_str, "%x_", const_id); - pattern += const_id_str; + pattern += const_id_str; - time_t timer; - char buffer[26]; - struct tm* tm_info; + time_t timer; + char buffer[26]; + struct tm* tm_info; - time(&timer); - tm_info = localtime(&timer); + time(&timer); + tm_info = localtime(&timer); - strftime(buffer, 26, "%Y-%m-%d-%H:%M:%S", tm_info); + strftime(buffer, 26, "%Y-%m-%d-%H:%M:%S", tm_info); - pattern += buffer; + pattern += buffer; - }*/ + }*/ - if(generate_iptables_rule) - { - string rule=iptables_command+"-I INPUT "; - rule+=pattern; - rule+=" -j DROP"; + if (generate_iptables_rule) { + string rule = iptables_command + "-I INPUT "; + rule += pattern; + rule += " -j DROP"; - printf("generated iptables rule:\n"); - printf("%s\n",rule.c_str()); - myexit(0); - } - if(generate_iptables_rule_add) - { - iptables_gen_add(pattern.c_str(),const_id); - myexit(0); - } + printf("generated iptables rule:\n"); + printf("%s\n", rule.c_str()); + myexit(0); + } + if (generate_iptables_rule_add) { + iptables_gen_add(pattern.c_str(), const_id); + myexit(0); + } - if(auto_add_iptables_rule) - { - iptables_rule_init(pattern.c_str(),const_id,keep_rule); - if(keep_rule) - { - if(pthread_create(&keep_thread, NULL, run_keep, 0)) { - - mylog(log_fatal, "Error creating thread\n"); - myexit(-1); - } - keep_thread_running=1; - } - } - else - { - mylog(log_warn," -a has not been set, make sure you have added the needed iptables rules manually\n"); - } + if (auto_add_iptables_rule) { + iptables_rule_init(pattern.c_str(), const_id, keep_rule); + if (keep_rule) { + if (pthread_create(&keep_thread, NULL, run_keep, 0)) { + mylog(log_fatal, "Error creating thread\n"); + myexit(-1); + } + keep_thread_running = 1; + } + } else { + mylog(log_warn, " -a has not been set, make sure you have added the needed iptables rules manually\n"); + } } #endif -int unit_test() -{ - printf("running unit test\n"); - vector conf_lines= {"---aaa","--aaa bbb","-a bbb"," \t \t \t-a\t \t \t bbbbb\t \t \t "}; - for(int i=0;i",res[j].c_str()); - } - printf("\n"); - } +int unit_test() { + printf("running unit test\n"); + vector conf_lines = {"---aaa", "--aaa bbb", "-a bbb", " \t \t \t-a\t \t \t bbbbb\t \t \t "}; + for (int i = 0; i < int(conf_lines.size()); i++) { + printf("orign:%s\n", conf_lines[i].c_str()); + auto res = parse_conf_line(conf_lines[i]); + printf("pasrse_result: size %d", int(res.size())); + for (int j = 0; j < int(res.size()); j++) { + printf("<%s>", res[j].c_str()); + } + printf("\n"); + } - char s1[]={1,2,3,4,5}; + char s1[] = {1, 2, 3, 4, 5}; - char s2[]={1}; + char s2[] = {1}; - short c1=csum((unsigned short*)s1,5); - short c2=csum((unsigned short*)s2,1); - //c2=0; + short c1 = csum((unsigned short *)s1, 5); + short c2 = csum((unsigned short *)s2, 1); + // c2=0; - printf("%x %x\n",(int)c1,(int)c2); + printf("%x %x\n", (int)c1, (int)c2); - const char buf[]={1,2,3,4,5,6,7,8,9,10,11,2,13,14,15,16}; - char key[100]={0}; - char buf2[100]={0}; - char buf3[100]={0}; - char buf4[100]={0}; - int len=16; - for(int i=0;i",buf[i]); - } - printf("\n"); - cipher_encrypt(buf,buf2,len,key); - for(int i=0;i",buf2[i]); - } - printf("\n"); - int temp_len=len; - cipher_decrypt(buf2,buf3,len,key); - for(int i=0;i",buf3[i]); - } - printf("\n"); - cipher_encrypt(buf2,buf4,temp_len,key); - for(int i=0;i",buf4[i]); - } - return 0; + const char buf[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 2, 13, 14, 15, 16}; + char key[100] = {0}; + char buf2[100] = {0}; + char buf3[100] = {0}; + char buf4[100] = {0}; + int len = 16; + for (int i = 0; i < len; i++) { + printf("<%d>", buf[i]); + } + printf("\n"); + cipher_encrypt(buf, buf2, len, key); + for (int i = 0; i < len; i++) { + printf("<%d>", buf2[i]); + } + printf("\n"); + int temp_len = len; + cipher_decrypt(buf2, buf3, len, key); + for (int i = 0; i < len; i++) { + printf("<%d>", buf3[i]); + } + printf("\n"); + cipher_encrypt(buf2, buf4, temp_len, key); + for (int i = 0; i < temp_len; i++) { + printf("<%d>", buf4[i]); + } + return 0; } #ifdef UDP2RAW_LINUX -int set_timer(int epollfd,int &timer_fd)//put a timer_fd into epoll,general function,used both in client and server +int set_timer(int epollfd, int &timer_fd) // put a timer_fd into epoll,general function,used both in client and server { - int ret; - epoll_event ev; + int ret; + epoll_event ev; - itimerspec its; - memset(&its,0,sizeof(its)); + itimerspec its; + memset(&its, 0, sizeof(its)); - if((timer_fd=timerfd_create(CLOCK_MONOTONIC,TFD_NONBLOCK)) < 0) - { - mylog(log_fatal,"timer_fd create error\n"); - myexit(1); - } - its.it_interval.tv_sec=(timer_interval/1000); - its.it_interval.tv_nsec=(timer_interval%1000)*1000ll*1000ll; - its.it_value.tv_nsec=1; //imidiately - timerfd_settime(timer_fd,0,&its,0); + if ((timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK)) < 0) { + mylog(log_fatal, "timer_fd create error\n"); + myexit(1); + } + its.it_interval.tv_sec = (timer_interval / 1000); + its.it_interval.tv_nsec = (timer_interval % 1000) * 1000ll * 1000ll; + its.it_value.tv_nsec = 1; // imidiately + timerfd_settime(timer_fd, 0, &its, 0); + ev.events = EPOLLIN; + ev.data.u64 = timer_fd; - ev.events = EPOLLIN; - ev.data.u64 = timer_fd; - - ret=epoll_ctl(epollfd, EPOLL_CTL_ADD, timer_fd, &ev); - if (ret < 0) { - mylog(log_fatal,"epoll_ctl return %d\n", ret); - myexit(-1); - } - return 0; + ret = epoll_ctl(epollfd, EPOLL_CTL_ADD, timer_fd, &ev); + if (ret < 0) { + mylog(log_fatal, "epoll_ctl return %d\n", ret); + myexit(-1); + } + return 0; } - -int set_timer_server(int epollfd,int &timer_fd,fd64_t &fd64)//only for server +int set_timer_server(int epollfd, int &timer_fd, fd64_t &fd64) // only for server { - int ret; - epoll_event ev; + int ret; + epoll_event ev; - itimerspec its; - memset(&its,0,sizeof(its)); + itimerspec its; + memset(&its, 0, sizeof(its)); - if((timer_fd=timerfd_create(CLOCK_MONOTONIC,TFD_NONBLOCK)) < 0) - { - mylog(log_fatal,"timer_fd create error\n"); - myexit(1); - } - its.it_interval.tv_sec=(timer_interval/1000); - its.it_interval.tv_nsec=(timer_interval%1000)*1000ll*1000ll; - its.it_value.tv_nsec=1; //imidiately - timerfd_settime(timer_fd,0,&its,0); + if ((timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK)) < 0) { + mylog(log_fatal, "timer_fd create error\n"); + myexit(1); + } + its.it_interval.tv_sec = (timer_interval / 1000); + its.it_interval.tv_nsec = (timer_interval % 1000) * 1000ll * 1000ll; + its.it_value.tv_nsec = 1; // imidiately + timerfd_settime(timer_fd, 0, &its, 0); - fd64=fd_manager.create(timer_fd); + fd64 = fd_manager.create(timer_fd); + ev.events = EPOLLIN; + ev.data.u64 = fd64; ////difference - ev.events = EPOLLIN; - ev.data.u64 = fd64;////difference - - ret=epoll_ctl(epollfd, EPOLL_CTL_ADD, timer_fd, &ev); - if (ret < 0) { - mylog(log_fatal,"epoll_ctl return %d\n", ret); - myexit(-1); - } - return 0; + ret = epoll_ctl(epollfd, EPOLL_CTL_ADD, timer_fd, &ev); + if (ret < 0) { + mylog(log_fatal, "epoll_ctl return %d\n", ret); + myexit(-1); + } + return 0; } -int handle_lower_level(raw_info_t &raw_info)//fill lower_level info,when --lower-level is enabled,only for server +int handle_lower_level(raw_info_t &raw_info) // fill lower_level info,when --lower-level is enabled,only for server { - packet_info_t &send_info=raw_info.send_info; - packet_info_t &recv_info=raw_info.recv_info; + packet_info_t &send_info = raw_info.send_info; + packet_info_t &recv_info = raw_info.recv_info; - if(lower_level_manual) - { - memset(&send_info.addr_ll,0,sizeof(send_info.addr_ll)); - send_info.addr_ll.sll_family=AF_PACKET; - send_info.addr_ll.sll_ifindex=ifindex; - send_info.addr_ll.sll_halen=ETHER_ADDR_LEN; - send_info.addr_ll.sll_protocol=htons(ETH_P_IP); - memcpy(&send_info.addr_ll.sll_addr,dest_hw_addr,ETHER_ADDR_LEN); - mylog(log_debug,"[manual]lower level info %x %x\n ",send_info.addr_ll.sll_halen,send_info.addr_ll.sll_protocol); - } - else - { - memset(&send_info.addr_ll,0,sizeof(send_info.addr_ll)); - send_info.addr_ll.sll_family=recv_info.addr_ll.sll_family; - send_info.addr_ll.sll_ifindex=recv_info.addr_ll.sll_ifindex; - send_info.addr_ll.sll_protocol=recv_info.addr_ll.sll_protocol; - send_info.addr_ll.sll_halen=recv_info.addr_ll.sll_halen; - memcpy(send_info.addr_ll.sll_addr,recv_info.addr_ll.sll_addr,sizeof(send_info.addr_ll.sll_addr)); - //other bytes should be kept zero. + if (lower_level_manual) { + memset(&send_info.addr_ll, 0, sizeof(send_info.addr_ll)); + send_info.addr_ll.sll_family = AF_PACKET; + send_info.addr_ll.sll_ifindex = ifindex; + send_info.addr_ll.sll_halen = ETHER_ADDR_LEN; + send_info.addr_ll.sll_protocol = htons(ETH_P_IP); + memcpy(&send_info.addr_ll.sll_addr, dest_hw_addr, ETHER_ADDR_LEN); + mylog(log_debug, "[manual]lower level info %x %x\n ", send_info.addr_ll.sll_halen, send_info.addr_ll.sll_protocol); + } else { + memset(&send_info.addr_ll, 0, sizeof(send_info.addr_ll)); + send_info.addr_ll.sll_family = recv_info.addr_ll.sll_family; + send_info.addr_ll.sll_ifindex = recv_info.addr_ll.sll_ifindex; + send_info.addr_ll.sll_protocol = recv_info.addr_ll.sll_protocol; + send_info.addr_ll.sll_halen = recv_info.addr_ll.sll_halen; + memcpy(send_info.addr_ll.sll_addr, recv_info.addr_ll.sll_addr, sizeof(send_info.addr_ll.sll_addr)); + // other bytes should be kept zero. - mylog(log_debug,"[auto]lower level info %x %x\n ",send_info.addr_ll.sll_halen,send_info.addr_ll.sll_protocol); - } - return 0; + mylog(log_debug, "[auto]lower level info %x %x\n ", send_info.addr_ll.sll_halen, send_info.addr_ll.sll_protocol); + } + return 0; } - string chain[2]; string rule_keep[2]; string rule_keep_add[2]; string rule_keep_del[2]; -u64_t keep_rule_last_time=0; +u64_t keep_rule_last_time = 0; pthread_t keep_thread; -int keep_thread_running=0; -int iptables_gen_add(const char * s,u32_t const_id) -{ - string dummy=""; - iptables_pattern=s; - chain[0] =dummy+ "udp2rawDwrW_C"; - rule_keep[0]=dummy+ iptables_pattern+" -j " +chain[0]; - rule_keep_add[0]=iptables_command+"-I INPUT "+rule_keep[0]; +int keep_thread_running = 0; +int iptables_gen_add(const char *s, u32_t const_id) { + string dummy = ""; + iptables_pattern = s; + chain[0] = dummy + "udp2rawDwrW_C"; + rule_keep[0] = dummy + iptables_pattern + " -j " + chain[0]; + rule_keep_add[0] = iptables_command + "-I INPUT " + rule_keep[0]; - char *output; - run_command(iptables_command+"-N "+chain[0],output,show_none); - run_command(iptables_command+"-F "+chain[0],output); - run_command(iptables_command+"-I "+chain[0] + " -j DROP",output); + char *output; + run_command(iptables_command + "-N " + chain[0], output, show_none); + run_command(iptables_command + "-F " + chain[0], output); + run_command(iptables_command + "-I " + chain[0] + " -j DROP", output); - rule_keep_del[0]=iptables_command+"-D INPUT "+rule_keep[0]; + rule_keep_del[0] = iptables_command + "-D INPUT " + rule_keep[0]; - run_command(rule_keep_del[0],output,show_none); - run_command(rule_keep_del[0],output,show_none); + run_command(rule_keep_del[0], output, show_none); + run_command(rule_keep_del[0], output, show_none); - if(run_command(rule_keep_add[0],output)!=0) - { - mylog(log_fatal,"auto added iptables failed by: %s\n",rule_keep_add[0].c_str()); - myexit(-1); - } - return 0; + if (run_command(rule_keep_add[0], output) != 0) { + mylog(log_fatal, "auto added iptables failed by: %s\n", rule_keep_add[0].c_str()); + myexit(-1); + } + return 0; } -int iptables_rule_init(const char * s,u32_t const_id,int keep) -{ - iptables_pattern=s; - iptables_rule_added=1; - iptables_rule_keeped=keep; +int iptables_rule_init(const char *s, u32_t const_id, int keep) { + iptables_pattern = s; + iptables_rule_added = 1; + iptables_rule_keeped = keep; - string dummy=""; - char const_id_str[100]; - sprintf(const_id_str, "%x", const_id); + string dummy = ""; + char const_id_str[100]; + sprintf(const_id_str, "%x", const_id); - chain[0] =dummy+ "udp2rawDwrW_"+const_id_str+"_C0"; - chain[1] =dummy+ "udp2rawDwrW_"+const_id_str+"_C1"; + chain[0] = dummy + "udp2rawDwrW_" + const_id_str + "_C0"; + chain[1] = dummy + "udp2rawDwrW_" + const_id_str + "_C1"; - rule_keep[0]=dummy+ iptables_pattern+" -j " +chain[0]; - rule_keep[1]=dummy+ iptables_pattern+" -j " +chain[1]; + rule_keep[0] = dummy + iptables_pattern + " -j " + chain[0]; + rule_keep[1] = dummy + iptables_pattern + " -j " + chain[1]; - rule_keep_add[0]=iptables_command+"-I INPUT "+rule_keep[0]; - rule_keep_add[1]=iptables_command+"-I INPUT "+rule_keep[1]; + rule_keep_add[0] = iptables_command + "-I INPUT " + rule_keep[0]; + rule_keep_add[1] = iptables_command + "-I INPUT " + rule_keep[1]; - rule_keep_del[0]=iptables_command+"-D INPUT "+rule_keep[0]; - rule_keep_del[1]=iptables_command+"-D INPUT "+rule_keep[1]; + rule_keep_del[0] = iptables_command + "-D INPUT " + rule_keep[0]; + rule_keep_del[1] = iptables_command + "-D INPUT " + rule_keep[1]; - keep_rule_last_time=get_current_time(); + keep_rule_last_time = get_current_time(); - char *output; + char *output; - for(int i=0;i<=iptables_rule_keeped;i++) - { - run_command(iptables_command+"-N "+chain[i],output); - run_command(iptables_command+"-F "+chain[i],output); - run_command(iptables_command+"-I "+chain[i] + " -j DROP",output); + for (int i = 0; i <= iptables_rule_keeped; i++) { + run_command(iptables_command + "-N " + chain[i], output); + run_command(iptables_command + "-F " + chain[i], output); + run_command(iptables_command + "-I " + chain[i] + " -j DROP", output); - if(run_command(rule_keep_add[i],output)!=0) - { - mylog(log_fatal,"auto added iptables failed by: %s\n",rule_keep_add[i].c_str()); - myexit(-1); - } - } - mylog(log_warn,"auto added iptables rules\n"); - return 0; + if (run_command(rule_keep_add[i], output) != 0) { + mylog(log_fatal, "auto added iptables failed by: %s\n", rule_keep_add[i].c_str()); + myexit(-1); + } + } + mylog(log_warn, "auto added iptables rules\n"); + return 0; } -int keep_iptables_rule() //magic to work on a machine without grep/iptables --check/-m commment +int keep_iptables_rule() // magic to work on a machine without grep/iptables --check/-m commment { - /* - if(iptables_rule_keeped==0) return 0; + /* + if(iptables_rule_keeped==0) return 0; - uint64_t tmp_current_time=get_current_time(); - if(tmp_current_time-keep_rule_last_time<=iptables_rule_keep_interval) - { - return 0; - } - else - { - keep_rule_last_time=tmp_current_time; - }*/ + uint64_t tmp_current_time=get_current_time(); + if(tmp_current_time-keep_rule_last_time<=iptables_rule_keep_interval) + { + return 0; + } + else + { + keep_rule_last_time=tmp_current_time; + }*/ - mylog(log_debug,"keep_iptables_rule begin %llu\n",get_current_time()); - iptables_rule_keep_index+=1; - iptables_rule_keep_index%=2; + mylog(log_debug, "keep_iptables_rule begin %llu\n", get_current_time()); + iptables_rule_keep_index += 1; + iptables_rule_keep_index %= 2; - string dummy=""; - char *output; + string dummy = ""; + char *output; - int i=iptables_rule_keep_index; + int i = iptables_rule_keep_index; - run_command(iptables_command + "-N " + chain[i], output,show_none); + run_command(iptables_command + "-N " + chain[i], output, show_none); - if (run_command(iptables_command + "-F " + chain[i], output,show_none) != 0) - mylog(log_warn, "iptables -F failed %d\n",i); + if (run_command(iptables_command + "-F " + chain[i], output, show_none) != 0) + mylog(log_warn, "iptables -F failed %d\n", i); - if (run_command(iptables_command + "-I " + chain[i] + " -j DROP",output,show_none) != 0) - mylog(log_warn, "iptables -I failed %d\n",i); + if (run_command(iptables_command + "-I " + chain[i] + " -j DROP", output, show_none) != 0) + mylog(log_warn, "iptables -I failed %d\n", i); - if (run_command(rule_keep_del[i], output,show_none) != 0) - mylog(log_warn, "rule_keep_del failed %d\n",i); + if (run_command(rule_keep_del[i], output, show_none) != 0) + mylog(log_warn, "rule_keep_del failed %d\n", i); - run_command(rule_keep_del[i], output,show_none); //do it twice,incase it fails for unknown random reason + run_command(rule_keep_del[i], output, show_none); // do it twice,incase it fails for unknown random reason - if(run_command(rule_keep_add[i], output,show_log)!=0) - mylog(log_warn, "rule_keep_del failed %d\n",i); + if (run_command(rule_keep_add[i], output, show_log) != 0) + mylog(log_warn, "rule_keep_del failed %d\n", i); - mylog(log_debug,"keep_iptables_rule end %llu\n",get_current_time()); - return 0; + mylog(log_debug, "keep_iptables_rule end %llu\n", get_current_time()); + return 0; } -int clear_iptables_rule() -{ - char *output; - string dummy=""; - if(!iptables_rule_added) return 0; +int clear_iptables_rule() { + char *output; + string dummy = ""; + if (!iptables_rule_added) return 0; - for(int i=0;i<=iptables_rule_keeped;i++ ) - { - run_command(rule_keep_del[i],output); - run_command(iptables_command+"-F "+chain[i],output); - run_command(iptables_command+"-X "+chain[i],output); - } - return 0; + for (int i = 0; i <= iptables_rule_keeped; i++) { + run_command(rule_keep_del[i], output); + run_command(iptables_command + "-F " + chain[i], output); + run_command(iptables_command + "-X " + chain[i], output); + } + return 0; } #endif #ifdef UDP2RAW_MP void iptables_rule() // handles -a -g --gen-add --keep-rule --clear --wait-lock { + if (generate_iptables_rule) { + if (raw_mode == mode_faketcp && use_tcp_dummy_socket == 1) { + mylog(log_fatal, "failed,-g doesnt work with easy-faketcp mode\n"); + myexit(-1); + } + if (raw_mode == mode_udp) { + mylog(log_warn, "It not necessary to use iptables/firewall rule in udp mode\n"); + } + log_bare(log_warn, "for linux, use:\n"); + if (raw_ip_version == AF_INET) { + if (raw_mode == mode_faketcp) + printf("iptables -I INPUT -s %s -p tcp -m tcp --sport %d -j DROP\n", remote_addr.get_ip(), remote_addr.get_port()); + if (raw_mode == mode_udp) + printf("iptables -I INPUT -s %s -p udp -m udp --sport %d -j DROP\n", remote_addr.get_ip(), remote_addr.get_port()); + if (raw_mode == mode_icmp) + printf("iptables -I INPUT -s %s -p icmp --icmp-type 0 -j DROP\n", remote_addr.get_ip()); + printf("\n"); + } else { + assert(raw_ip_version == AF_INET6); + if (raw_mode == mode_faketcp) + printf("ip6tables -I INPUT -s %s -p tcp -m tcp --sport %d -j DROP\n", remote_addr.get_ip(), remote_addr.get_port()); + if (raw_mode == mode_udp) + printf("ip6tables -I INPUT -s %s -p udp -m udp --sport %d -j DROP\n", remote_addr.get_ip(), remote_addr.get_port()); + if (raw_mode == mode_icmp) + printf("ip6tables -I INPUT -s %s -p -p icmpv6 --icmpv6-type 129 -j DROP\n", remote_addr.get_ip()); + printf("\n"); + } - if(generate_iptables_rule) - { - if(raw_mode==mode_faketcp && use_tcp_dummy_socket==1) - { - mylog(log_fatal, "failed,-g doesnt work with easy-faketcp mode\n"); - myexit(-1); - } - if(raw_mode==mode_udp) - { - mylog(log_warn, "It not necessary to use iptables/firewall rule in udp mode\n"); - } - log_bare(log_warn,"for linux, use:\n"); - if(raw_ip_version==AF_INET) - { - if(raw_mode==mode_faketcp) - printf("iptables -I INPUT -s %s -p tcp -m tcp --sport %d -j DROP\n",remote_addr.get_ip(),remote_addr.get_port()); - if(raw_mode==mode_udp) - printf("iptables -I INPUT -s %s -p udp -m udp --sport %d -j DROP\n",remote_addr.get_ip(),remote_addr.get_port()); - if(raw_mode==mode_icmp) - printf("iptables -I INPUT -s %s -p icmp --icmp-type 0 -j DROP\n",remote_addr.get_ip()); - printf("\n"); - } - else - { - assert(raw_ip_version==AF_INET6); - if(raw_mode==mode_faketcp) - printf("ip6tables -I INPUT -s %s -p tcp -m tcp --sport %d -j DROP\n",remote_addr.get_ip(),remote_addr.get_port()); - if(raw_mode==mode_udp) - printf("ip6tables -I INPUT -s %s -p udp -m udp --sport %d -j DROP\n",remote_addr.get_ip(),remote_addr.get_port()); - if(raw_mode==mode_icmp) - printf("ip6tables -I INPUT -s %s -p -p icmpv6 --icmpv6-type 129 -j DROP\n",remote_addr.get_ip()); - printf("\n"); - } + log_bare(log_warn, "for mac/bsd use:\n"); + if (raw_ip_version == AF_INET) { + if (raw_mode == mode_faketcp) + printf("echo 'block drop inet proto tcp from %s port %d to any' > ./1.conf\n", remote_addr.get_ip(), remote_addr.get_port()); + if (raw_mode == mode_udp) + printf("echo 'block drop inet proto udp from %s port %d to any' > ./1.conf\n", remote_addr.get_ip(), remote_addr.get_port()); + if (raw_mode == mode_icmp) + printf("echo 'block drop inet proto icmp from %s to any' > ./1.conf\n", remote_addr.get_ip()); + } else { + assert(raw_ip_version == AF_INET6); + if (raw_mode == mode_faketcp) + printf("echo 'block drop inet6 proto tcp from %s port %d to any' > ./1.conf\n", remote_addr.get_ip(), remote_addr.get_port()); + if (raw_mode == mode_udp) + printf("echo 'block drop inet6 proto udp from %s port %d to any' > ./1.conf\n", remote_addr.get_ip(), remote_addr.get_port()); + if (raw_mode == mode_icmp) + printf("echo 'block drop inet6 proto icmp6 from %s to any' > ./1.conf\n", remote_addr.get_ip()); + } + printf("pfctl -f ./1.conf\n"); + printf("pfctl -e\n"); + printf("\n"); - log_bare(log_warn,"for mac/bsd use:\n"); - if(raw_ip_version==AF_INET) - { - if(raw_mode==mode_faketcp) - printf("echo 'block drop inet proto tcp from %s port %d to any' > ./1.conf\n",remote_addr.get_ip(),remote_addr.get_port()); - if(raw_mode==mode_udp) - printf("echo 'block drop inet proto udp from %s port %d to any' > ./1.conf\n",remote_addr.get_ip(),remote_addr.get_port()); - if(raw_mode==mode_icmp) - printf("echo 'block drop inet proto icmp from %s to any' > ./1.conf\n",remote_addr.get_ip()); - } - else - { - assert(raw_ip_version==AF_INET6); - if(raw_mode==mode_faketcp) - printf("echo 'block drop inet6 proto tcp from %s port %d to any' > ./1.conf\n",remote_addr.get_ip(),remote_addr.get_port()); - if(raw_mode==mode_udp) - printf("echo 'block drop inet6 proto udp from %s port %d to any' > ./1.conf\n",remote_addr.get_ip(),remote_addr.get_port()); - if(raw_mode==mode_icmp) - printf("echo 'block drop inet6 proto icmp6 from %s to any' > ./1.conf\n",remote_addr.get_ip()); - } - printf("pfctl -f ./1.conf\n"); - printf("pfctl -e\n"); - printf("\n"); + log_bare(log_warn, "for windows vista and above use:\n"); + if (raw_ip_version == AF_INET) { + if (raw_mode == mode_faketcp) { + printf("netsh advfirewall firewall add rule name=udp2raw protocol=TCP dir=in remoteip=%s remoteport=%d action=block\n", remote_addr.get_ip(), remote_addr.get_port()); + printf("netsh advfirewall firewall add rule name=udp2raw protocol=TCP dir=out remoteip=%s remoteport=%d action=block\n", remote_addr.get_ip(), remote_addr.get_port()); + } + if (raw_mode == mode_udp) { + printf("netsh advfirewall firewall add rule name=udp2raw protocol=UDP dir=in remoteip=%s remoteport=%d action=block\n", remote_addr.get_ip(), remote_addr.get_port()); + printf("netsh advfirewall firewall add rule name=udp2raw protocol=UDP dir=out remoteip=%s remoteport=%d action=block\n", remote_addr.get_ip(), remote_addr.get_port()); + } - log_bare(log_warn,"for windows vista and above use:\n"); - if(raw_ip_version==AF_INET) - { - if(raw_mode==mode_faketcp) - { - printf("netsh advfirewall firewall add rule name=udp2raw protocol=TCP dir=in remoteip=%s remoteport=%d action=block\n",remote_addr.get_ip(),remote_addr.get_port()); - printf("netsh advfirewall firewall add rule name=udp2raw protocol=TCP dir=out remoteip=%s remoteport=%d action=block\n",remote_addr.get_ip(),remote_addr.get_port()); - } - if(raw_mode==mode_udp) - { - printf("netsh advfirewall firewall add rule name=udp2raw protocol=UDP dir=in remoteip=%s remoteport=%d action=block\n",remote_addr.get_ip(),remote_addr.get_port()); - printf("netsh advfirewall firewall add rule name=udp2raw protocol=UDP dir=out remoteip=%s remoteport=%d action=block\n",remote_addr.get_ip(),remote_addr.get_port()); - } + if (raw_mode == mode_icmp) { + printf("netsh advfirewall firewall add rule name=udp2raw protocol=ICMPV4 dir=in remoteip=%s action=block\n", remote_addr.get_ip()); + printf("netsh advfirewall firewall add rule name=udp2raw protocol=ICMPV4 dir=out remoteip=%s action=block\n", remote_addr.get_ip()); + } + } else { + assert(raw_ip_version == AF_INET6); + if (raw_mode == mode_faketcp) { + printf("netsh advfirewall firewall add rule name=udp2raw protocol=TCP dir=in remoteip=%s remoteport=%d action=block\n", remote_addr.get_ip(), remote_addr.get_port()); + printf("netsh advfirewall firewall add rule name=udp2raw protocol=TCP dir=out remoteip=%s remoteport=%d action=block\n", remote_addr.get_ip(), remote_addr.get_port()); + } + if (raw_mode == mode_udp) { + printf("netsh advfirewall firewall add rule name=udp2raw protocol=UDP dir=in remoteip=%s remoteport=%d action=block\n", remote_addr.get_ip(), remote_addr.get_port()); + printf("netsh advfirewall firewall add rule name=udp2raw protocol=UDP dir=out remoteip=%s remoteport=%d action=block\n", remote_addr.get_ip(), remote_addr.get_port()); + } - if(raw_mode==mode_icmp) - { - printf("netsh advfirewall firewall add rule name=udp2raw protocol=ICMPV4 dir=in remoteip=%s action=block\n",remote_addr.get_ip()); - printf("netsh advfirewall firewall add rule name=udp2raw protocol=ICMPV4 dir=out remoteip=%s action=block\n",remote_addr.get_ip()); - } - } - else - { - assert(raw_ip_version==AF_INET6); - if(raw_mode==mode_faketcp) - { - printf("netsh advfirewall firewall add rule name=udp2raw protocol=TCP dir=in remoteip=%s remoteport=%d action=block\n",remote_addr.get_ip(),remote_addr.get_port()); - printf("netsh advfirewall firewall add rule name=udp2raw protocol=TCP dir=out remoteip=%s remoteport=%d action=block\n",remote_addr.get_ip(),remote_addr.get_port()); - } - if(raw_mode==mode_udp) - { - printf("netsh advfirewall firewall add rule name=udp2raw protocol=UDP dir=in remoteip=%s remoteport=%d action=block\n",remote_addr.get_ip(),remote_addr.get_port()); - printf("netsh advfirewall firewall add rule name=udp2raw protocol=UDP dir=out remoteip=%s remoteport=%d action=block\n",remote_addr.get_ip(),remote_addr.get_port()); - } - - if(raw_mode==mode_icmp) - { - printf("netsh advfirewall firewall add rule name=udp2raw protocol=ICMPV6 dir=in remoteip=%s action=block\n",remote_addr.get_ip()); - printf("netsh advfirewall firewall add rule name=udp2raw protocol=ICMPV6 dir=out remoteip=%s action=block\n",remote_addr.get_ip()); - } - } - - myexit(0); - - } + if (raw_mode == mode_icmp) { + printf("netsh advfirewall firewall add rule name=udp2raw protocol=ICMPV6 dir=in remoteip=%s action=block\n", remote_addr.get_ip()); + printf("netsh advfirewall firewall add rule name=udp2raw protocol=ICMPV6 dir=out remoteip=%s action=block\n", remote_addr.get_ip()); + } + } + myexit(0); + } } #endif -void signal_handler(int sig) -{ - about_to_exit=1; +void signal_handler(int sig) { + about_to_exit = 1; // myexit(0); } diff --git a/misc.h b/misc.h index 9fe14b4..b0e4239 100644 --- a/misc.h +++ b/misc.h @@ -8,7 +8,6 @@ #ifndef MISC_H_ #define MISC_H_ - #include "common.h" #include "log.h" #include "network.h" @@ -26,128 +25,131 @@ extern int enable_dns_resolve; extern int ttl_value; +const u32_t max_handshake_conn_num = 10000; +const u32_t max_ready_conn_num = 1000; +const u32_t anti_replay_window_size = 4000; +const int max_conv_num = 10000; -const u32_t max_handshake_conn_num=10000; -const u32_t max_ready_conn_num=1000; -const u32_t anti_replay_window_size=4000; -const int max_conv_num=10000; +const u32_t client_handshake_timeout = 5000; // unit ms +const u32_t client_retry_interval = 1000; // ms -const u32_t client_handshake_timeout=5000;//unit ms -const u32_t client_retry_interval=1000;//ms +const u32_t server_handshake_timeout = client_handshake_timeout + 5000; // this should be longer than clients. client retry initially ,server retry passtively -const u32_t server_handshake_timeout=client_handshake_timeout+5000;// this should be longer than clients. client retry initially ,server retry passtively +const int conv_clear_ratio = 30; // conv grabage collecter check 1/30 of all conv one time +const int conn_clear_ratio = 50; +const int conv_clear_min = 1; +const int conn_clear_min = 1; -const int conv_clear_ratio=30; //conv grabage collecter check 1/30 of all conv one time -const int conn_clear_ratio=50; -const int conv_clear_min=1; -const int conn_clear_min=1; +const u32_t conv_clear_interval = 1000; // ms +const u32_t conn_clear_interval = 1000; // ms -const u32_t conv_clear_interval=1000;//ms -const u32_t conn_clear_interval=1000;//ms +const i32_t max_fail_time = 0; // disable +const u32_t heartbeat_interval = 600; // ms -const i32_t max_fail_time=0;//disable +const u32_t timer_interval = 400; // ms. this should be smaller than heartbeat_interval and retry interval; -const u32_t heartbeat_interval=600;//ms +const uint32_t conv_timeout = 180000; // ms. 120 second +// const u32_t conv_timeout=30000; //for test -const u32_t timer_interval=400;//ms. this should be smaller than heartbeat_interval and retry interval; +const u32_t client_conn_timeout = 10000; // ms. +const u32_t client_conn_uplink_timeout = client_conn_timeout + 2000; // ms -const uint32_t conv_timeout=180000; //ms. 120 second -//const u32_t conv_timeout=30000; //for test +const uint32_t server_conn_timeout = conv_timeout + 60000; // ms. this should be 60s+ longer than conv_timeout,so that conv_manager can destruct convs gradually,to avoid latency glicth +// const u32_t server_conn_timeout=conv_timeout+10000;//for test -const u32_t client_conn_timeout=10000;//ms. -const u32_t client_conn_uplink_timeout=client_conn_timeout+2000;//ms +const u32_t iptables_rule_keep_interval = 20; // unit: second; -const uint32_t server_conn_timeout=conv_timeout+60000;//ms. this should be 60s+ longer than conv_timeout,so that conv_manager can destruct convs gradually,to avoid latency glicth -//const u32_t server_conn_timeout=conv_timeout+10000;//for test +enum server_current_state_t { server_idle = 0, + server_handshake1, + server_ready }; // server state machine +enum client_current_state_t { client_idle = 0, + client_tcp_handshake, + client_handshake1, + client_handshake2, + client_ready, + client_tcp_handshake_dummy }; // client state machine -const u32_t iptables_rule_keep_interval=20;//unit: second; +enum raw_mode_t { mode_faketcp = 0, + mode_udp, + mode_icmp, + mode_end }; +enum program_mode_t { unset_mode = 0, + client_mode, + server_mode }; -enum server_current_state_t {server_idle=0,server_handshake1,server_ready}; //server state machine -enum client_current_state_t {client_idle=0,client_tcp_handshake,client_handshake1,client_handshake2,client_ready,client_tcp_handshake_dummy};//client state machine - -enum raw_mode_t{mode_faketcp=0,mode_udp,mode_icmp,mode_end}; -enum program_mode_t {unset_mode=0,client_mode,server_mode}; - -union current_state_t -{ - server_current_state_t server_current_state; - client_current_state_t client_current_state; +union current_state_t { + server_current_state_t server_current_state; + client_current_state_t client_current_state; }; -//extern char remote_address[max_address_len]; -//extern char local_ip[100], remote_ip[100],source_ip[100];//local_ip is for -l option,remote_ip for -r option,source for --source-ip -//extern u32_t local_ip_uint32,remote_ip_uint32,source_ip_uint32;//convert from last line. -//extern int local_port , remote_port,source_port;//similiar to local_ip remote_ip,buf for port.source_port=0 indicates --source-port is not enabled +// extern char remote_address[max_address_len]; +// extern char local_ip[100], remote_ip[100],source_ip[100];//local_ip is for -l option,remote_ip for -r option,source for --source-ip +// extern u32_t local_ip_uint32,remote_ip_uint32,source_ip_uint32;//convert from last line. +// extern int local_port , remote_port,source_port;//similiar to local_ip remote_ip,buf for port.source_port=0 indicates --source-port is not enabled -extern address_t local_addr,remote_addr,source_addr; +extern address_t local_addr, remote_addr, source_addr; extern my_ip_t bind_addr; extern int bind_addr_used; -extern int force_source_ip; //if --source-ip is enabled +extern int force_source_ip; // if --source-ip is enabled extern int force_source_port; extern int source_port; -extern my_id_t const_id;//an id used for connection recovery,its generated randomly,it never change since its generated +extern my_id_t const_id; // an id used for connection recovery,its generated randomly,it never change since its generated -extern int udp_fd; //for client only. client use this fd to listen and handle udp connection -extern int bind_fd; //bind only,never send or recv. its just a dummy fd for bind,so that other program wont occupy the same port -extern int epollfd; //fd for epoll -extern int timer_fd; //the general timer fd for client and server.for server this is not the only timer find,every connection has a timer fd. -extern int fail_time_counter;//determine if the max_fail_time is reached -extern int epoll_trigger_counter;//for debug only -extern int debug_flag;//for debug only +extern int udp_fd; // for client only. client use this fd to listen and handle udp connection +extern int bind_fd; // bind only,never send or recv. its just a dummy fd for bind,so that other program wont occupy the same port +extern int epollfd; // fd for epoll +extern int timer_fd; // the general timer fd for client and server.for server this is not the only timer find,every connection has a timer fd. +extern int fail_time_counter; // determine if the max_fail_time is reached +extern int epoll_trigger_counter; // for debug only +extern int debug_flag; // for debug only - -extern int simple_rule; //deprecated. -extern int keep_rule; //whether to monitor the iptables rule periodly,re-add if losted -extern int auto_add_iptables_rule;//if -a is set -extern int generate_iptables_rule;//if -g is set -extern int generate_iptables_rule_add;// if --gen-add is set +extern int simple_rule; // deprecated. +extern int keep_rule; // whether to monitor the iptables rule periodly,re-add if losted +extern int auto_add_iptables_rule; // if -a is set +extern int generate_iptables_rule; // if -g is set +extern int generate_iptables_rule_add; // if --gen-add is set extern int retry_on_error; -const int retry_on_error_interval=10; +const int retry_on_error_interval = 10; -extern int debug_resend; // debug only +extern int debug_resend; // debug only -extern char key_string[1000];// -k option +extern char key_string[1000]; // -k option extern char fifo_file[1000]; - extern raw_mode_t raw_mode; extern u32_t raw_ip_version; extern program_mode_t program_mode; -extern unordered_map raw_mode_tostring ; +extern unordered_map raw_mode_tostring; extern int about_to_exit; extern int socket_buf_size; - extern pthread_t keep_thread; extern int keep_thread_running; - int process_lower_level_arg(); void print_help(); void iptables_rule(); -void pre_process_arg(int argc, char *argv[]);//mainly for load conf file; +void pre_process_arg(int argc, char *argv[]); // mainly for load conf file; int unit_test(); -int set_timer(int epollfd,int &timer_fd); -int set_timer_server(int epollfd,int &timer_fd,fd64_t &fd64); +int set_timer(int epollfd, int &timer_fd); +int set_timer_server(int epollfd, int &timer_fd, fd64_t &fd64); int handle_lower_level(raw_info_t &raw_info); int add_iptables_rule(const char *); int clear_iptables_rule(); -int iptables_gen_add(const char * s,u32_t const_id); -int iptables_rule_init(const char * s,u32_t const_id,int keep); +int iptables_gen_add(const char *s, u32_t const_id); +int iptables_rule_init(const char *s, u32_t const_id, int keep); int keep_iptables_rule(); - - -void signal_handler(int sig); +void signal_handler(int sig); #endif /* MISC_H_ */ diff --git a/my_ev.h b/my_ev.h index c0c0e24..5278bf0 100644 --- a/my_ev.h +++ b/my_ev.h @@ -2,4 +2,3 @@ #include "my_ev_common.h" #include "ev.h" - diff --git a/my_ev_common.h b/my_ev_common.h index 9ffd863..8bb97ea 100644 --- a/my_ev_common.h +++ b/my_ev_common.h @@ -1,6 +1,8 @@ #define EV_STANDALONE 1 -#define EV_COMMON void *data; unsigned long long u64; +#define EV_COMMON \ + void *data; \ + unsigned long long u64; #define EV_COMPAT3 0 //#include @@ -8,11 +10,10 @@ //#define EV_USE_SELECT 1 //#define EV_SELECT_IS_WINSOCKET 1 -# define EV_FD_TO_WIN32_HANDLE(fd) (fd) -# define EV_WIN32_HANDLE_TO_FD(handle) (handle) -# define EV_WIN32_CLOSE_FD(fd) closesocket (fd) -# define FD_SETSIZE 4096 +#define EV_FD_TO_WIN32_HANDLE(fd) (fd) +#define EV_WIN32_HANDLE_TO_FD(handle) (handle) +#define EV_WIN32_CLOSE_FD(fd) closesocket(fd) +#define FD_SETSIZE 4096 #endif //#define EV_VERIFY 2 - diff --git a/network.cpp b/network.cpp index 5699c9c..adb8d9b 100644 --- a/network.cpp +++ b/network.cpp @@ -9,53 +9,52 @@ #include "log.h" #include "misc.h" -int g_fix_gro=0; +int g_fix_gro = 0; -int raw_recv_fd=-1; -int raw_send_fd=-1; -u32_t link_level_header_len=0;//set it to 14 if SOCK_RAW is used in socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP)); -int use_tcp_dummy_socket=0; +int raw_recv_fd = -1; +int raw_send_fd = -1; +u32_t link_level_header_len = 0; // set it to 14 if SOCK_RAW is used in socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP)); +int use_tcp_dummy_socket = 0; -int seq_mode=3; -int max_seq_mode=4; -int random_drop=0; +int seq_mode = 3; +int max_seq_mode = 4; +int random_drop = 0; -int filter_port=-1; +int filter_port = -1; -int disable_bpf_filter=0; //for test only,most time no need to disable this +int disable_bpf_filter = 0; // for test only,most time no need to disable this -//u32_t bind_address_uint32=0; +// u32_t bind_address_uint32=0; -int lower_level=0; -int lower_level_manual=0; -int ifindex=-1; -char if_name[100]=""; +int lower_level = 0; +int lower_level_manual = 0; +int ifindex = -1; +char if_name[100] = ""; -char dev[100]=""; +char dev[100] = ""; -unsigned short g_ip_id_counter=0; +unsigned short g_ip_id_counter = 0; #ifdef UDP2RAW_LINUX -unsigned char dest_hw_addr[sizeof(sockaddr_ll::sll_addr)]= - {0xff,0xff,0xff,0xff,0xff,0xff,0,0}; +unsigned char dest_hw_addr[sizeof(sockaddr_ll::sll_addr)] = + {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0}; #endif //{0x00,0x23,0x45,0x67,0x89,0xb9}; -const u32_t receive_window_lower_bound=40960; -const u32_t receive_window_random_range=512; -const unsigned char wscale=0x05; +const u32_t receive_window_lower_bound = 40960; +const u32_t receive_window_random_range = 512; +const unsigned char wscale = 0x05; -char g_packet_buf[huge_buf_len]; //looks dirty but works well -int g_packet_buf_len=-1; -int g_packet_buf_cnt=0; +char g_packet_buf[huge_buf_len]; // looks dirty but works well +int g_packet_buf_len = -1; +int g_packet_buf_cnt = 0; #ifdef UDP2RAW_LINUX -union -{ - sockaddr_ll ll; - sockaddr_in ipv4; - sockaddr_in6 ipv6; -}g_sockaddr; +union { + sockaddr_ll ll; + sockaddr_in ipv4; + sockaddr_in6 ipv6; +} g_sockaddr; socklen_t g_sockaddr_len = -1; #endif @@ -63,65 +62,65 @@ socklen_t g_sockaddr_len = -1; #ifndef NO_LIBNET libnet_t *libnet_handle; -libnet_ptag_t g_ptag=0; -int send_with_pcap=0; +libnet_ptag_t g_ptag = 0; +int send_with_pcap = 0; #else -int send_with_pcap=1; +int send_with_pcap = 1; #endif -int pcap_header_captured=0; +int pcap_header_captured = 0; int pcap_header_buf[buf_len]; -int pcap_captured_full_len=-1; +int pcap_captured_full_len = -1; pcap_t *pcap_handle; -int pcap_link_header_len=-1; -//int pcap_cnt=0; +int pcap_link_header_len = -1; +// int pcap_cnt=0; queue_t my_queue; pthread_mutex_t queue_mutex = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t pcap_mutex = PTHREAD_MUTEX_INITIALIZER; -int use_pcap_mutex=1; +int use_pcap_mutex = 1; ev_async async_watcher; -struct ev_loop* g_default_loop; +struct ev_loop *g_default_loop; pthread_t pcap_recv_thread; struct bpf_program g_filter; -long long g_filter_compile_cnt=0; +long long g_filter_compile_cnt = 0; #endif #ifdef UDP2RAW_LINUX struct sock_filter code_tcp_old[] = { - { 0x28, 0, 0, 0x0000000c },//0 - { 0x15, 0, 10, 0x00000800 },//1 - { 0x30, 0, 0, 0x00000017 },//2 - { 0x15, 0, 8, 0x00000006 },//3 - { 0x28, 0, 0, 0x00000014 },//4 - { 0x45, 6, 0, 0x00001fff },//5 - { 0xb1, 0, 0, 0x0000000e },//6 - { 0x48, 0, 0, 0x0000000e },//7 - { 0x15, 2, 0, 0x0000ef32 },//8 - { 0x48, 0, 0, 0x00000010 },//9 - { 0x15, 0, 1, 0x0000ef32 },//10 - { 0x6, 0, 0, 0x0000ffff },//11 - { 0x6, 0, 0, 0x00000000 },//12 + {0x28, 0, 0, 0x0000000c}, // 0 + {0x15, 0, 10, 0x00000800}, // 1 + {0x30, 0, 0, 0x00000017}, // 2 + {0x15, 0, 8, 0x00000006}, // 3 + {0x28, 0, 0, 0x00000014}, // 4 + {0x45, 6, 0, 0x00001fff}, // 5 + {0xb1, 0, 0, 0x0000000e}, // 6 + {0x48, 0, 0, 0x0000000e}, // 7 + {0x15, 2, 0, 0x0000ef32}, // 8 + {0x48, 0, 0, 0x00000010}, // 9 + {0x15, 0, 1, 0x0000ef32}, // 10 + {0x6, 0, 0, 0x0000ffff}, // 11 + {0x6, 0, 0, 0x00000000}, // 12 }; struct sock_filter code_tcp[] = { -//{ 0x5, 0, 0, 0x00000001 },//0 //jump to 2,dirty hack from tcpdump -d's output -//{ 0x5, 0, 0, 0x00000000 },//1 -{ 0x30, 0, 0, 0x00000009 },//2 -{ 0x15, 0, 6, 0x00000006 },//3 -{ 0x28, 0, 0, 0x00000006 },//4 -{ 0x45, 4, 0, 0x00001fff },//5 -{ 0xb1, 0, 0, 0x00000000 },//6 -{ 0x48, 0, 0, 0x00000002 },//7 -{ 0x15, 0, 1, 0x0000fffe },//8 //modify this fffe to the port you listen on -{ 0x6, 0, 0, 0x0000ffff },//9 -{ 0x6, 0, 0, 0x00000000 },//10 + //{ 0x5, 0, 0, 0x00000001 },//0 //jump to 2,dirty hack from tcpdump -d's output + //{ 0x5, 0, 0, 0x00000000 },//1 + {0x30, 0, 0, 0x00000009}, // 2 + {0x15, 0, 6, 0x00000006}, // 3 + {0x28, 0, 0, 0x00000006}, // 4 + {0x45, 4, 0, 0x00001fff}, // 5 + {0xb1, 0, 0, 0x00000000}, // 6 + {0x48, 0, 0, 0x00000002}, // 7 + {0x15, 0, 1, 0x0000fffe}, // 8 //modify this fffe to the port you listen on + {0x6, 0, 0, 0x0000ffff}, // 9 + {0x6, 0, 0, 0x00000000}, // 10 }; /* { 0x28, 0, 0, 0x0000000c }, @@ -137,19 +136,19 @@ struct sock_filter code_tcp[] = { { 0x6, 0, 0, 0x00000000 }, */ -int code_tcp_port_index=6; +int code_tcp_port_index = 6; -//tcpdump -i ens33 ip6 and tcp and dst port 65534 -dd +// tcpdump -i ens33 ip6 and tcp and dst port 65534 -dd struct sock_filter code_tcp6[] = { -//{ 0x28, 0, 0, 0x0000000c },//0 -//{ 0x15, 0, 5, 0x000086dd },//1 -{ 0x30, 0, 0, 0x00000006 },//2 -{ 0x15, 0, 3, 0x00000006 },//3 -{ 0x28, 0, 0, 0x0000002a },//4 -{ 0x15, 0, 1, 0x0000fffe },//5 -{ 0x6, 0, 0, 0x00040000 },//6 -{ 0x6, 0, 0, 0x00000000 },//7 -};//note: this filter doesnt support extension headers + //{ 0x28, 0, 0, 0x0000000c },//0 + //{ 0x15, 0, 5, 0x000086dd },//1 + {0x30, 0, 0, 0x00000006}, // 2 + {0x15, 0, 3, 0x00000006}, // 3 + {0x28, 0, 0, 0x0000002a}, // 4 + {0x15, 0, 1, 0x0000fffe}, // 5 + {0x6, 0, 0, 0x00040000}, // 6 + {0x6, 0, 0, 0x00000000}, // 7 +}; // note: this filter doesnt support extension headers /* { 0x30, 0, 0, 0x00000014 },//2 { 0x15, 0, 3, 0x00000006 },//3 @@ -159,55 +158,55 @@ struct sock_filter code_tcp6[] = { { 0x6, 0, 0, 0x00000000 },//7 */ -int code_tcp6_port_index=3; +int code_tcp6_port_index = 3; struct sock_filter code_udp[] = { -//{ 0x5, 0, 0, 0x00000001 }, -//{ 0x5, 0, 0, 0x00000000 }, -{ 0x30, 0, 0, 0x00000009 }, -{ 0x15, 0, 6, 0x00000011 }, -{ 0x28, 0, 0, 0x00000006 }, -{ 0x45, 4, 0, 0x00001fff }, -{ 0xb1, 0, 0, 0x00000000 }, -{ 0x48, 0, 0, 0x00000002 }, -{ 0x15, 0, 1, 0x0000fffe }, //modify this fffe to the port you listen on -{ 0x6, 0, 0, 0x0000ffff }, -{ 0x6, 0, 0, 0x00000000 }, + //{ 0x5, 0, 0, 0x00000001 }, + //{ 0x5, 0, 0, 0x00000000 }, + {0x30, 0, 0, 0x00000009}, + {0x15, 0, 6, 0x00000011}, + {0x28, 0, 0, 0x00000006}, + {0x45, 4, 0, 0x00001fff}, + {0xb1, 0, 0, 0x00000000}, + {0x48, 0, 0, 0x00000002}, + {0x15, 0, 1, 0x0000fffe}, // modify this fffe to the port you listen on + {0x6, 0, 0, 0x0000ffff}, + {0x6, 0, 0, 0x00000000}, }; -int code_udp_port_index=6; +int code_udp_port_index = 6; struct sock_filter code_udp6[] = { -// { 0x28, 0, 0, 0x0000000c }, -// { 0x15, 0, 5, 0x000086dd }, - { 0x30, 0, 0, 0x00000006 }, - { 0x15, 0, 3, 0x00000011 }, - { 0x28, 0, 0, 0x0000002a }, - { 0x15, 0, 1, 0x0000fffe }, - { 0x6, 0, 0, 0x00040000 }, - { 0x6, 0, 0, 0x00000000 }, + // { 0x28, 0, 0, 0x0000000c }, + // { 0x15, 0, 5, 0x000086dd }, + {0x30, 0, 0, 0x00000006}, + {0x15, 0, 3, 0x00000011}, + {0x28, 0, 0, 0x0000002a}, + {0x15, 0, 1, 0x0000fffe}, + {0x6, 0, 0, 0x00040000}, + {0x6, 0, 0, 0x00000000}, }; -int code_udp6_port_index=3; +int code_udp6_port_index = 3; struct sock_filter code_icmp[] = { -//{ 0x5, 0, 0, 0x00000001 }, -//{ 0x5, 0, 0, 0x00000000 }, -{ 0x30, 0, 0, 0x00000009 }, -{ 0x15, 0, 1, 0x00000001 }, -{ 0x6, 0, 0, 0x0000ffff }, -{ 0x6, 0, 0, 0x00000000 }, + //{ 0x5, 0, 0, 0x00000001 }, + //{ 0x5, 0, 0, 0x00000000 }, + {0x30, 0, 0, 0x00000009}, + {0x15, 0, 1, 0x00000001}, + {0x6, 0, 0, 0x0000ffff}, + {0x6, 0, 0, 0x00000000}, }; struct sock_filter code_icmp6[] = { -// { 0x28, 0, 0, 0x0000000c }, -// { 0x15, 0, 6, 0x000086dd }, - { 0x30, 0, 0, 0x00000006 }, - { 0x15, 3, 0, 0x0000003a }, - { 0x15, 0, 3, 0x0000002c }, - { 0x30, 0, 0, 0x00000028 }, - { 0x15, 0, 1, 0x0000003a }, - { 0x6, 0, 0, 0x00040000 }, - { 0x6, 0, 0, 0x00000000 }, + // { 0x28, 0, 0, 0x0000000c }, + // { 0x15, 0, 6, 0x000086dd }, + {0x30, 0, 0, 0x00000006}, + {0x15, 3, 0, 0x0000003a}, + {0x15, 0, 3, 0x0000002c}, + {0x30, 0, 0, 0x00000028}, + {0x15, 0, 1, 0x0000003a}, + {0x6, 0, 0, 0x00040000}, + {0x6, 0, 0, 0x00000000}, }; /* @@ -260,1001 +259,842 @@ tcpdump -i eth1 ip and icmp -dd */ #endif -packet_info_t::packet_info_t() -{ - src_port=0; - dst_port=0; - if (raw_mode == mode_faketcp) - { - protocol = IPPROTO_TCP; - ack_seq = get_true_random_number(); - seq = get_true_random_number(); - has_ts=0; - ts_ack=0; - syn=0; - ack=1; - ack_seq_counter=0; - - //mylog(log_info,"\n",ts_ack); - } - else if (raw_mode == mode_udp) - { - protocol = IPPROTO_UDP; - } - else if (raw_mode == mode_icmp) - { - if(raw_ip_version==AF_INET) - { - protocol = IPPROTO_ICMP; - } - else - { - assert(raw_ip_version==AF_INET6); - protocol = IPPROTO_ICMPV6; - } - my_icmp_seq=0; - } +packet_info_t::packet_info_t() { + src_port = 0; + dst_port = 0; + if (raw_mode == mode_faketcp) { + protocol = IPPROTO_TCP; + ack_seq = get_true_random_number(); + seq = get_true_random_number(); + has_ts = 0; + ts_ack = 0; + syn = 0; + ack = 1; + ack_seq_counter = 0; + // mylog(log_info,"\n",ts_ack); + } else if (raw_mode == mode_udp) { + protocol = IPPROTO_UDP; + } else if (raw_mode == mode_icmp) { + if (raw_ip_version == AF_INET) { + protocol = IPPROTO_ICMP; + } else { + assert(raw_ip_version == AF_INET6); + protocol = IPPROTO_ICMPV6; + } + my_icmp_seq = 0; + } } #ifdef UDP2RAW_MP void my_packet_handler( u_char *args, const struct pcap_pkthdr *packet_header, - const u_char *pkt_data -) -{ - /*printf("<%d %d>\n",(int)packet_header->caplen,(int)packet_header->len ); - for(int i=0;i",int( p[i] )); - } - printf("\n");*/ - //mylog(log_debug,"received a packet!\n"); - assert(packet_header->caplen <= packet_header->len); - assert(packet_header->caplen <= huge_data_len); - //if(packet_header->caplen > max_data_len) return ; - if(g_fix_gro==0&&packet_header->caplenlen) return; + const u_char *pkt_data) { + /*printf("<%d %d>\n",(int)packet_header->caplen,(int)packet_header->len ); + for(int i=0;i",int( p[i] )); + } + printf("\n");*/ + // mylog(log_debug,"received a packet!\n"); + assert(packet_header->caplen <= packet_header->len); + assert(packet_header->caplen <= huge_data_len); + // if(packet_header->caplen > max_data_len) return ; + if (g_fix_gro == 0 && packet_header->caplen < packet_header->len) return; - if((int)packet_header->caplencaplen < pcap_link_header_len) return; + // mylog(log_debug,"and its vaild!\n"); - pthread_mutex_lock(&queue_mutex); - if(!my_queue.full()) - my_queue.push_back((char *)pkt_data,(int)(packet_header->caplen)); - pthread_mutex_unlock(&queue_mutex); + pthread_mutex_lock(&queue_mutex); + if (!my_queue.full()) + my_queue.push_back((char *)pkt_data, (int)(packet_header->caplen)); + pthread_mutex_unlock(&queue_mutex); - //pcap_cnt++; + // pcap_cnt++; - ev_async_send (g_default_loop,&async_watcher); + ev_async_send(g_default_loop, &async_watcher); return; } -void *pcap_recv_thread_entry(void *none) -{ - struct pcap_pkthdr *packet_header; - const u_char *pkt_data; +void *pcap_recv_thread_entry(void *none) { + struct pcap_pkthdr *packet_header; + const u_char *pkt_data; - while(1) - { - if(use_pcap_mutex) pthread_mutex_lock(&pcap_mutex); - int ret=pcap_loop(pcap_handle, -1, my_packet_handler, NULL); //use -1 instead of 0 as cnt, since 0 is undefined in old versions - if(use_pcap_mutex) pthread_mutex_unlock(&pcap_mutex); - if(ret==-1) - mylog(log_warn,"pcap_loop exited with value %d\n",ret); - else - { - mylog(log_debug,"pcap_loop exited with value %d\n",ret); - } - ev_sleep(1.0); - //myexit(-1); - } - /* - while(1) - { - //printf("!!!\n"); - pthread_mutex_lock(&pcap_mutex); - int ret=pcap_next_ex(pcap_handle,&packet_header,&pkt_data); - pthread_mutex_unlock(&pcap_mutex); + while (1) { + if (use_pcap_mutex) pthread_mutex_lock(&pcap_mutex); + int ret = pcap_loop(pcap_handle, -1, my_packet_handler, NULL); // use -1 instead of 0 as cnt, since 0 is undefined in old versions + if (use_pcap_mutex) pthread_mutex_unlock(&pcap_mutex); + if (ret == -1) + mylog(log_warn, "pcap_loop exited with value %d\n", ret); + else { + mylog(log_debug, "pcap_loop exited with value %d\n", ret); + } + ev_sleep(1.0); + // myexit(-1); + } + /* + while(1) + { + //printf("!!!\n"); + pthread_mutex_lock(&pcap_mutex); + int ret=pcap_next_ex(pcap_handle,&packet_header,&pkt_data); + pthread_mutex_unlock(&pcap_mutex); - switch (ret) - { - case 0: - continue; - case 1: + switch (ret) + { + case 0: + continue; + case 1: - break; + break; - case -1: - mylog(log_fatal,"pcap_next_ex error [%s]\n",pcap_geterr(pcap_handle)); - myexit(-1); - break; - case -2: - assert(0==1);// - break; - default: - assert(0==1);// - } - } - myexit(-1);*/ - return 0; + case -1: + mylog(log_fatal,"pcap_next_ex error [%s]\n",pcap_geterr(pcap_handle)); + myexit(-1); + break; + case -2: + assert(0==1);// + break; + default: + assert(0==1);// + } + } + myexit(-1);*/ + return 0; } extern void async_cb(struct ev_loop *loop, struct ev_async *watcher, int revents); #endif #ifdef UDP2RAW_LINUX -int init_raw_socket() -{ - assert(raw_ip_version==AF_INET||raw_ip_version==AF_INET6); +int init_raw_socket() { + assert(raw_ip_version == AF_INET || raw_ip_version == AF_INET6); - g_ip_id_counter=get_true_random_number()%65535; - if(lower_level==0) - { - raw_send_fd = socket(raw_ip_version , SOCK_RAW , IPPROTO_RAW);// IPPROTO_TCP?? + g_ip_id_counter = get_true_random_number() % 65535; + if (lower_level == 0) { + raw_send_fd = socket(raw_ip_version, SOCK_RAW, IPPROTO_RAW); // IPPROTO_TCP?? - if(raw_send_fd == -1) { - mylog(log_fatal,"Failed to create raw_send_fd\n"); - //perror("Failed to create raw_send_fd"); - myexit(1); - } + if (raw_send_fd == -1) { + mylog(log_fatal, "Failed to create raw_send_fd\n"); + // perror("Failed to create raw_send_fd"); + myexit(1); + } - /*ETH_P_IP - int one = 1; - const int *val = &one; - if (setsockopt (raw_send_fd, IPPROTO_IP, IP_HDRINCL, val, sizeof (one)) < 0) { - mylog(log_fatal,"Error setting IP_HDRINCL %d\n",errno); - //perror("Error setting IP_HDRINCL"); - myexit(2); - }*/ + /*ETH_P_IP + int one = 1; + const int *val = &one; + if (setsockopt (raw_send_fd, IPPROTO_IP, IP_HDRINCL, val, sizeof (one)) < 0) { + mylog(log_fatal,"Error setting IP_HDRINCL %d\n",errno); + //perror("Error setting IP_HDRINCL"); + myexit(2); + }*/ + } else { + raw_send_fd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP)); // todo how to create a recv only raw socket? - } - else - { - raw_send_fd = socket(PF_PACKET , SOCK_DGRAM , htons(ETH_P_IP));// todo how to create a recv only raw socket? - - if(raw_send_fd == -1) { - mylog(log_fatal,"Failed to create raw_send_fd\n"); - //perror("Failed to create raw_send_fd"); - myexit(1); - } - //init_ifindex(if_name); - - } + if (raw_send_fd == -1) { + mylog(log_fatal, "Failed to create raw_send_fd\n"); + // perror("Failed to create raw_send_fd"); + myexit(1); + } + // init_ifindex(if_name); + } int opt = 0; - assert(setsockopt(raw_send_fd, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt))==0);// raw_send_fd is for send only, set its recv buffer to zero + assert(setsockopt(raw_send_fd, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt)) == 0); // raw_send_fd is for send only, set its recv buffer to zero - if(force_socket_buf) - { - if(setsockopt(raw_send_fd, SOL_SOCKET, SO_SNDBUFFORCE, &socket_buf_size, sizeof(socket_buf_size))<0) - { - mylog(log_fatal,"SO_SNDBUFFORCE fail socket_buf_size=%d errno=%s\n",socket_buf_size,strerror(errno)); - myexit(1); - } - } - else - { - if(setsockopt(raw_send_fd, SOL_SOCKET, SO_SNDBUF, &socket_buf_size, sizeof(socket_buf_size))<0) - { - mylog(log_fatal,"SO_SNDBUF fail socket_buf_size=%d errno=%s\n",socket_buf_size,strerror(errno)); - myexit(1); - } - } + if (force_socket_buf) { + if (setsockopt(raw_send_fd, SOL_SOCKET, SO_SNDBUFFORCE, &socket_buf_size, sizeof(socket_buf_size)) < 0) { + mylog(log_fatal, "SO_SNDBUFFORCE fail socket_buf_size=%d errno=%s\n", socket_buf_size, strerror(errno)); + myexit(1); + } + } else { + if (setsockopt(raw_send_fd, SOL_SOCKET, SO_SNDBUF, &socket_buf_size, sizeof(socket_buf_size)) < 0) { + mylog(log_fatal, "SO_SNDBUF fail socket_buf_size=%d errno=%s\n", socket_buf_size, strerror(errno)); + myexit(1); + } + } + // raw_fd = socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_ALL)); + if (raw_ip_version == AF_INET) + raw_recv_fd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP)); + else + raw_recv_fd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IPV6)); + // ETH_P_IP doesnt read outgoing packets + // https://stackoverflow.com/questions/20264895/eth-p-ip-is-not-working-as-expected-i-can-only-receive-incoming-packets + // to capture both incoming and outgoing packets use ETH_P_ALL - //raw_fd = socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_ALL)); - - if(raw_ip_version==AF_INET) - raw_recv_fd= socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP)); - else - raw_recv_fd= socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IPV6)); - //ETH_P_IP doesnt read outgoing packets - // https://stackoverflow.com/questions/20264895/eth-p-ip-is-not-working-as-expected-i-can-only-receive-incoming-packets - // to capture both incoming and outgoing packets use ETH_P_ALL - - if(raw_recv_fd == -1) { - mylog(log_fatal,"Failed to create raw_recv_fd\n"); - //perror(""); + if (raw_recv_fd == -1) { + mylog(log_fatal, "Failed to create raw_recv_fd\n"); + // perror(""); myexit(1); } - if(strlen(dev)!=0) - { + if (strlen(dev) != 0) { struct sockaddr_ll bind_address; memset(&bind_address, 0, sizeof(bind_address)); - int index=-1; - assert(init_ifindex(dev,raw_recv_fd,index)==0); + int index = -1; + assert(init_ifindex(dev, raw_recv_fd, index) == 0); bind_address.sll_family = AF_PACKET; - if(raw_ip_version==AF_INET) - bind_address.sll_protocol = htons(ETH_P_IP); - else - bind_address.sll_protocol = htons(ETH_P_IPV6); + if (raw_ip_version == AF_INET) + bind_address.sll_protocol = htons(ETH_P_IP); + else + bind_address.sll_protocol = htons(ETH_P_IPV6); bind_address.sll_ifindex = index; - if(bind(raw_recv_fd, (struct sockaddr *)&bind_address, sizeof(bind_address))==-1) - { - mylog(log_fatal,"bind to dev [%s] failed\n",dev); - myexit(1); + if (bind(raw_recv_fd, (struct sockaddr *)&bind_address, sizeof(bind_address)) == -1) { + mylog(log_fatal, "bind to dev [%s] failed\n", dev); + myexit(1); } } - if(force_socket_buf) - { - if(setsockopt(raw_recv_fd, SOL_SOCKET, SO_RCVBUFFORCE, &socket_buf_size, sizeof(socket_buf_size))<0) - { - mylog(log_fatal,"SO_RCVBUFFORCE fail socket_buf_size=%d errno=%s\n",socket_buf_size,strerror(errno)); - myexit(1); - } - } - else - { - if(setsockopt(raw_recv_fd, SOL_SOCKET, SO_RCVBUF, &socket_buf_size, sizeof(socket_buf_size))<0) - { - mylog(log_fatal,"SO_RCVBUF fail socket_buf_size=%d errno=%s\n",socket_buf_size,strerror(errno)); - myexit(1); - } - } + if (force_socket_buf) { + if (setsockopt(raw_recv_fd, SOL_SOCKET, SO_RCVBUFFORCE, &socket_buf_size, sizeof(socket_buf_size)) < 0) { + mylog(log_fatal, "SO_RCVBUFFORCE fail socket_buf_size=%d errno=%s\n", socket_buf_size, strerror(errno)); + myexit(1); + } + } else { + if (setsockopt(raw_recv_fd, SOL_SOCKET, SO_RCVBUF, &socket_buf_size, sizeof(socket_buf_size)) < 0) { + mylog(log_fatal, "SO_RCVBUF fail socket_buf_size=%d errno=%s\n", socket_buf_size, strerror(errno)); + myexit(1); + } + } - //IP_HDRINCL to tell the kernel that headers are included in the packet + // IP_HDRINCL to tell the kernel that headers are included in the packet - - - setnonblocking(raw_send_fd); //not really necessary + setnonblocking(raw_send_fd); // not really necessary setnonblocking(raw_recv_fd); - return 0; + return 0; } #endif #ifdef UDP2RAW_MP -int init_raw_socket() -{ - +int init_raw_socket() { #ifndef NO_LIBNET - char libnet_errbuf[LIBNET_ERRBUF_SIZE]; + char libnet_errbuf[LIBNET_ERRBUF_SIZE]; - if(raw_ip_version==AF_INET) - { - libnet_handle = libnet_init(LIBNET_RAW4, dev, libnet_errbuf); - } - else - { - assert(raw_ip_version==AF_INET6); - libnet_handle = libnet_init(LIBNET_RAW6, dev, libnet_errbuf); - } + if (raw_ip_version == AF_INET) { + libnet_handle = libnet_init(LIBNET_RAW4, dev, libnet_errbuf); + } else { + assert(raw_ip_version == AF_INET6); + libnet_handle = libnet_init(LIBNET_RAW6, dev, libnet_errbuf); + } - if(libnet_handle==0) - { - mylog(log_fatal,"libnet_init failed bc of [%s]\n",libnet_errbuf); - myexit(-1); - } - g_ptag=0; + if (libnet_handle == 0) { + mylog(log_fatal, "libnet_init failed bc of [%s]\n", libnet_errbuf); + myexit(-1); + } + g_ptag = 0; libnet_clear_packet(libnet_handle); #endif - char pcap_errbuf[PCAP_ERRBUF_SIZE]; + char pcap_errbuf[PCAP_ERRBUF_SIZE]; - //pcap_handle=pcap_open_live(dev,max_data_len,0,1000,pcap_errbuf); + // pcap_handle=pcap_open_live(dev,max_data_len,0,1000,pcap_errbuf); - pcap_handle = pcap_create( dev, pcap_errbuf ); + pcap_handle = pcap_create(dev, pcap_errbuf); - - if(pcap_handle==0) - { - mylog(log_fatal,"pcap_create failed bc of [%s]\n",pcap_errbuf); - myexit(-1); - } - - assert( pcap_set_snaplen(pcap_handle, huge_data_len) ==0); - assert( pcap_set_promisc(pcap_handle, 0) ==0); - assert( pcap_set_timeout(pcap_handle, 1) ==0); - assert( pcap_set_immediate_mode(pcap_handle,1) ==0); - - int ret = pcap_activate( pcap_handle ); - if( ret < 0 ) - { - printf("pcap_activate failed %s\n", pcap_geterr(pcap_handle)); - myexit(-1); - } - - if(send_with_pcap) - { - ret=pcap_setdirection(pcap_handle,PCAP_D_INOUT);//must be used after being actived - if(ret!=0) mylog(log_debug,"pcap_setdirection(pcap_handle,PCAP_D_INOUT) failed with value %d, %s\n",ret,pcap_geterr(pcap_handle)); - } - else - { - ret=pcap_setdirection(pcap_handle,PCAP_D_IN); - if(ret!=0) mylog(log_debug,"pcap_setdirection(pcap_handle,PCAP_D_IN) failed with value %d, %s\n",ret,pcap_geterr(pcap_handle)); - } - - - ret=pcap_datalink(pcap_handle); - - if(ret==DLT_EN10MB) - { - pcap_link_header_len=14; - } - else if(ret==DLT_NULL) - { - pcap_link_header_len=4; - } - else if(ret==DLT_LINUX_SLL) - { - pcap_link_header_len=16; - } - else - { - mylog(log_fatal,"unknown pcap link type : %d\n",ret); - myexit(-1); - } - - char filter_exp[1000]; - - address_t tmp_addr; - if(get_src_adress2(tmp_addr,remote_addr)!=0) - { - mylog(log_error,"get_src_adress() failed, maybe you dont have internet\n"); - myexit(-1); - } - - string src=tmp_addr.get_ip(); - string dst=remote_addr.get_ip(); - if(raw_ip_version==AF_INET) - { - //sprintf(filter_exp,"ip and src %s and dst %s and (tcp or udp or icmp)",my_ntoa(source_ip_uint32),dst.c_str()); - sprintf(filter_exp,"ip and src %s and dst %s and (tcp or udp or icmp)",src.c_str(),dst.c_str()); - } - else - { - assert(raw_ip_version==AF_INET6); - sprintf(filter_exp,"ip6 and src %s and dst %s and (tcp or udp or icmp6)",src.c_str(),dst.c_str()); - - } - - if (pcap_compile(pcap_handle, &g_filter, filter_exp, 0, PCAP_NETMASK_UNKNOWN ) == -1) { - printf("Bad filter - %s\n", pcap_geterr(pcap_handle)); - myexit(-1); - } - g_filter_compile_cnt++; - - - if (pcap_setfilter(pcap_handle, &g_filter) == -1) { - printf("Error setting filter - %s\n", pcap_geterr(pcap_handle)); - myexit(-1); - } - -///////////////////////////////////////////////////////////////new thread created here - if(pthread_create(&pcap_recv_thread, NULL, pcap_recv_thread_entry, 0)) { - mylog(log_fatal, "Error creating thread\n"); - myexit(-1); - } -//////////////////////////////////////////////////////////////////////////////// - - - g_ip_id_counter=get_true_random_number()%65535; - - /* - if(lower_level==0) - { - raw_send_fd = socket(AF_INET , SOCK_RAW , IPPROTO_TCP); - - if(raw_send_fd == -1) { - mylog(log_fatal,"Failed to create raw_send_fd\n"); - //perror("Failed to create raw_send_fd"); - myexit(1); - } - - int one = 1; - const int *val = &one; - if (setsockopt (raw_send_fd, IPPROTO_IP, IP_HDRINCL, val, sizeof (one)) < 0) { - mylog(log_fatal,"Error setting IP_HDRINCL %d\n",errno); - //perror("Error setting IP_HDRINCL"); - myexit(2); - } - - - } - else - { - raw_send_fd = socket(PF_PACKET , SOCK_DGRAM , htons(ETH_P_IP)); - - if(raw_send_fd == -1) { - mylog(log_fatal,"Failed to create raw_send_fd\n"); - //perror("Failed to create raw_send_fd"); - myexit(1); - } - //init_ifindex(if_name); - - } - - if(force_socket_buf) - { - if(setsockopt(raw_send_fd, SOL_SOCKET, SO_SNDBUFFORCE, &socket_buf_size, sizeof(socket_buf_size))<0) - { - mylog(log_fatal,"SO_SNDBUFFORCE fail socket_buf_size=%d errno=%s\n",socket_buf_size,strerror(errno)); - myexit(1); - } - } - else - { - if(setsockopt(raw_send_fd, SOL_SOCKET, SO_SNDBUF, &socket_buf_size, sizeof(socket_buf_size))<0) - { - mylog(log_fatal,"SO_SNDBUF fail socket_buf_size=%d errno=%s\n",socket_buf_size,strerror(errno)); - myexit(1); - } - } - - - - //raw_fd = socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_ALL)); - - raw_recv_fd= socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP)); - - if(raw_recv_fd == -1) { - mylog(log_fatal,"Failed to create raw_recv_fd\n"); - //perror(""); - myexit(1); + if (pcap_handle == 0) { + mylog(log_fatal, "pcap_create failed bc of [%s]\n", pcap_errbuf); + myexit(-1); } - if(force_socket_buf) - { - if(setsockopt(raw_recv_fd, SOL_SOCKET, SO_RCVBUFFORCE, &socket_buf_size, sizeof(socket_buf_size))<0) - { - mylog(log_fatal,"SO_RCVBUFFORCE fail socket_buf_size=%d errno=%s\n",socket_buf_size,strerror(errno)); - myexit(1); - } - } - else - { - if(setsockopt(raw_recv_fd, SOL_SOCKET, SO_RCVBUF, &socket_buf_size, sizeof(socket_buf_size))<0) - { - mylog(log_fatal,"SO_RCVBUF fail socket_buf_size=%d errno=%s\n",socket_buf_size,strerror(errno)); - myexit(1); - } - } + assert(pcap_set_snaplen(pcap_handle, huge_data_len) == 0); + assert(pcap_set_promisc(pcap_handle, 0) == 0); + assert(pcap_set_timeout(pcap_handle, 1) == 0); + assert(pcap_set_immediate_mode(pcap_handle, 1) == 0); - //IP_HDRINCL to tell the kernel that headers are included in the packet + int ret = pcap_activate(pcap_handle); + if (ret < 0) { + printf("pcap_activate failed %s\n", pcap_geterr(pcap_handle)); + myexit(-1); + } + + if (send_with_pcap) { + ret = pcap_setdirection(pcap_handle, PCAP_D_INOUT); // must be used after being actived + if (ret != 0) mylog(log_debug, "pcap_setdirection(pcap_handle,PCAP_D_INOUT) failed with value %d, %s\n", ret, pcap_geterr(pcap_handle)); + } else { + ret = pcap_setdirection(pcap_handle, PCAP_D_IN); + if (ret != 0) mylog(log_debug, "pcap_setdirection(pcap_handle,PCAP_D_IN) failed with value %d, %s\n", ret, pcap_geterr(pcap_handle)); + } + + ret = pcap_datalink(pcap_handle); + + if (ret == DLT_EN10MB) { + pcap_link_header_len = 14; + } else if (ret == DLT_NULL) { + pcap_link_header_len = 4; + } else if (ret == DLT_LINUX_SLL) { + pcap_link_header_len = 16; + } else { + mylog(log_fatal, "unknown pcap link type : %d\n", ret); + myexit(-1); + } + + char filter_exp[1000]; + + address_t tmp_addr; + if (get_src_adress2(tmp_addr, remote_addr) != 0) { + mylog(log_error, "get_src_adress() failed, maybe you dont have internet\n"); + myexit(-1); + } + + string src = tmp_addr.get_ip(); + string dst = remote_addr.get_ip(); + if (raw_ip_version == AF_INET) { + // sprintf(filter_exp,"ip and src %s and dst %s and (tcp or udp or icmp)",my_ntoa(source_ip_uint32),dst.c_str()); + sprintf(filter_exp, "ip and src %s and dst %s and (tcp or udp or icmp)", src.c_str(), dst.c_str()); + } else { + assert(raw_ip_version == AF_INET6); + sprintf(filter_exp, "ip6 and src %s and dst %s and (tcp or udp or icmp6)", src.c_str(), dst.c_str()); + } + + if (pcap_compile(pcap_handle, &g_filter, filter_exp, 0, PCAP_NETMASK_UNKNOWN) == -1) { + printf("Bad filter - %s\n", pcap_geterr(pcap_handle)); + myexit(-1); + } + g_filter_compile_cnt++; + + if (pcap_setfilter(pcap_handle, &g_filter) == -1) { + printf("Error setting filter - %s\n", pcap_geterr(pcap_handle)); + myexit(-1); + } + + ///////////////////////////////////////////////////////////////new thread created here + if (pthread_create(&pcap_recv_thread, NULL, pcap_recv_thread_entry, 0)) { + mylog(log_fatal, "Error creating thread\n"); + myexit(-1); + } + //////////////////////////////////////////////////////////////////////////////// + + g_ip_id_counter = get_true_random_number() % 65535; + + /* + if(lower_level==0) + { + raw_send_fd = socket(AF_INET , SOCK_RAW , IPPROTO_TCP); + + if(raw_send_fd == -1) { + mylog(log_fatal,"Failed to create raw_send_fd\n"); + //perror("Failed to create raw_send_fd"); + myexit(1); + } + + int one = 1; + const int *val = &one; + if (setsockopt (raw_send_fd, IPPROTO_IP, IP_HDRINCL, val, sizeof (one)) < 0) { + mylog(log_fatal,"Error setting IP_HDRINCL %d\n",errno); + //perror("Error setting IP_HDRINCL"); + myexit(2); + } + + + } + else + { + raw_send_fd = socket(PF_PACKET , SOCK_DGRAM , htons(ETH_P_IP)); + + if(raw_send_fd == -1) { + mylog(log_fatal,"Failed to create raw_send_fd\n"); + //perror("Failed to create raw_send_fd"); + myexit(1); + } + //init_ifindex(if_name); + + } + + if(force_socket_buf) + { + if(setsockopt(raw_send_fd, SOL_SOCKET, SO_SNDBUFFORCE, &socket_buf_size, sizeof(socket_buf_size))<0) + { + mylog(log_fatal,"SO_SNDBUFFORCE fail socket_buf_size=%d errno=%s\n",socket_buf_size,strerror(errno)); + myexit(1); + } + } + else + { + if(setsockopt(raw_send_fd, SOL_SOCKET, SO_SNDBUF, &socket_buf_size, sizeof(socket_buf_size))<0) + { + mylog(log_fatal,"SO_SNDBUF fail socket_buf_size=%d errno=%s\n",socket_buf_size,strerror(errno)); + myexit(1); + } + } - setnonblocking(raw_send_fd); //not really necessary - setnonblocking(raw_recv_fd);*/ + //raw_fd = socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_ALL)); - return 0; + raw_recv_fd= socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP)); + +if(raw_recv_fd == -1) { + mylog(log_fatal,"Failed to create raw_recv_fd\n"); + //perror(""); + myexit(1); +} + + if(force_socket_buf) + { + if(setsockopt(raw_recv_fd, SOL_SOCKET, SO_RCVBUFFORCE, &socket_buf_size, sizeof(socket_buf_size))<0) + { + mylog(log_fatal,"SO_RCVBUFFORCE fail socket_buf_size=%d errno=%s\n",socket_buf_size,strerror(errno)); + myexit(1); + } + } + else + { + if(setsockopt(raw_recv_fd, SOL_SOCKET, SO_RCVBUF, &socket_buf_size, sizeof(socket_buf_size))<0) + { + mylog(log_fatal,"SO_RCVBUF fail socket_buf_size=%d errno=%s\n",socket_buf_size,strerror(errno)); + myexit(1); + } + } + +//IP_HDRINCL to tell the kernel that headers are included in the packet + + + +setnonblocking(raw_send_fd); //not really necessary +setnonblocking(raw_recv_fd);*/ + + return 0; } #endif #ifdef UDP2RAW_LINUX -void init_filter(int port) -{ - sock_fprog bpf; - assert(raw_ip_version==AF_INET||raw_ip_version==AF_INET6); - if(raw_mode==mode_faketcp||raw_mode==mode_udp) - { - filter_port=port; - } - if(disable_bpf_filter) return; - //if(raw_mode==mode_icmp) return ; - //code_tcp[8].k=code_tcp[10].k=port; - if(raw_mode==mode_faketcp) - { - if(raw_ip_version==AF_INET) - { - bpf.len = sizeof(code_tcp)/sizeof(code_tcp[0]); - code_tcp[code_tcp_port_index].k=port; - bpf.filter = code_tcp; - }else - { - bpf.len = sizeof(code_tcp6)/sizeof(code_tcp6[0]); - code_tcp6[code_tcp6_port_index].k=port; - bpf.filter = code_tcp6; - } - } - else if(raw_mode==mode_udp) - { - if(raw_ip_version==AF_INET) - { - bpf.len = sizeof(code_udp)/sizeof(code_udp[0]); - code_udp[code_udp_port_index].k=port; - bpf.filter = code_udp; - }else - { - bpf.len = sizeof(code_udp6)/sizeof(code_udp6[0]); - code_udp6[code_udp6_port_index].k=port; - bpf.filter = code_udp6; - } - } - else if(raw_mode==mode_icmp) - { - if(raw_ip_version==AF_INET) - { - bpf.len = sizeof(code_icmp)/sizeof(code_icmp[0]); - bpf.filter = code_icmp; - }else - { - bpf.len = sizeof(code_icmp6)/sizeof(code_icmp6[0]); - bpf.filter = code_icmp6; - } - } +void init_filter(int port) { + sock_fprog bpf; + assert(raw_ip_version == AF_INET || raw_ip_version == AF_INET6); + if (raw_mode == mode_faketcp || raw_mode == mode_udp) { + filter_port = port; + } + if (disable_bpf_filter) return; + // if(raw_mode==mode_icmp) return ; + // code_tcp[8].k=code_tcp[10].k=port; + if (raw_mode == mode_faketcp) { + if (raw_ip_version == AF_INET) { + bpf.len = sizeof(code_tcp) / sizeof(code_tcp[0]); + code_tcp[code_tcp_port_index].k = port; + bpf.filter = code_tcp; + } else { + bpf.len = sizeof(code_tcp6) / sizeof(code_tcp6[0]); + code_tcp6[code_tcp6_port_index].k = port; + bpf.filter = code_tcp6; + } + } else if (raw_mode == mode_udp) { + if (raw_ip_version == AF_INET) { + bpf.len = sizeof(code_udp) / sizeof(code_udp[0]); + code_udp[code_udp_port_index].k = port; + bpf.filter = code_udp; + } else { + bpf.len = sizeof(code_udp6) / sizeof(code_udp6[0]); + code_udp6[code_udp6_port_index].k = port; + bpf.filter = code_udp6; + } + } else if (raw_mode == mode_icmp) { + if (raw_ip_version == AF_INET) { + bpf.len = sizeof(code_icmp) / sizeof(code_icmp[0]); + bpf.filter = code_icmp; + } else { + bpf.len = sizeof(code_icmp6) / sizeof(code_icmp6[0]); + bpf.filter = code_icmp6; + } + } - int dummy; + int dummy; - int ret=setsockopt(raw_recv_fd, SOL_SOCKET, SO_DETACH_FILTER, &dummy, sizeof(dummy)); //in case i forgot to remove - if (ret != 0) - { - mylog(log_debug,"error remove fiter\n"); - //perror("filter"); - //exit(-1); - } - ret = setsockopt(raw_recv_fd, SOL_SOCKET, SO_ATTACH_FILTER, &bpf, sizeof(bpf)); - if (ret != 0) - { - mylog(log_fatal,"error set fiter\n"); - //perror("filter"); - myexit(-1); - } + int ret = setsockopt(raw_recv_fd, SOL_SOCKET, SO_DETACH_FILTER, &dummy, sizeof(dummy)); // in case i forgot to remove + if (ret != 0) { + mylog(log_debug, "error remove fiter\n"); + // perror("filter"); + // exit(-1); + } + ret = setsockopt(raw_recv_fd, SOL_SOCKET, SO_ATTACH_FILTER, &bpf, sizeof(bpf)); + if (ret != 0) { + mylog(log_fatal, "error set fiter\n"); + // perror("filter"); + myexit(-1); + } } #endif #ifdef UDP2RAW_MP -void init_filter(int port) -{ - /* - sock_fprog bpf;*/ - if(raw_mode==mode_faketcp||raw_mode==mode_udp) - { - filter_port=port; - } +void init_filter(int port) { + /* + sock_fprog bpf;*/ + if (raw_mode == mode_faketcp || raw_mode == mode_udp) { + filter_port = port; + } + char filter_exp[1000]; + if (raw_ip_version == AF_INET) { + if (raw_mode == mode_faketcp) { + sprintf(filter_exp, "ip and tcp and src %s and src port %d and dst port %d", remote_addr.get_ip(), remote_addr.get_port(), port); + } else if (raw_mode == mode_udp) { + sprintf(filter_exp, "ip and udp and src %s and src port %d and dst port %d", remote_addr.get_ip(), remote_addr.get_port(), port); + } else if (raw_mode == mode_icmp) { + sprintf(filter_exp, "ip and icmp and src %s", remote_addr.get_ip()); + } else { + mylog(log_fatal, "unknow raw mode\n"); + myexit(-1); + } + } else { + assert(raw_ip_version == AF_INET6); + if (raw_mode == mode_faketcp) { + sprintf(filter_exp, "ip6 and tcp and src %s and src port %d and dst port %d", remote_addr.get_ip(), remote_addr.get_port(), port); + } else if (raw_mode == mode_udp) { + sprintf(filter_exp, "ip6 and udp and src %s and src port %d and dst port %d", remote_addr.get_ip(), remote_addr.get_port(), port); + } else if (raw_mode == mode_icmp) { + sprintf(filter_exp, "ip6 and icmp6 and src %s", remote_addr.get_ip()); + } else { + mylog(log_fatal, "unknow raw mode\n"); + myexit(-1); + } + } - char filter_exp[1000]; + mylog(log_info, "filter expression is [%s]\n", filter_exp); - if(raw_ip_version==AF_INET) - { - if(raw_mode==mode_faketcp) - { - sprintf(filter_exp,"ip and tcp and src %s and src port %d and dst port %d",remote_addr.get_ip(),remote_addr.get_port(),port); - } - else if(raw_mode==mode_udp) - { - sprintf(filter_exp,"ip and udp and src %s and src port %d and dst port %d",remote_addr.get_ip(),remote_addr.get_port(),port); - } - else if(raw_mode==mode_icmp) - { - sprintf(filter_exp,"ip and icmp and src %s",remote_addr.get_ip()); - } - else - { - mylog(log_fatal,"unknow raw mode\n"); - myexit(-1); - } - } - else - { - assert(raw_ip_version==AF_INET6); - if(raw_mode==mode_faketcp) - { - sprintf(filter_exp,"ip6 and tcp and src %s and src port %d and dst port %d",remote_addr.get_ip(),remote_addr.get_port(),port); - } - else if(raw_mode==mode_udp) - { - sprintf(filter_exp,"ip6 and udp and src %s and src port %d and dst port %d",remote_addr.get_ip(),remote_addr.get_port(),port); - } - else if(raw_mode==mode_icmp) - { - sprintf(filter_exp,"ip6 and icmp6 and src %s",remote_addr.get_ip()); - } - else - { - mylog(log_fatal,"unknow raw mode\n"); - myexit(-1); - } - } + // pthread_mutex_lock(&pcap_mutex);//not sure if mutex is needed here - mylog(log_info,"filter expression is [%s]\n",filter_exp); + long long tmp_cnt = 0; + if (use_pcap_mutex) { + while (pthread_mutex_trylock(&pcap_mutex) != 0) { + tmp_cnt++; + pcap_breakloop(pcap_handle); + if (tmp_cnt == 100) { + mylog(log_warn, "%lld attempts of pcap_breakloop()\n", tmp_cnt); + } + if (tmp_cnt % 1000 == 0) { + mylog(log_warn, "%lld attempts of pcap_breakloop()\n", tmp_cnt); + if (tmp_cnt > 5000) { + mylog(log_fatal, "we might have already run into a deadlock\n"); + } + } + ev_sleep(0.001); + } + mylog(log_info, "breakloop() succeed after %lld attempt(s)\n", tmp_cnt); + } - //pthread_mutex_lock(&pcap_mutex);//not sure if mutex is needed here + if (1) { + int ret = pcap_setdirection(pcap_handle, PCAP_D_IN); + if (ret != 0) mylog(log_debug, "pcap_setdirection(pcap_handle,PCAP_D_IN) failed with value %d, %s\n", ret, pcap_geterr(pcap_handle)); + } - long long tmp_cnt=0; - if(use_pcap_mutex) - { - while(pthread_mutex_trylock(&pcap_mutex)!=0) - { - tmp_cnt++; - pcap_breakloop(pcap_handle); - if(tmp_cnt==100) - { - mylog(log_warn,"%lld attempts of pcap_breakloop()\n", tmp_cnt); - } - if(tmp_cnt%1000==0) - { - mylog(log_warn,"%lld attempts of pcap_breakloop()\n", tmp_cnt); - if(tmp_cnt>5000) - { - mylog(log_fatal,"we might have already run into a deadlock\n"); - } - } - ev_sleep(0.001); - } - mylog(log_info,"breakloop() succeed after %lld attempt(s)\n", tmp_cnt); - } + assert(g_filter_compile_cnt != 0); + pcap_freecode(&g_filter); - if(1) - { - int ret=pcap_setdirection(pcap_handle,PCAP_D_IN); - if(ret!=0) mylog(log_debug,"pcap_setdirection(pcap_handle,PCAP_D_IN) failed with value %d, %s\n",ret,pcap_geterr(pcap_handle)); - } + if (pcap_compile(pcap_handle, &g_filter, filter_exp, 0, PCAP_NETMASK_UNKNOWN) == -1) { + mylog(log_fatal, "Bad filter - %s\n", pcap_geterr(pcap_handle)); + myexit(-1); + } + g_filter_compile_cnt++; - assert(g_filter_compile_cnt!=0); - pcap_freecode(&g_filter); + if (pcap_setfilter(pcap_handle, &g_filter) == -1) { + mylog(log_fatal, "Error setting filter - %s\n", pcap_geterr(pcap_handle)); + myexit(-1); + } - if (pcap_compile(pcap_handle, &g_filter, filter_exp, 0, PCAP_NETMASK_UNKNOWN ) == -1) { - mylog(log_fatal,"Bad filter - %s\n", pcap_geterr(pcap_handle)); - myexit(-1); - } - g_filter_compile_cnt++; + if (use_pcap_mutex) pthread_mutex_unlock(&pcap_mutex); + /* + if(disable_bpf_filter) return; + //if(raw_mode==mode_icmp) return ; + //code_tcp[8].k=code_tcp[10].k=port; + if(raw_mode==mode_faketcp) + { + bpf.len = sizeof(code_tcp)/sizeof(code_tcp[0]); + code_tcp[code_tcp_port_index].k=port; + bpf.filter = code_tcp; + } + else if(raw_mode==mode_udp) + { + bpf.len = sizeof(code_udp)/sizeof(code_udp[0]); + code_udp[code_udp_port_index].k=port; + bpf.filter = code_udp; + } + else if(raw_mode==mode_icmp) + { + bpf.len = sizeof(code_icmp)/sizeof(code_icmp[0]); + bpf.filter = code_icmp; + } - if (pcap_setfilter(pcap_handle, &g_filter) == -1) - { - mylog(log_fatal,"Error setting filter - %s\n", pcap_geterr(pcap_handle)); - myexit(-1); - } + int dummy; - - if(use_pcap_mutex) pthread_mutex_unlock(&pcap_mutex); - /* - if(disable_bpf_filter) return; - //if(raw_mode==mode_icmp) return ; - //code_tcp[8].k=code_tcp[10].k=port; - if(raw_mode==mode_faketcp) - { - bpf.len = sizeof(code_tcp)/sizeof(code_tcp[0]); - code_tcp[code_tcp_port_index].k=port; - bpf.filter = code_tcp; - } - else if(raw_mode==mode_udp) - { - bpf.len = sizeof(code_udp)/sizeof(code_udp[0]); - code_udp[code_udp_port_index].k=port; - bpf.filter = code_udp; - } - else if(raw_mode==mode_icmp) - { - bpf.len = sizeof(code_icmp)/sizeof(code_icmp[0]); - bpf.filter = code_icmp; - } - - int dummy; - - int ret=setsockopt(raw_recv_fd, SOL_SOCKET, SO_DETACH_FILTER, &dummy, sizeof(dummy)); //in case i forgot to remove - if (ret != 0) - { - mylog(log_debug,"error remove fiter\n"); - //perror("filter"); - //exit(-1); - } - ret = setsockopt(raw_recv_fd, SOL_SOCKET, SO_ATTACH_FILTER, &bpf, sizeof(bpf)); - if (ret != 0) - { - mylog(log_fatal,"error set fiter\n"); - //perror("filter"); - myexit(-1); - }*/ + int ret=setsockopt(raw_recv_fd, SOL_SOCKET, SO_DETACH_FILTER, &dummy, sizeof(dummy)); //in case i forgot to remove + if (ret != 0) + { + mylog(log_debug,"error remove fiter\n"); + //perror("filter"); + //exit(-1); + } + ret = setsockopt(raw_recv_fd, SOL_SOCKET, SO_ATTACH_FILTER, &bpf, sizeof(bpf)); + if (ret != 0) + { + mylog(log_fatal,"error set fiter\n"); + //perror("filter"); + myexit(-1); + }*/ } #endif -void remove_filter() -{ - filter_port=0; +void remove_filter() { + filter_port = 0; #ifdef UDP2RAW_LINUX - int dummy; - int ret=setsockopt(raw_recv_fd, SOL_SOCKET, SO_DETACH_FILTER, &dummy, sizeof(dummy)); - if (ret != 0) - { - mylog(log_debug,"error remove fiter\n"); - //perror("filter"); - //exit(-1); - } + int dummy; + int ret = setsockopt(raw_recv_fd, SOL_SOCKET, SO_DETACH_FILTER, &dummy, sizeof(dummy)); + if (ret != 0) { + mylog(log_debug, "error remove fiter\n"); + // perror("filter"); + // exit(-1); + } #endif } -int init_ifindex(const char * if_name,int fd,int &index) -{ +int init_ifindex(const char *if_name, int fd, int &index) { #ifdef UDP2RAW_LINUX - struct ifreq ifr; - size_t if_name_len=strlen(if_name); - if (if_name_len find_route_entry(const vector &route_info_vec,u32_t ip) -{ - vector res; - for(u32_t i=0;i<=32;i++) - { - u32_t mask=0xffffffff; - //mask >>=i; - //if(i==32) mask=0; //why 0xffffffff>>32 equals 0xffffffff?? +int dest_idx = 1; +int gw_idx = 2; +int if_idx = 0; +int mask_idx = 7; +int flag_idx = 3; +vector find_route_entry(const vector &route_info_vec, u32_t ip) { + vector res; + for (u32_t i = 0; i <= 32; i++) { + u32_t mask = 0xffffffff; + // mask >>=i; + // if(i==32) mask=0; //why 0xffffffff>>32 equals 0xffffffff?? - mask <<=i; - if(i==32) mask=0; - log_bare(log_debug,"(mask:%x)",mask); - for(u32_t j=0;j>",i,j); - if((info.dest&mask)==(ip&mask)) - { - log_bare(log_debug,"found!"); - res.push_back(j); - } - } - if(res.size()!=0) - { - return res; - } - } - return res; + mask <<= i; + if (i == 32) mask = 0; + log_bare(log_debug, "(mask:%x)", mask); + for (u32_t j = 0; j < route_info_vec.size(); j++) { + const route_info_t &info = route_info_vec[j]; + if (info.mask != mask) + continue; + log_bare(log_debug, "<<%d,%d>>", i, j); + if ((info.dest & mask) == (ip & mask)) { + log_bare(log_debug, "found!"); + res.push_back(j); + } + } + if (res.size() != 0) { + return res; + } + } + return res; } -int find_direct_dest(const vector &route_info_vec,u32_t ip,u32_t &dest_ip,string &if_name) -{ - vector res; - for(int i=0;i<1000;i++) - { - res=find_route_entry(route_info_vec,ip); - log_bare(log_debug,"",(u32_t)res.size()); - if(res.size()==0) - { - mylog(log_error,"cant find route entry\n"); - return -1; - } - if(res.size()>1) - { - mylog(log_error,"found duplicated entries\n"); - return -1; - } - if((route_info_vec[res[0]].flag&2)==0) - { - dest_ip=ip; - if_name=route_info_vec[res[0]].if_name; - return 0; - } - else - { - ip=route_info_vec[res[0]].gw; - } - } - mylog(log_error,"dead loop in find_direct_dest\n"); - return -1; +int find_direct_dest(const vector &route_info_vec, u32_t ip, u32_t &dest_ip, string &if_name) { + vector res; + for (int i = 0; i < 1000; i++) { + res = find_route_entry(route_info_vec, ip); + log_bare(log_debug, "", (u32_t)res.size()); + if (res.size() == 0) { + mylog(log_error, "cant find route entry\n"); + return -1; + } + if (res.size() > 1) { + mylog(log_error, "found duplicated entries\n"); + return -1; + } + if ((route_info_vec[res[0]].flag & 2) == 0) { + dest_ip = ip; + if_name = route_info_vec[res[0]].if_name; + return 0; + } else { + ip = route_info_vec[res[0]].gw; + } + } + mylog(log_error, "dead loop in find_direct_dest\n"); + return -1; } -struct arp_info_t -{ - u32_t ip; - string hw; - string if_name; +struct arp_info_t { + u32_t ip; + string hw; + string if_name; }; -int arp_ip_idx=0; -int arp_hw_idx=3; -int arp_if_idx=5; +int arp_ip_idx = 0; +int arp_hw_idx = 3; +int arp_if_idx = 5; - -int find_arp(const vector &arp_info_vec,u32_t ip,string if_name,string &hw) -{ - int pos=-1; - int count=0; - for(u32_t i=0;i1) - { - mylog(log_error,"find multiple arp entry for %s %s\n",my_ntoa(ip),if_name.c_str()); - return -1; - } - hw=arp_info_vec[pos].hw; - return 0; +int find_arp(const vector &arp_info_vec, u32_t ip, string if_name, string &hw) { + int pos = -1; + int count = 0; + for (u32_t i = 0; i < arp_info_vec.size(); i++) { + const arp_info_t &info = arp_info_vec[i]; + if (info.if_name != if_name) continue; + if (info.ip == ip) { + count++; + pos = i; + } + } + if (count == 0) { + // mylog(log_warn,"cant find arp entry for %s %s,using 00:00:00:00:00:00\n",my_ntoa(ip),if_name.c_str()); + // hw="00:00:00:00:00:00"; + mylog(log_error, "cant find arp entry for %s %s\n", my_ntoa(ip), if_name.c_str()); + return -1; + } + if (count > 1) { + mylog(log_error, "find multiple arp entry for %s %s\n", my_ntoa(ip), if_name.c_str()); + return -1; + } + hw = arp_info_vec[pos].hw; + return 0; } -int find_lower_level_info(u32_t ip,u32_t &dest_ip,string &if_name,string &hw) -{ - ip=htonl(ip); - if(ip==htonl(inet_addr("127.0.0.1"))) - { - dest_ip=ntohl(ip); - if_name="lo"; - hw="00:00:00:00:00:00"; - return 0; - } +int find_lower_level_info(u32_t ip, u32_t &dest_ip, string &if_name, string &hw) { + ip = htonl(ip); + if (ip == htonl(inet_addr("127.0.0.1"))) { + dest_ip = ntohl(ip); + if_name = "lo"; + hw = "00:00:00:00:00:00"; + return 0; + } - string route_file; - if(read_file("/proc/net/route",route_file)!=0) return -1; - string arp_file; - if(read_file("/proc/net/arp",arp_file)!=0) return -1; + string route_file; + if (read_file("/proc/net/route", route_file) != 0) return -1; + string arp_file; + if (read_file("/proc/net/arp", arp_file) != 0) return -1; - log_bare(log_debug,"/proc/net/route:<<%s>>\n",route_file.c_str()); - log_bare(log_debug,"/proc/net/arp:<<%s>>\n",route_file.c_str()); + log_bare(log_debug, "/proc/net/route:<<%s>>\n", route_file.c_str()); + log_bare(log_debug, "/proc/net/arp:<<%s>>\n", route_file.c_str()); - auto route_vec2=string_to_vec2(route_file.c_str()); - vector route_info_vec; - for(u32_t i=1;i",(u32_t)route_vec2[i].size()); - if(route_vec2[i].size()!=11) - { - mylog(log_error,"route coloum %d !=11 \n",int(route_vec2[i].size())); - return -1; - } - route_info_t tmp; - tmp.if_name=route_vec2[i][if_idx]; - if(hex_to_u32_with_endian(route_vec2[i][dest_idx],tmp.dest)!=0) return -1; - if(hex_to_u32_with_endian(route_vec2[i][gw_idx],tmp.gw)!=0) return -1; - if(hex_to_u32_with_endian(route_vec2[i][mask_idx],tmp.mask)!=0) return -1; - if(hex_to_u32(route_vec2[i][flag_idx],tmp.flag)!=0)return -1; - route_info_vec.push_back(tmp); - for(u32_t j=0;j",route_vec2[i][j].c_str()); - } - log_bare(log_debug,"%s dest:%x mask:%x gw:%x flag:%x",tmp.if_name.c_str(),tmp.dest,tmp.mask,tmp.gw,tmp.flag); - log_bare(log_debug,"\n"); - } + auto route_vec2 = string_to_vec2(route_file.c_str()); + vector route_info_vec; + for (u32_t i = 1; i < route_vec2.size(); i++) { + log_bare(log_debug, "", (u32_t)route_vec2[i].size()); + if (route_vec2[i].size() != 11) { + mylog(log_error, "route coloum %d !=11 \n", int(route_vec2[i].size())); + return -1; + } + route_info_t tmp; + tmp.if_name = route_vec2[i][if_idx]; + if (hex_to_u32_with_endian(route_vec2[i][dest_idx], tmp.dest) != 0) return -1; + if (hex_to_u32_with_endian(route_vec2[i][gw_idx], tmp.gw) != 0) return -1; + if (hex_to_u32_with_endian(route_vec2[i][mask_idx], tmp.mask) != 0) return -1; + if (hex_to_u32(route_vec2[i][flag_idx], tmp.flag) != 0) return -1; + route_info_vec.push_back(tmp); + for (u32_t j = 0; j < route_vec2[i].size(); j++) { + log_bare(log_debug, "<%s>", route_vec2[i][j].c_str()); + } + log_bare(log_debug, "%s dest:%x mask:%x gw:%x flag:%x", tmp.if_name.c_str(), tmp.dest, tmp.mask, tmp.gw, tmp.flag); + log_bare(log_debug, "\n"); + } - if(find_direct_dest(route_info_vec,ip,dest_ip,if_name)!=0) - { - mylog(log_error,"find_direct_dest failed for ip %s\n",my_ntoa(ntohl(ip))); - return -1; - } + if (find_direct_dest(route_info_vec, ip, dest_ip, if_name) != 0) { + mylog(log_error, "find_direct_dest failed for ip %s\n", my_ntoa(ntohl(ip))); + return -1; + } + log_bare(log_debug, "========\n"); + auto arp_vec2 = string_to_vec2(arp_file.c_str()); + vector arp_info_vec; + for (u32_t i = 1; i < arp_vec2.size(); i++) { + log_bare(log_debug, "<>", (int)arp_vec2[i].size()); - log_bare(log_debug,"========\n"); - auto arp_vec2=string_to_vec2(arp_file.c_str()); - vector arp_info_vec; - for(u32_t i=1;i>",(int)arp_vec2[i].size()); + for (u32_t j = 0; j < arp_vec2[i].size(); j++) { + log_bare(log_debug, "<%s>", arp_vec2[i][j].c_str()); + } + if (arp_vec2[i].size() != 6) { + mylog(log_error, "arp coloum %d !=11 \n", int(arp_vec2[i].size())); + return -1; + } + arp_info_t tmp; + tmp.if_name = arp_vec2[i][arp_if_idx]; + tmp.hw = arp_vec2[i][arp_hw_idx]; + tmp.ip = htonl(inet_addr(arp_vec2[i][arp_ip_idx].c_str())); + arp_info_vec.push_back(tmp); + log_bare(log_debug, "\n"); + } + if (!interface_has_arp(if_name.c_str())) { + mylog(log_info, "%s is a noarp interface,using 00:00:00:00:00:00\n", if_name.c_str()); + hw = "00:00:00:00:00:00"; + } else if (find_arp(arp_info_vec, dest_ip, if_name, hw) != 0) { + mylog(log_error, "find_arp failed for dest_ip %s ,if_name %s\n", my_ntoa(ntohl(ip)), if_name.c_str()); + return -1; + } + // printf("%s\n",hw.c_str()); - for(u32_t j=0;j",arp_vec2[i][j].c_str()); - } - if(arp_vec2[i].size()!=6) - { - mylog(log_error,"arp coloum %d !=11 \n",int(arp_vec2[i].size())); - return -1; - } - arp_info_t tmp; - tmp.if_name=arp_vec2[i][arp_if_idx]; - tmp.hw=arp_vec2[i][arp_hw_idx]; - tmp.ip=htonl(inet_addr(arp_vec2[i][arp_ip_idx].c_str())); - arp_info_vec.push_back(tmp); - log_bare(log_debug,"\n"); - } - if(!interface_has_arp(if_name.c_str())) - { - mylog(log_info,"%s is a noarp interface,using 00:00:00:00:00:00\n",if_name.c_str()); - hw="00:00:00:00:00:00"; - } - else if(find_arp(arp_info_vec,dest_ip,if_name,hw)!=0) - { - mylog(log_error,"find_arp failed for dest_ip %s ,if_name %s\n",my_ntoa(ntohl(ip)),if_name.c_str()); - return -1; - } - //printf("%s\n",hw.c_str()); - - dest_ip=ntohl(dest_ip); - return 0; + dest_ip = ntohl(dest_ip); + return 0; } #endif #ifdef UDP2RAW_LINUX -int send_raw_packet(raw_info_t &raw_info,const char * packet,int len) -{ - const packet_info_t &send_info=raw_info.send_info; - const packet_info_t &recv_info=raw_info.recv_info; +int send_raw_packet(raw_info_t &raw_info, const char *packet, int len) { + const packet_info_t &send_info = raw_info.send_info; + const packet_info_t &recv_info = raw_info.recv_info; int ret; - if(lower_level==0) - { - if(raw_ip_version==AF_INET) - { - struct sockaddr_in sin={0}; - sin.sin_family = raw_ip_version; - //sin.sin_port = htons(info.dst_port); //dont need this - sin.sin_addr.s_addr = send_info.new_dst_ip.v4; - ret = sendto(raw_send_fd, packet, len , 0, (struct sockaddr *) &sin, sizeof (sin)); - } - else if(raw_ip_version==AF_INET6) - { - struct sockaddr_in6 sin={0}; - sin.sin6_family = raw_ip_version; - //sin.sin_port = htons(info.dst_port); //dont need this - sin.sin6_addr = send_info.new_dst_ip.v6; - ret = sendto(raw_send_fd, packet, len , 0, (struct sockaddr *) &sin, sizeof (sin)); - }else - { - assert(0==1); - } + if (lower_level == 0) { + if (raw_ip_version == AF_INET) { + struct sockaddr_in sin = {0}; + sin.sin_family = raw_ip_version; + // sin.sin_port = htons(info.dst_port); //dont need this + sin.sin_addr.s_addr = send_info.new_dst_ip.v4; + ret = sendto(raw_send_fd, packet, len, 0, (struct sockaddr *)&sin, sizeof(sin)); + } else if (raw_ip_version == AF_INET6) { + struct sockaddr_in6 sin = {0}; + sin.sin6_family = raw_ip_version; + // sin.sin_port = htons(info.dst_port); //dont need this + sin.sin6_addr = send_info.new_dst_ip.v6; + ret = sendto(raw_send_fd, packet, len, 0, (struct sockaddr *)&sin, sizeof(sin)); + } else { + assert(0 == 1); + } + } else { + struct sockaddr_ll addr = {0}; //={0} not necessary + memcpy(&addr, &send_info.addr_ll, sizeof(addr)); + + ret = sendto(raw_send_fd, packet, len, 0, (struct sockaddr *)&addr, sizeof(addr)); } - else - { - - struct sockaddr_ll addr={0}; //={0} not necessary - memcpy(&addr,&send_info.addr_ll,sizeof(addr)); - - ret = sendto(raw_send_fd, packet, len , 0, (struct sockaddr *) &addr, sizeof (addr)); - } - if(ret==-1) - { - - mylog(log_trace,"sendto failed\n"); - //perror("why?"); - return -1; - } - else - { - //mylog(log_info,"sendto succ\n"); + if (ret == -1) { + mylog(log_trace, "sendto failed\n"); + // perror("why?"); + return -1; + } else { + // mylog(log_info,"sendto succ\n"); } return 0; } @@ -1262,764 +1102,666 @@ int send_raw_packet(raw_info_t &raw_info,const char * packet,int len) #ifdef UDP2RAW_MP -int send_raw_packet(raw_info_t &raw_info,const char * packet,int len) -{ - const packet_info_t &send_info=raw_info.send_info; - const packet_info_t &recv_info=raw_info.recv_info; +int send_raw_packet(raw_info_t &raw_info, const char *packet, int len) { + const packet_info_t &send_info = raw_info.send_info; + const packet_info_t &recv_info = raw_info.recv_info; - if(! send_with_pcap) - { + if (!send_with_pcap) { #ifndef NO_LIBNET - //g_ptag=libnet_build_ipv4(ip_tot_len, iph->tos, ntohs(iph->id), ntohs(iph->frag_off), - // iph->ttl , iph->protocol , iph->check , iph->saddr, iph->daddr, - // (const unsigned char *)payload, payloadlen, libnet_handle, g_ptag); + // g_ptag=libnet_build_ipv4(ip_tot_len, iph->tos, ntohs(iph->id), ntohs(iph->frag_off), + // iph->ttl , iph->protocol , iph->check , iph->saddr, iph->daddr, + // (const unsigned char *)payload, payloadlen, libnet_handle, g_ptag); - //assert(g_ptag!=-1 &&g_ptag!=0); + // assert(g_ptag!=-1 &&g_ptag!=0); - //int ret; - //ret= libnet_write(libnet_handle); + // int ret; + // ret= libnet_write(libnet_handle); - //assert(ret!=-1); + // assert(ret!=-1); - - //iph->tot_len=htons(ip_tot_len); - //iph->check =csum ((unsigned short *) send_raw_ip_buf, iph->ihl*4); - if(raw_ip_version==AF_INET) - { - libnet_write_raw_ipv4(libnet_handle,(const unsigned char *)packet,len); //todo, this api is marked as internal, maybe we should avoid using it. - } - else - { - assert(raw_ip_version==AF_INET6); - libnet_write_raw_ipv6(libnet_handle,(const unsigned char *)packet,len); - } + // iph->tot_len=htons(ip_tot_len); + // iph->check =csum ((unsigned short *) send_raw_ip_buf, iph->ihl*4); + if (raw_ip_version == AF_INET) { + libnet_write_raw_ipv4(libnet_handle, (const unsigned char *)packet, len); // todo, this api is marked as internal, maybe we should avoid using it. + } else { + assert(raw_ip_version == AF_INET6); + libnet_write_raw_ipv6(libnet_handle, (const unsigned char *)packet, len); + } #endif - } - else - { - char buf[buf_len]; - assert(pcap_header_captured==1); - assert(pcap_link_header_len!=-1); - memcpy(buf,pcap_header_buf,pcap_link_header_len); - memcpy(buf+pcap_link_header_len,packet,len); - //pthread_mutex_lock(&pcap_mutex); looks like this is not necessary, and it harms performance - int ret=pcap_sendpacket(pcap_handle,(const unsigned char *)buf,len+pcap_link_header_len); - if(ret!=0) - { - mylog(log_warn,"pcap_sendpcaket failed with vaule %d,%s, data_len=%d\n",ret,pcap_geterr(pcap_handle),len); - //pthread_mutex_unlock(&pcap_mutex); - //myexit(-1); - } - //pthread_mutex_unlock(&pcap_mutex); - /* - unsigned char *p=(unsigned char *)send_raw_ip_buf0; - for(int i=0;i",int(p[i])); - printf("\n"); - assert(pcap_sendpacket(pcap_handle,(const unsigned char *)pcap_header_buf,cap_len)==0); - p=(unsigned char *)pcap_header_buf; - for(int i=0;i",int(p[i])); - printf("\n"); - printf("pcap send!\n");*/ + } else { + char buf[buf_len]; + assert(pcap_header_captured == 1); + assert(pcap_link_header_len != -1); + memcpy(buf, pcap_header_buf, pcap_link_header_len); + memcpy(buf + pcap_link_header_len, packet, len); + // pthread_mutex_lock(&pcap_mutex); looks like this is not necessary, and it harms performance + int ret = pcap_sendpacket(pcap_handle, (const unsigned char *)buf, len + pcap_link_header_len); + if (ret != 0) { + mylog(log_warn, "pcap_sendpcaket failed with vaule %d,%s, data_len=%d\n", ret, pcap_geterr(pcap_handle), len); + // pthread_mutex_unlock(&pcap_mutex); + // myexit(-1); + } + // pthread_mutex_unlock(&pcap_mutex); + /* +unsigned char *p=(unsigned char *)send_raw_ip_buf0; +for(int i=0;i",int(p[i])); +printf("\n"); +assert(pcap_sendpacket(pcap_handle,(const unsigned char *)pcap_header_buf,cap_len)==0); +p=(unsigned char *)pcap_header_buf; +for(int i=0;i",int(p[i])); +printf("\n"); +printf("pcap send!\n");*/ } return 0; } #endif -int send_raw_ip(raw_info_t &raw_info,const char * payload,int payloadlen) -{ - const packet_info_t &send_info=raw_info.send_info; - const packet_info_t &recv_info=raw_info.recv_info; - char send_raw_ip_buf[buf_len]; +int send_raw_ip(raw_info_t &raw_info, const char *payload, int payloadlen) { + const packet_info_t &send_info = raw_info.send_info; + const packet_info_t &recv_info = raw_info.recv_info; + char send_raw_ip_buf[buf_len]; - if(raw_info.disabled) - { - mylog(log_debug,"[%s,%d]connection disabled, no packet will be sent\n",recv_info.new_src_ip.get_str1(),recv_info.src_port); - assert(max_rst_allowed>=0); - return 0; - } + if (raw_info.disabled) { + mylog(log_debug, "[%s,%d]connection disabled, no packet will be sent\n", recv_info.new_src_ip.get_str1(), recv_info.src_port); + assert(max_rst_allowed >= 0); + return 0; + } uint16_t ip_tot_len; - if(raw_ip_version==AF_INET) - { - struct my_iphdr *iph = (struct my_iphdr *) send_raw_ip_buf; - memset(iph,0,sizeof(my_iphdr)); + if (raw_ip_version == AF_INET) { + struct my_iphdr *iph = (struct my_iphdr *)send_raw_ip_buf; + memset(iph, 0, sizeof(my_iphdr)); - iph->ihl = sizeof(my_iphdr)/4; //we dont use ip options,so the length is just sizeof(iphdr) + iph->ihl = sizeof(my_iphdr) / 4; // we dont use ip options,so the length is just sizeof(iphdr) iph->version = 4; iph->tos = 0; - if(lower_level) - { - //iph->id=0; - iph->id = htons (g_ip_id_counter++); //Id of this packet - } - else//no need to else? - { - iph->id = htons (g_ip_id_counter++); //Id of this packet - //iph->id = 0; //Id of this packet ,kernel will auto fill this if id is zero ,or really?????// todo //seems like there is a problem - } + if (lower_level) { + // iph->id=0; + iph->id = htons(g_ip_id_counter++); // Id of this packet + } else // no need to else? + { + iph->id = htons(g_ip_id_counter++); // Id of this packet + // iph->id = 0; //Id of this packet ,kernel will auto fill this if id is zero ,or really?????// todo //seems like there is a problem + } - iph->frag_off = htons(0x4000); //DF set,others are zero - // iph->frag_off = htons(0x0000); //DF set,others are zero - iph->ttl = (unsigned char)ttl_value; - iph->protocol = send_info.protocol; - iph->check = 0; //Set to 0 before calculating checksum - iph->saddr = send_info.new_src_ip.v4; //Spoof the source ip address - iph->daddr = send_info.new_dst_ip.v4; + iph->frag_off = htons(0x4000); // DF set,others are zero + // iph->frag_off = htons(0x0000); //DF set,others are zero + iph->ttl = (unsigned char)ttl_value; + iph->protocol = send_info.protocol; + iph->check = 0; // Set to 0 before calculating checksum + iph->saddr = send_info.new_src_ip.v4; // Spoof the source ip address + iph->daddr = send_info.new_dst_ip.v4; - ip_tot_len=sizeof (struct my_iphdr)+payloadlen; + ip_tot_len = sizeof(struct my_iphdr) + payloadlen; #ifdef UDP2RAW_LINUX - if(lower_level)iph->tot_len = htons(ip_tot_len); //this is not necessary ,kernel will always auto fill this //http://man7.org/linux/man-pages/man7/raw.7.html - else - iph->tot_len = 0; + if (lower_level) + iph->tot_len = htons(ip_tot_len); // this is not necessary ,kernel will always auto fill this //http://man7.org/linux/man-pages/man7/raw.7.html + else + iph->tot_len = 0; #endif #ifdef UDP2RAW_MP - iph->tot_len = htons(ip_tot_len);//always fill for mp version + iph->tot_len = htons(ip_tot_len); // always fill for mp version #endif - memcpy(send_raw_ip_buf+sizeof(my_iphdr) , payload, payloadlen); + memcpy(send_raw_ip_buf + sizeof(my_iphdr), payload, payloadlen); #ifdef UDP2RAW_LINUX - if(lower_level) iph->check = - csum ((unsigned short *) send_raw_ip_buf, iph->ihl*4); //this is not necessary ,kernel will always auto fill this - else - iph->check=0; + if (lower_level) + iph->check = + csum((unsigned short *)send_raw_ip_buf, iph->ihl * 4); // this is not necessary ,kernel will always auto fill this + else + iph->check = 0; #endif #ifdef UDP2RAW_MP - iph->check =csum((unsigned short *) send_raw_ip_buf, iph->ihl*4);//always cal checksum for mp version + iph->check = csum((unsigned short *)send_raw_ip_buf, iph->ihl * 4); // always cal checksum for mp version #endif - } - else - { - assert(raw_ip_version==AF_INET6); + } else { + assert(raw_ip_version == AF_INET6); - struct my_ip6hdr *ip6h = (struct my_ip6hdr *) send_raw_ip_buf; - memset(ip6h,0,sizeof(my_ip6hdr)); + struct my_ip6hdr *ip6h = (struct my_ip6hdr *)send_raw_ip_buf; + memset(ip6h, 0, sizeof(my_ip6hdr)); - ip6h->version=6; - ip6h->payload_len=htons(payloadlen); - ip6h->next_header=send_info.protocol; - ip6h->hop_limit=(unsigned char)ttl_value; - ip6h->src=send_info.new_src_ip.v6; - ip6h->dst=send_info.new_dst_ip.v6; + ip6h->version = 6; + ip6h->payload_len = htons(payloadlen); + ip6h->next_header = send_info.protocol; + ip6h->hop_limit = (unsigned char)ttl_value; + ip6h->src = send_info.new_src_ip.v6; + ip6h->dst = send_info.new_dst_ip.v6; - ip_tot_len=sizeof (struct my_ip6hdr)+payloadlen; - memcpy(send_raw_ip_buf+sizeof(my_ip6hdr) , payload, payloadlen); + ip_tot_len = sizeof(struct my_ip6hdr) + payloadlen; + memcpy(send_raw_ip_buf + sizeof(my_ip6hdr), payload, payloadlen); } - - return send_raw_packet(raw_info,send_raw_ip_buf,ip_tot_len); + return send_raw_packet(raw_info, send_raw_ip_buf, ip_tot_len); } -int pre_recv_raw_packet() -{ +int pre_recv_raw_packet() { #ifdef UDP2RAW_LINUX - assert(g_packet_buf_cnt==0); + assert(g_packet_buf_cnt == 0); - g_sockaddr_len=sizeof(g_sockaddr.ll); - g_packet_buf_len = recvfrom(raw_recv_fd, g_packet_buf, huge_data_len+1, 0 ,(sockaddr*)&g_sockaddr , &g_sockaddr_len); - //assert(g_sockaddr_len==sizeof(g_sockaddr.ll)); //g_sockaddr_len=18, sizeof(g_sockaddr.ll)=20, why its not equal? maybe its bc sll_halen is 6? + g_sockaddr_len = sizeof(g_sockaddr.ll); + g_packet_buf_len = recvfrom(raw_recv_fd, g_packet_buf, huge_data_len + 1, 0, (sockaddr *)&g_sockaddr, &g_sockaddr_len); + // assert(g_sockaddr_len==sizeof(g_sockaddr.ll)); //g_sockaddr_len=18, sizeof(g_sockaddr.ll)=20, why its not equal? maybe its bc sll_halen is 6? - //assert(g_addr_ll_size==sizeof(g_addr_ll)); + // assert(g_addr_ll_size==sizeof(g_addr_ll)); - if(g_packet_buf_len==huge_data_len+1) - { - if(g_fix_gro==0) - { - mylog(log_warn,"huge packet, data_len %d > %d,dropped\n",g_packet_buf_len,huge_data_len); - return -1; - } - else - { - mylog(log_debug,"huge packet, data_len %d > %d,not dropped\n",g_packet_buf_len,huge_data_len); - g_packet_buf_len=huge_data_len; - } - } + if (g_packet_buf_len == huge_data_len + 1) { + if (g_fix_gro == 0) { + mylog(log_warn, "huge packet, data_len %d > %d,dropped\n", g_packet_buf_len, huge_data_len); + return -1; + } else { + mylog(log_debug, "huge packet, data_len %d > %d,not dropped\n", g_packet_buf_len, huge_data_len); + g_packet_buf_len = huge_data_len; + } + } - if(g_packet_buf_len>= max_data_len+1) - { - if(g_fix_gro==0) - { + if (g_packet_buf_len >= max_data_len + 1) { + if (g_fix_gro == 0) { mylog(log_warn, "huge packet, data_len %d > %d(max_data_len) dropped, maybe you need to turn down mtu at upper level, or you may take a look at --fix-gro\n", g_packet_buf_len, max_data_len); return -1; - } - else - { + } else { mylog(log_debug, "huge packet, data_len %d > %d(max_data_len) not dropped\n", g_packet_buf_len, max_data_len); - //return -1; + // return -1; } - } - if(g_packet_buf_len<0) - { - mylog(log_trace,"recv_len %d\n",g_packet_buf_len); - return -1; - } - g_packet_buf_cnt++; + if (g_packet_buf_len < 0) { + mylog(log_trace, "recv_len %d\n", g_packet_buf_len); + return -1; + } + g_packet_buf_cnt++; #endif - return 0; + return 0; } -int discard_raw_packet() -{ - assert(g_packet_buf_cnt==1); - g_packet_buf_cnt--; - return 0; +int discard_raw_packet() { + assert(g_packet_buf_cnt == 1); + g_packet_buf_cnt--; + return 0; } #ifdef UDP2RAW_LINUX -int recv_raw_packet(char * &packet,int &len,int peek) -{ - assert(g_packet_buf_cnt==1); - if(!peek) - g_packet_buf_cnt--; +int recv_raw_packet(char *&packet, int &len, int peek) { + assert(g_packet_buf_cnt == 1); + if (!peek) + g_packet_buf_cnt--; - if(g_packet_buf_lenversion!=4) - { - mylog(log_trace,"expect ipv4 packet, but got something else: %02x\n",iph->version); - return -1; - } - if(raw_packet_len<(int)sizeof(my_iphdr)) - { - mylog(log_trace,"raw_packet_lenversion!=6) - { - mylog(log_trace,"expect ipv6 packet, but got something else: %02x\n",ip6h->version); - return -1; - } - if(raw_packet_len<(int)sizeof(my_ip6hdr)) - { - mylog(log_trace,"raw_packet_lenversion != 4) { + mylog(log_trace, "expect ipv4 packet, but got something else: %02x\n", iph->version); + return -1; + } + if (raw_packet_len < (int)sizeof(my_iphdr)) { + mylog(log_trace, "raw_packet_lenversion != 6) { + mylog(log_trace, "expect ipv6 packet, but got something else: %02x\n", ip6h->version); + return -1; + } + if (raw_packet_len < (int)sizeof(my_ip6hdr)) { + mylog(log_trace, "raw_packet_lensaddr; - recv_info.new_dst_ip.v4=iph->daddr; - recv_info.protocol=iph->protocol; - iphdrlen =iph->ihl*4; - ip_len=ntohs(iph->tot_len); - } - else - { - //todo flow id - assert(raw_ip_version==AF_INET6); - recv_info.new_src_ip.v6=ip6h->src; - recv_info.new_dst_ip.v6=ip6h->dst; - iphdrlen=40; - recv_info.protocol=ip6h->next_header; //todo handle extension headers; - ip_len=ntohs(ip6h->payload_len)+iphdrlen; - } - - if(bind_addr_used && !recv_info.new_dst_ip.equal(bind_addr)) - { - mylog(log_trace,"bind adress doenst match %s %s, dropped\n",recv_info.new_dst_ip.get_str1(), bind_addr.get_str2()); - //printf(" bind adress doenst match, dropped\n"); - return -1; - } - - //if (!(iph->ihl > 0 && iph->ihl <=60)) { - // mylog(log_trace,"iph ihl error\n"); - // return -1; - // } - - - if(raw_packet_len saddr; + recv_info.new_dst_ip.v4 = iph->daddr; + recv_info.protocol = iph->protocol; + iphdrlen = iph->ihl * 4; + ip_len = ntohs(iph->tot_len); + } else { + // todo flow id + assert(raw_ip_version == AF_INET6); + recv_info.new_src_ip.v6 = ip6h->src; + recv_info.new_dst_ip.v6 = ip6h->dst; + iphdrlen = 40; + recv_info.protocol = ip6h->next_header; // todo handle extension headers; + ip_len = ntohs(ip6h->payload_len) + iphdrlen; } - return 0; + if (bind_addr_used && !recv_info.new_dst_ip.equal(bind_addr)) { + mylog(log_trace, "bind adress doenst match %s %s, dropped\n", recv_info.new_dst_ip.get_str1(), bind_addr.get_str2()); + // printf(" bind adress doenst match, dropped\n"); + return -1; + } + + // if (!(iph->ihl > 0 && iph->ihl <=60)) { + // mylog(log_trace,"iph ihl error\n"); + // return -1; + // } + + if (raw_packet_len < ip_len) { + mylog(log_debug, "incomplete packet\n"); + return -1; + } + + if (raw_ip_version == AF_INET) { + if (raw_info.peek == 0) // avoid cal it twice + { + u32_t ip_chk = csum((unsigned short *)ip_begin, iphdrlen); + + if (ip_chk != 0) { + mylog(log_debug, "ip header error %x\n", ip_chk); + return -1; + } + } + } else { + // do nothing + } + + payload = ip_begin + iphdrlen; + + payloadlen = ip_len - iphdrlen; + + if (payloadlen < 0) { + mylog(log_warn, "error payload len\n"); + return -1; + } + + return 0; } -int peek_raw(raw_info_t &raw_info) -{ - //static char peek_raw_buf[buf_len]; - //assert(g_packet_buf_cnt==1); - //g_packet_buf_cnt--; - //char * peek_raw_buf=g_packet_buf; - //int recv_len=g_packet_buf_len; +int peek_raw(raw_info_t &raw_info) { + // static char peek_raw_buf[buf_len]; + // assert(g_packet_buf_cnt==1); + // g_packet_buf_cnt--; + // char * peek_raw_buf=g_packet_buf; + // int recv_len=g_packet_buf_len; - //char *ip_begin=peek_raw_buf+link_level_header_len; - //struct sockaddr saddr={0}; - //socklen_t saddr_size=sizeof(saddr); - //int recv_len = recvfrom(raw_recv_fd, peek_raw_buf,max_data_len, MSG_PEEK ,&saddr , &saddr_size);//change max_data_len to something smaller,we only need header here - //iphdr * iph = (struct iphdr *) (ip_begin); - //mylog(log_info,"recv_len %d\n",recv_len); - //if(recv_lensaddr; - //unsigned short iphdrlen =iph->ihl*4; - //char *payload=ip_begin+iphdrlen; + // char *ip_begin=peek_raw_buf+link_level_header_len; + // struct sockaddr saddr={0}; + // socklen_t saddr_size=sizeof(saddr); + // int recv_len = recvfrom(raw_recv_fd, peek_raw_buf,max_data_len, MSG_PEEK ,&saddr , &saddr_size);//change max_data_len to something smaller,we only need header here + // iphdr * iph = (struct iphdr *) (ip_begin); + // mylog(log_info,"recv_len %d\n",recv_len); + // if(recv_lensaddr; + // unsigned short iphdrlen =iph->ihl*4; + // char *payload=ip_begin+iphdrlen; - packet_info_t &recv_info=raw_info.recv_info; + packet_info_t &recv_info = raw_info.recv_info; - char *payload;int payload_len; - if(recv_raw_ip(raw_info,payload,payload_len)!=0) - return -1; - //mylog(log_info,"protocol %d\n",iph->protocol); - switch(raw_mode) - { - case mode_faketcp: - { - if(recv_info.protocol!=IPPROTO_TCP) - { - mylog(log_trace,"failed here"); - return -1; - } - struct my_tcphdr *tcph=(my_tcphdr *)payload; - if(payload_lensource); - recv_info.syn=tcph->syn; - break; - } - case mode_udp: - { - if(recv_info.protocol!=IPPROTO_UDP) return -1; - struct my_udphdr *udph=(my_udphdr *)payload; - if(payload_lensource); - break; - } - case mode_icmp: - { - if(raw_ip_version==AF_INET) - { - if(recv_info.protocol!=IPPROTO_ICMP) return -1; - }else - { - assert(raw_ip_version==AF_INET6); - if(recv_info.protocol!=IPPROTO_ICMPV6) return -1; - } - struct my_icmphdr *icmph=(my_icmphdr *)payload; - if(payload_lenid); - break; - } - default:return -1; + char *payload; + int payload_len; + if (recv_raw_ip(raw_info, payload, payload_len) != 0) + return -1; + // mylog(log_info,"protocol %d\n",iph->protocol); + switch (raw_mode) { + case mode_faketcp: { + if (recv_info.protocol != IPPROTO_TCP) { + mylog(log_trace, "failed here"); + return -1; + } + struct my_tcphdr *tcph = (my_tcphdr *)payload; + if (payload_len < int(sizeof(my_tcphdr))) { + mylog(log_trace, "failed here"); + return -1; + } + recv_info.src_port = ntohs(tcph->source); + recv_info.syn = tcph->syn; + break; + } + case mode_udp: { + if (recv_info.protocol != IPPROTO_UDP) return -1; + struct my_udphdr *udph = (my_udphdr *)payload; + if (payload_len < int(sizeof(my_udphdr))) + return -1; + recv_info.src_port = ntohs(udph->source); + break; + } + case mode_icmp: { + if (raw_ip_version == AF_INET) { + if (recv_info.protocol != IPPROTO_ICMP) return -1; + } else { + assert(raw_ip_version == AF_INET6); + if (recv_info.protocol != IPPROTO_ICMPV6) return -1; + } + struct my_icmphdr *icmph = (my_icmphdr *)payload; + if (payload_len < int(sizeof(my_udphdr))) + return -1; + recv_info.src_port = ntohs(icmph->id); + break; + } + default: + return -1; } return 0; } -int send_raw_icmp(raw_info_t &raw_info, const char * payload, int payloadlen) -{ - const packet_info_t &send_info=raw_info.send_info; - const packet_info_t &recv_info=raw_info.recv_info; +int send_raw_icmp(raw_info_t &raw_info, const char *payload, int payloadlen) { + const packet_info_t &send_info = raw_info.send_info; + const packet_info_t &recv_info = raw_info.recv_info; - char send_raw_icmp_buf[buf_len]; - my_icmphdr *icmph=(struct my_icmphdr *) (send_raw_icmp_buf); - memset(icmph,0,sizeof(my_icmphdr)); - if(raw_ip_version==AF_INET) - { - if(program_mode==client_mode) - { - icmph->type=8; - } - else - { - icmph->type=0; - } - } - else - { - assert(raw_ip_version==AF_INET6); - if(program_mode==client_mode) - { - icmph->type=128; - } - else - { - icmph->type=129; - } - } - icmph->code=0; - icmph->id=htons(send_info.src_port); + char send_raw_icmp_buf[buf_len]; + my_icmphdr *icmph = (struct my_icmphdr *)(send_raw_icmp_buf); + memset(icmph, 0, sizeof(my_icmphdr)); + if (raw_ip_version == AF_INET) { + if (program_mode == client_mode) { + icmph->type = 8; + } else { + icmph->type = 0; + } + } else { + assert(raw_ip_version == AF_INET6); + if (program_mode == client_mode) { + icmph->type = 128; + } else { + icmph->type = 129; + } + } + icmph->code = 0; + icmph->id = htons(send_info.src_port); - icmph->seq=htons(send_info.my_icmp_seq); /////////////modify + icmph->seq = htons(send_info.my_icmp_seq); /////////////modify - memcpy(send_raw_icmp_buf+sizeof(my_icmphdr),payload,payloadlen); + memcpy(send_raw_icmp_buf + sizeof(my_icmphdr), payload, payloadlen); - if(raw_ip_version==AF_INET) - { - icmph->check_sum = csum( (unsigned short*) send_raw_icmp_buf, sizeof(my_icmphdr)+payloadlen); - } - else - { - assert(raw_ip_version==AF_INET6); + if (raw_ip_version == AF_INET) { + icmph->check_sum = csum((unsigned short *)send_raw_icmp_buf, sizeof(my_icmphdr) + payloadlen); + } else { + assert(raw_ip_version == AF_INET6); - pseudo_header6 v6; - struct pseudo_header6 *psh = &v6; + pseudo_header6 v6; + struct pseudo_header6 *psh = &v6; - psh->src=send_info.new_src_ip.v6; - psh->dst=send_info.new_dst_ip.v6; - psh->next_header=IPPROTO_ICMPV6; - psh->tcp_length=htons(sizeof(my_icmphdr)+payloadlen); - psh->placeholder1 = 0; - psh->placeholder2 = 0; + psh->src = send_info.new_src_ip.v6; + psh->dst = send_info.new_dst_ip.v6; + psh->next_header = IPPROTO_ICMPV6; + psh->tcp_length = htons(sizeof(my_icmphdr) + payloadlen); + psh->placeholder1 = 0; + psh->placeholder2 = 0; - icmph->check_sum = csum_with_header((char *)psh,sizeof(pseudo_header6), (unsigned short*) send_raw_icmp_buf, sizeof(my_icmphdr)+payloadlen); - } - if(send_raw_ip(raw_info,send_raw_icmp_buf,sizeof(my_icmphdr)+payloadlen)!=0) - { - return -1; - } + icmph->check_sum = csum_with_header((char *)psh, sizeof(pseudo_header6), (unsigned short *)send_raw_icmp_buf, sizeof(my_icmphdr) + payloadlen); + } + if (send_raw_ip(raw_info, send_raw_icmp_buf, sizeof(my_icmphdr) + payloadlen) != 0) { + return -1; + } - /*if(program_mode==client_mode) - { - send_info.icmp_seq++; - }*/ + /*if(program_mode==client_mode) + { + send_info.icmp_seq++; + }*/ - return 0; + return 0; } -int send_raw_udp(raw_info_t &raw_info, const char * payload, int payloadlen) -{ - const packet_info_t &send_info=raw_info.send_info; - const packet_info_t &recv_info=raw_info.recv_info; +int send_raw_udp(raw_info_t &raw_info, const char *payload, int payloadlen) { + const packet_info_t &send_info = raw_info.send_info; + const packet_info_t &recv_info = raw_info.recv_info; - char send_raw_udp_buf[buf_len]; + char send_raw_udp_buf[buf_len]; - my_udphdr *udph=(struct my_udphdr *) (send_raw_udp_buf); + my_udphdr *udph = (struct my_udphdr *)(send_raw_udp_buf); - memset(udph,0,sizeof(my_udphdr)); + memset(udph, 0, sizeof(my_udphdr)); - udph->source = htons(send_info.src_port); - udph->dest = htons(send_info.dst_port); + udph->source = htons(send_info.src_port); + udph->dest = htons(send_info.dst_port); - int udp_tot_len=payloadlen+sizeof(my_udphdr); + int udp_tot_len = payloadlen + sizeof(my_udphdr); + if (udp_tot_len > 65535) { + mylog(log_debug, "invalid len\n"); + return -1; + } + mylog(log_trace, "udp_len:%d %d\n", udp_tot_len, udph->len); + udph->len = htons(uint16_t(udp_tot_len)); - if(udp_tot_len>65535) - { - mylog(log_debug,"invalid len\n"); - return -1; - } - mylog(log_trace,"udp_len:%d %d\n",udp_tot_len,udph->len); - udph->len=htons(uint16_t(udp_tot_len)); + memcpy(send_raw_udp_buf + sizeof(my_udphdr), payload, payloadlen); - memcpy(send_raw_udp_buf+sizeof(my_udphdr),payload,payloadlen); + if (raw_ip_version == AF_INET) { + pseudo_header v4; + struct pseudo_header *psh = &v4; + psh->source_address = send_info.new_src_ip.v4; + psh->dest_address = send_info.new_dst_ip.v4; + psh->placeholder = 0; + psh->protocol = IPPROTO_UDP; + psh->tcp_length = htons(udp_tot_len); + udph->check = csum_with_header((char *)psh, sizeof(pseudo_header), (unsigned short *)send_raw_udp_buf, udp_tot_len); + } else { + assert(raw_ip_version == AF_INET6); + pseudo_header6 v6; + struct pseudo_header6 *psh = &v6; + psh->src = send_info.new_src_ip.v6; + psh->dst = send_info.new_dst_ip.v6; + psh->next_header = IPPROTO_UDP; + psh->tcp_length = htons(udp_tot_len); - if(raw_ip_version==AF_INET) - { - pseudo_header v4; - struct pseudo_header *psh = &v4; + psh->placeholder1 = 0; + psh->placeholder2 = 0; - psh->source_address = send_info.new_src_ip.v4; - psh->dest_address = send_info.new_dst_ip.v4; - psh->placeholder = 0; - psh->protocol = IPPROTO_UDP; - psh->tcp_length = htons(udp_tot_len); + udph->check = csum_with_header((char *)psh, sizeof(pseudo_header6), (unsigned short *)send_raw_udp_buf, udp_tot_len); + } - udph->check = csum_with_header((char *)psh,sizeof(pseudo_header), (unsigned short*) send_raw_udp_buf, udp_tot_len); - } - else - { - assert(raw_ip_version==AF_INET6); - pseudo_header6 v6; - struct pseudo_header6 *psh = &v6; - - psh->src=send_info.new_src_ip.v6; - psh->dst=send_info.new_dst_ip.v6; - psh->next_header=IPPROTO_UDP; - psh->tcp_length=htons(udp_tot_len); - - psh->placeholder1 = 0; - psh->placeholder2 = 0; - - - udph->check = csum_with_header((char *)psh,sizeof(pseudo_header6), (unsigned short*) send_raw_udp_buf, udp_tot_len); - } - - - if(send_raw_ip(raw_info,send_raw_udp_buf,udp_tot_len)!=0) - { - return -1; - } - return 0; + if (send_raw_ip(raw_info, send_raw_udp_buf, udp_tot_len) != 0) { + return -1; + } + return 0; } -int send_raw_tcp(raw_info_t &raw_info,const char * payload, int payloadlen) { //TODO seq increase +int send_raw_tcp(raw_info_t &raw_info, const char *payload, int payloadlen) { // TODO seq increase + const packet_info_t &send_info = raw_info.send_info; + const packet_info_t &recv_info = raw_info.recv_info; - const packet_info_t &send_info=raw_info.send_info; - const packet_info_t &recv_info=raw_info.recv_info; + // mylog(log_debug,"syn %d\n",send_info.syn); - //mylog(log_debug,"syn %d\n",send_info.syn); + char send_raw_tcp_buf[buf_len]; + // char *send_raw_tcp_buf=send_raw_tcp_buf0; - char send_raw_tcp_buf[buf_len]; - //char *send_raw_tcp_buf=send_raw_tcp_buf0; + struct my_tcphdr *tcph = (struct my_tcphdr *)(send_raw_tcp_buf); - struct my_tcphdr *tcph = (struct my_tcphdr *) (send_raw_tcp_buf); + memset(tcph, 0, sizeof(my_tcphdr)); - memset(tcph,0,sizeof(my_tcphdr)); + // TCP Header + tcph->source = htons(send_info.src_port); + tcph->dest = htons(send_info.dst_port); - //TCP Header - tcph->source = htons(send_info.src_port); - tcph->dest = htons(send_info.dst_port); + tcph->seq = htonl(send_info.seq); + tcph->ack_seq = htonl(send_info.ack_seq); - tcph->seq = htonl(send_info.seq); - tcph->ack_seq = htonl(send_info.ack_seq); + tcph->fin = 0; + tcph->syn = send_info.syn; + tcph->rst = 0; + tcph->psh = send_info.psh; + tcph->ack = send_info.ack; - tcph->fin = 0; - tcph->syn = send_info.syn; - tcph->rst = 0; - tcph->psh = send_info.psh; - tcph->ack = send_info.ack; + if (tcph->syn == 1) { + tcph->doff = 10; // tcp header size + int i = sizeof(my_tcphdr); + send_raw_tcp_buf[i++] = 0x02; // mss + send_raw_tcp_buf[i++] = 0x04; + send_raw_tcp_buf[i++] = 0x05; + send_raw_tcp_buf[i++] = (char)0xb4; - if (tcph->syn == 1) { - tcph->doff = 10; //tcp header size - int i = sizeof(my_tcphdr); - send_raw_tcp_buf[i++] = 0x02; //mss - send_raw_tcp_buf[i++] = 0x04; - send_raw_tcp_buf[i++] = 0x05; - send_raw_tcp_buf[i++] = (char)0xb4; + // raw_send_buf[i++]=0x01; + // raw_send_buf[i++]=0x01; + send_raw_tcp_buf[i++] = 0x04; // sack ok + send_raw_tcp_buf[i++] = 0x02; // sack ok - //raw_send_buf[i++]=0x01; - //raw_send_buf[i++]=0x01; - send_raw_tcp_buf[i++] = 0x04; //sack ok - send_raw_tcp_buf[i++] = 0x02; //sack ok + send_raw_tcp_buf[i++] = 0x08; // ts i=6 + send_raw_tcp_buf[i++] = 0x0a; // i=7 - send_raw_tcp_buf[i++] = 0x08; //ts i=6 - send_raw_tcp_buf[i++] = 0x0a; //i=7 + //*(u32_t*) (&send_raw_tcp_buf[i]) = htonl( + // (u32_t) get_current_time()); - //*(u32_t*) (&send_raw_tcp_buf[i]) = htonl( - // (u32_t) get_current_time()); + u32_t ts = htonl((u32_t)get_current_time()); + memcpy(&send_raw_tcp_buf[i], &ts, sizeof(ts)); - u32_t ts=htonl((u32_t) get_current_time()); - memcpy(&send_raw_tcp_buf[i],&ts,sizeof(ts)); + i += 4; - i += 4; + // mylog(log_info,"[syn]\n",send_info.ts_ack); - //mylog(log_info,"[syn]\n",send_info.ts_ack); + //*(u32_t*) (&send_raw_tcp_buf[i]) = htonl(send_info.ts_ack); + u32_t ts_ack = htonl(send_info.ts_ack); + memcpy(&send_raw_tcp_buf[i], &ts_ack, sizeof(ts_ack)); - //*(u32_t*) (&send_raw_tcp_buf[i]) = htonl(send_info.ts_ack); - u32_t ts_ack=htonl(send_info.ts_ack); - memcpy(&send_raw_tcp_buf[i],&ts_ack,sizeof(ts_ack)); + i += 4; - i += 4; + send_raw_tcp_buf[i++] = 0x01; + send_raw_tcp_buf[i++] = 0x03; + send_raw_tcp_buf[i++] = 0x03; + send_raw_tcp_buf[i++] = wscale; + } else { + tcph->doff = 8; + int i = sizeof(my_tcphdr); - send_raw_tcp_buf[i++] = 0x01; - send_raw_tcp_buf[i++] = 0x03; - send_raw_tcp_buf[i++] = 0x03; - send_raw_tcp_buf[i++] = wscale; - } else { - tcph->doff = 8; - int i = sizeof(my_tcphdr); + send_raw_tcp_buf[i++] = 0x01; + send_raw_tcp_buf[i++] = 0x01; - send_raw_tcp_buf[i++] = 0x01; - send_raw_tcp_buf[i++] = 0x01; + send_raw_tcp_buf[i++] = 0x08; // ts //i=2 + send_raw_tcp_buf[i++] = 0x0a; // i=3; - send_raw_tcp_buf[i++] = 0x08; //ts //i=2 - send_raw_tcp_buf[i++] = 0x0a; //i=3; + //*(u32_t*) (&send_raw_tcp_buf[i]) = htonl( + // (u32_t) get_current_time()); - //*(u32_t*) (&send_raw_tcp_buf[i]) = htonl( - // (u32_t) get_current_time()); + u32_t ts = htonl((u32_t)get_current_time()); + memcpy(&send_raw_tcp_buf[i], &ts, sizeof(ts)); - u32_t ts=htonl((u32_t) get_current_time()); - memcpy(&send_raw_tcp_buf[i],&ts,sizeof(ts)); + i += 4; - i += 4; + // mylog(log_info,"\n",send_info.ts_ack); - //mylog(log_info,"\n",send_info.ts_ack); + //*(u32_t*) (&send_raw_tcp_buf[i]) = htonl(send_info.ts_ack); + u32_t ts_ack = htonl(send_info.ts_ack); + memcpy(&send_raw_tcp_buf[i], &ts_ack, sizeof(ts_ack)); + i += 4; + } - //*(u32_t*) (&send_raw_tcp_buf[i]) = htonl(send_info.ts_ack); - u32_t ts_ack=htonl(send_info.ts_ack); - memcpy(&send_raw_tcp_buf[i],&ts_ack,sizeof(ts_ack)); - i += 4; - } + tcph->urg = 0; + // tcph->window = htons((uint16_t)(1024)); + tcph->window = htons((uint16_t)(receive_window_lower_bound + get_true_random_number() % receive_window_random_range)); - tcph->urg = 0; - //tcph->window = htons((uint16_t)(1024)); - tcph->window = htons((uint16_t) (receive_window_lower_bound + get_true_random_number() % receive_window_random_range)); + tcph->check = 0; // leave checksum 0 now, filled later by pseudo header + tcph->urg_ptr = 0; - tcph->check = 0; //leave checksum 0 now, filled later by pseudo header - tcph->urg_ptr = 0; + char *tcp_data = send_raw_tcp_buf + +tcph->doff * 4; - char *tcp_data = send_raw_tcp_buf+ + tcph->doff * 4; + memcpy(tcp_data, payload, payloadlen); + int tcp_totlen = tcph->doff * 4 + payloadlen; - memcpy(tcp_data, payload, payloadlen); - int tcp_totlen=tcph->doff*4 + payloadlen; + if (raw_ip_version == AF_INET) { + pseudo_header v4; + struct pseudo_header *psh = &v4; - if(raw_ip_version==AF_INET) - { - pseudo_header v4; - struct pseudo_header *psh = &v4; + psh->source_address = send_info.new_src_ip.v4; + psh->dest_address = send_info.new_dst_ip.v4; + psh->placeholder = 0; + psh->protocol = IPPROTO_TCP; + psh->tcp_length = htons(tcp_totlen); - psh->source_address = send_info.new_src_ip.v4; - psh->dest_address = send_info.new_dst_ip.v4; - psh->placeholder = 0; - psh->protocol = IPPROTO_TCP; - psh->tcp_length = htons(tcp_totlen); + tcph->check = csum_with_header((char *)psh, sizeof(pseudo_header), (unsigned short *)send_raw_tcp_buf, tcp_totlen); + } else { + assert(raw_ip_version == AF_INET6); - tcph->check = csum_with_header((char *)psh,sizeof(pseudo_header), (unsigned short*) send_raw_tcp_buf, tcp_totlen); - } - else - { - assert(raw_ip_version==AF_INET6); + pseudo_header6 v6; + struct pseudo_header6 *psh = &v6; - pseudo_header6 v6; - struct pseudo_header6 *psh = &v6; + psh->src = send_info.new_src_ip.v6; + psh->dst = send_info.new_dst_ip.v6; + psh->next_header = IPPROTO_TCP; + psh->tcp_length = htons(tcp_totlen); + psh->placeholder1 = 0; + psh->placeholder2 = 0; - psh->src=send_info.new_src_ip.v6; - psh->dst=send_info.new_dst_ip.v6; - psh->next_header=IPPROTO_TCP; - psh->tcp_length=htons(tcp_totlen); - psh->placeholder1 = 0; - psh->placeholder2 = 0; + tcph->check = csum_with_header((char *)psh, sizeof(pseudo_header6), (unsigned short *)send_raw_tcp_buf, tcp_totlen); + } - tcph->check = csum_with_header((char *)psh,sizeof(pseudo_header6), (unsigned short*) send_raw_tcp_buf, tcp_totlen); - } + if (send_raw_ip(raw_info, send_raw_tcp_buf, tcp_totlen) != 0) { + return -1; + } - - if(send_raw_ip(raw_info,send_raw_tcp_buf,tcp_totlen)!=0) - { - return -1; - } - - - raw_info.send_info.data_len=payloadlen; - return 0; + raw_info.send_info.data_len = payloadlen; + return 0; } /* int send_raw_tcp_deprecated(const packet_info_t &info,const char * payload,int payloadlen) { - static uint16_t ip_id=1; - char raw_send_buf[buf_len]; - char raw_send_buf2[buf_len]; + static uint16_t ip_id=1; + char raw_send_buf[buf_len]; + char raw_send_buf2[buf_len]; - //if((prog_mode==client_mode&& payloadlen!=9) ||(prog_mode==server_mode&& payloadlen!=5 ) ) - mylog(log_trace,"send raw from to %d %d %d %d\n",info.src_ip,info.src_port,info.dst_ip,info.dst_port); + //if((prog_mode==client_mode&& payloadlen!=9) ||(prog_mode==server_mode&& payloadlen!=5 ) ) + mylog(log_trace,"send raw from to %d %d %d %d\n",info.src_ip,info.src_port,info.dst_ip,info.dst_port); - char *data; + char *data; memset(raw_send_buf,0,payloadlen+100); @@ -2064,51 +1806,51 @@ int send_raw_tcp_deprecated(const packet_info_t &info,const char * payload,int p if(tcph->syn==1) { - tcph->doff = 10; //tcp header size - int i=sizeof (struct iphdr)+20; - raw_send_buf[i++]=0x02;//mss - raw_send_buf[i++]=0x04; - raw_send_buf[i++]=0x05; - raw_send_buf[i++]=0xb4; + tcph->doff = 10; //tcp header size + int i=sizeof (struct iphdr)+20; + raw_send_buf[i++]=0x02;//mss + raw_send_buf[i++]=0x04; + raw_send_buf[i++]=0x05; + raw_send_buf[i++]=0xb4; - //raw_send_buf[i++]=0x01; - //raw_send_buf[i++]=0x01; - raw_send_buf[i++]=0x04; //sack ok - raw_send_buf[i++]=0x02; //sack ok + //raw_send_buf[i++]=0x01; + //raw_send_buf[i++]=0x01; + raw_send_buf[i++]=0x04; //sack ok + raw_send_buf[i++]=0x02; //sack ok - raw_send_buf[i++]=0x08; //i=6; - raw_send_buf[i++]=0x0a; + raw_send_buf[i++]=0x08; //i=6; + raw_send_buf[i++]=0x0a; - *(uint32_t*)(& raw_send_buf[i])=htonl((uint32_t)get_current_time()); + *(uint32_t*)(& raw_send_buf[i])=htonl((uint32_t)get_current_time()); - i+=4; + i+=4; - *(uint32_t*)(& raw_send_buf[i])=htonl(info.ts_ack); - i+=4; + *(uint32_t*)(& raw_send_buf[i])=htonl(info.ts_ack); + i+=4; - raw_send_buf[i++]=0x01; - raw_send_buf[i++]=0x03; - raw_send_buf[i++]=0x03; - raw_send_buf[i++]=0x05; + raw_send_buf[i++]=0x01; + raw_send_buf[i++]=0x03; + raw_send_buf[i++]=0x03; + raw_send_buf[i++]=0x05; } else { - tcph->doff=8; - int i=sizeof (struct iphdr)+20; + tcph->doff=8; + int i=sizeof (struct iphdr)+20; - raw_send_buf[i++]=0x01; - raw_send_buf[i++]=0x01; + raw_send_buf[i++]=0x01; + raw_send_buf[i++]=0x01; - raw_send_buf[i++]=0x08; //i=0; - raw_send_buf[i++]=0x0a; + raw_send_buf[i++]=0x08; //i=0; + raw_send_buf[i++]=0x0a; - *(uint32_t*)(& raw_send_buf[i])=htonl((uint32_t)get_current_time()); + *(uint32_t*)(& raw_send_buf[i])=htonl((uint32_t)get_current_time()); - i+=4; + i+=4; - *(uint32_t*)(& raw_send_buf[i])=htonl(info.ts_ack); - i+=4; + *(uint32_t*)(& raw_send_buf[i])=htonl(info.ts_ack); + i+=4; } @@ -2153,189 +1895,160 @@ int send_raw_tcp_deprecated(const packet_info_t &info,const char * payload,int p if(g_packet_info_send.syn==0&&g_packet_info_send.ack==1&&payloadlen!=0) { - if(seq_mode==0) - { + if(seq_mode==0) + { - } - else if(seq_mode==1) - { - g_packet_info_send.seq+=payloadlen; - } - else if(seq_mode==2) - { - if(random()% 5==3 ) - g_packet_info_send.seq+=payloadlen; - } + } + else if(seq_mode==1) + { + g_packet_info_send.seq+=payloadlen; + } + else if(seq_mode==2) + { + if(random()% 5==3 ) + g_packet_info_send.seq+=payloadlen; + } } mylog(log_trace,"\n",ret); - if(ret<0) + if(ret<0) { - mylog(log_fatal,""); - perror("raw send error\n"); - //printf("send error\n"); + mylog(log_fatal,""); + perror("raw send error\n"); + //printf("send error\n"); } return 0; } */ -int recv_raw_icmp(raw_info_t &raw_info, char *&payload, int &payloadlen) -{ - const packet_info_t &send_info=raw_info.send_info; - packet_info_t &recv_info=raw_info.recv_info; - static char recv_raw_icmp_buf[buf_len]; +int recv_raw_icmp(raw_info_t &raw_info, char *&payload, int &payloadlen) { + const packet_info_t &send_info = raw_info.send_info; + packet_info_t &recv_info = raw_info.recv_info; + static char recv_raw_icmp_buf[buf_len]; - char * ip_payload; - int ip_payloadlen; + char *ip_payload; + int ip_payloadlen; - if(recv_raw_ip(raw_info,ip_payload,ip_payloadlen)!=0) - { - mylog(log_debug,"recv_raw_ip error\n"); - return -1; - } - mylog(log_trace,"ip_payloadlen=%d\n",ip_payloadlen); - if(raw_ip_version==AF_INET) - { - if(recv_info.protocol!=IPPROTO_ICMP) - { - //printf("not udp protocol\n"); - return -1; - } - } - else - { - assert(raw_ip_version==AF_INET6); - if(recv_info.protocol!=IPPROTO_ICMPV6) - { - //printf("not udp protocol\n"); - return -1; - } - } + if (recv_raw_ip(raw_info, ip_payload, ip_payloadlen) != 0) { + mylog(log_debug, "recv_raw_ip error\n"); + return -1; + } + mylog(log_trace, "ip_payloadlen=%d\n", ip_payloadlen); + if (raw_ip_version == AF_INET) { + if (recv_info.protocol != IPPROTO_ICMP) { + // printf("not udp protocol\n"); + return -1; + } + } else { + assert(raw_ip_version == AF_INET6); + if (recv_info.protocol != IPPROTO_ICMPV6) { + // printf("not udp protocol\n"); + return -1; + } + } - if(ip_payloadlenid) != send_info.src_port) { + mylog(log_debug, "icmp id mis-match,ignored\n"); + return -1; + } - my_icmphdr *icmph=(struct my_icmphdr *) (ip_payload); + recv_info.src_port = recv_info.dst_port = ntohs(icmph->id); + recv_info.my_icmp_seq = ntohs(icmph->seq); - if(ntohs(icmph->id)!=send_info.src_port) - { - mylog(log_debug,"icmp id mis-match,ignored\n"); - return -1; - } + if (icmph->code != 0) + return -1; - recv_info.src_port=recv_info.dst_port=ntohs(icmph->id); - recv_info.my_icmp_seq=ntohs(icmph->seq); + unsigned short check; + if (raw_ip_version == AF_INET) { + if (program_mode == client_mode) { + if (icmph->type != 0) + return -1; + } else { + if (icmph->type != 8) + return -1; + } + check = csum((unsigned short *)ip_payload, ip_payloadlen); + } else { + assert(raw_ip_version == AF_INET6); + if (program_mode == client_mode) { + if (icmph->type != 129) + return -1; + } else { + if (icmph->type != 128) + return -1; + } - if(icmph->code!=0) - return -1; + pseudo_header6 tmp_header; + struct pseudo_header6 *psh = &tmp_header; - unsigned short check ; - if(raw_ip_version==AF_INET) - { - if(program_mode==client_mode) - { - if(icmph->type!=0) - return -1; - } - else - { - if(icmph->type!=8) - return -1; - } - check= csum( (unsigned short*) ip_payload, ip_payloadlen); - } - else - { - assert(raw_ip_version==AF_INET6); - if(program_mode==client_mode) - { - if(icmph->type!=129) - return -1; - } - else - { - if(icmph->type!=128) - return -1; - } + psh->src = recv_info.new_src_ip.v6; + psh->dst = recv_info.new_dst_ip.v6; + psh->placeholder1 = 0; + psh->placeholder2 = 0; + psh->next_header = IPPROTO_ICMPV6; + psh->tcp_length = htons(ip_payloadlen); - pseudo_header6 tmp_header; - struct pseudo_header6 *psh=&tmp_header ; + check = csum_with_header((char *)psh, sizeof(pseudo_header6), (unsigned short *)ip_payload, ip_payloadlen); + } - psh->src = recv_info.new_src_ip.v6; - psh->dst = recv_info.new_dst_ip.v6; - psh->placeholder1 = 0; - psh->placeholder2 = 0; - psh->next_header = IPPROTO_ICMPV6; - psh->tcp_length = htons(ip_payloadlen); + if (check != 0) { + mylog(log_debug, "icmp checksum fail %x\n", check); + return -1; + } + // mylog(log_info,"program_mode=%d\n",program_mode); + /* + if(program_mode==server_mode) + { + send_info.icmp_seq=ntohs(icmph->seq); + //mylog(log_info,"send_info.seq=%d\n",send_info.seq); + }*/ - check = csum_with_header((char *)psh,sizeof(pseudo_header6), (unsigned short*) ip_payload, ip_payloadlen); - } - - - if(check!=0) - { - mylog(log_debug,"icmp checksum fail %x\n",check); - return -1; - } - //mylog(log_info,"program_mode=%d\n",program_mode); -/* - if(program_mode==server_mode) - { - send_info.icmp_seq=ntohs(icmph->seq); - //mylog(log_info,"send_info.seq=%d\n",send_info.seq); - }*/ - - payload=ip_payload+sizeof(my_icmphdr); - payloadlen=ip_payloadlen-sizeof(my_icmphdr); - mylog(log_trace,"get a packet len=%d\n",payloadlen); + payload = ip_payload + sizeof(my_icmphdr); + payloadlen = ip_payloadlen - sizeof(my_icmphdr); + mylog(log_trace, "get a packet len=%d\n", payloadlen); return 0; } -int recv_raw_udp(raw_info_t &raw_info, char *&payload, int &payloadlen) -{ - const packet_info_t &send_info=raw_info.send_info; - packet_info_t &recv_info=raw_info.recv_info; - //static char recv_raw_udp_buf[buf_len]; - char * ip_payload; - int ip_payloadlen; +int recv_raw_udp(raw_info_t &raw_info, char *&payload, int &payloadlen) { + const packet_info_t &send_info = raw_info.send_info; + packet_info_t &recv_info = raw_info.recv_info; + // static char recv_raw_udp_buf[buf_len]; + char *ip_payload; + int ip_payloadlen; - if(recv_raw_ip(raw_info,ip_payload,ip_payloadlen)!=0) - { - mylog(log_debug,"recv_raw_ip error\n"); - return -1; - } - if(recv_info.protocol!=IPPROTO_UDP) - { - //printf("not udp protocol\n"); - return -1; - } - if(ip_payloadlenlen))!=ip_payloadlen) - { - - mylog(log_debug,"udp length error %d %d \n",ntohs(udph->len),ip_payloadlen); - return -1; - } - - if(udph->dest!=ntohs(uint16_t(filter_port))) - { - //printf("%x %x",tcph->dest,); - return -1; + if (int(ntohs(udph->len)) != ip_payloadlen) { + mylog(log_debug, "udp length error %d %d \n", ntohs(udph->len), ip_payloadlen); + return -1; } - //memcpy(recv_raw_udp_buf+ sizeof(struct pseudo_header) , ip_payload , ip_payloadlen); + if (udph->dest != ntohs(uint16_t(filter_port))) { + // printf("%x %x",tcph->dest,); + return -1; + } + + // memcpy(recv_raw_udp_buf+ sizeof(struct pseudo_header) , ip_payload , ip_payloadlen); /* pseudo_header tmp_header={0}; @@ -2351,220 +2064,187 @@ int recv_raw_udp(raw_info_t &raw_info, char *&payload, int &payloadlen) uint16_t udp_chk = csum_with_header((char *)psh,sizeof(pseudo_header), (unsigned short*) ip_payload, csum_len); */ uint16_t udp_chk; - int csum_len=ip_payloadlen; - if(raw_ip_version==AF_INET) - { - pseudo_header tmp_header; - struct pseudo_header *psh=&tmp_header ; + int csum_len = ip_payloadlen; + if (raw_ip_version == AF_INET) { + pseudo_header tmp_header; + struct pseudo_header *psh = &tmp_header; - psh->source_address = recv_info.new_src_ip.v4; - psh->dest_address = recv_info.new_dst_ip.v4; - psh->placeholder = 0; - psh->protocol = IPPROTO_UDP; - psh->tcp_length = htons(ip_payloadlen); + psh->source_address = recv_info.new_src_ip.v4; + psh->dest_address = recv_info.new_dst_ip.v4; + psh->placeholder = 0; + psh->protocol = IPPROTO_UDP; + psh->tcp_length = htons(ip_payloadlen); - udp_chk = csum_with_header((char *)psh,sizeof(pseudo_header), (unsigned short*) ip_payload, csum_len); - } - else - { - assert(raw_ip_version==AF_INET6); + udp_chk = csum_with_header((char *)psh, sizeof(pseudo_header), (unsigned short *)ip_payload, csum_len); + } else { + assert(raw_ip_version == AF_INET6); - pseudo_header6 tmp_header; - struct pseudo_header6 *psh=&tmp_header ; + pseudo_header6 tmp_header; + struct pseudo_header6 *psh = &tmp_header; - psh->src = recv_info.new_src_ip.v6; - psh->dst = recv_info.new_dst_ip.v6; - psh->placeholder1 = 0; - psh->placeholder2 = 0; - psh->next_header = IPPROTO_UDP; - psh->tcp_length = htons(ip_payloadlen); - - udp_chk = csum_with_header((char *)psh,sizeof(pseudo_header6), (unsigned short*) ip_payload, csum_len); - } - - if(udp_chk!=0) - { - mylog(log_debug,"udp_chk:%x\n",udp_chk); - mylog(log_debug,"udp header error\n"); - return -1; + psh->src = recv_info.new_src_ip.v6; + psh->dst = recv_info.new_dst_ip.v6; + psh->placeholder1 = 0; + psh->placeholder2 = 0; + psh->next_header = IPPROTO_UDP; + psh->tcp_length = htons(ip_payloadlen); + udp_chk = csum_with_header((char *)psh, sizeof(pseudo_header6), (unsigned short *)ip_payload, csum_len); } - char *udp_begin=ip_payload; + if (udp_chk != 0) { + mylog(log_debug, "udp_chk:%x\n", udp_chk); + mylog(log_debug, "udp header error\n"); + return -1; + } - recv_info.src_port=ntohs(udph->source); - recv_info.dst_port=ntohs(udph->dest); + char *udp_begin = ip_payload; - payloadlen = ip_payloadlen-sizeof(my_udphdr); + recv_info.src_port = ntohs(udph->source); + recv_info.dst_port = ntohs(udph->dest); - payload=udp_begin+sizeof(my_udphdr); + payloadlen = ip_payloadlen - sizeof(my_udphdr); + + payload = udp_begin + sizeof(my_udphdr); return 0; } -int parse_tcp_option(char * option_begin,char * option_end,packet_info_t &recv_info) -{ - recv_info.has_ts=0; - recv_info.ts=0; +int parse_tcp_option(char *option_begin, char *option_end, packet_info_t &recv_info) { + recv_info.has_ts = 0; + recv_info.ts = 0; - char *ptr=option_begin; - //char *option_end=tcp_begin+tcp_hdr_len; - while(ptr=option_end) - { - mylog(log_trace,"invaild option ptr+1==option_end,for ts\n"); - return -1; - } - if(*(ptr+1)!=10) - { - mylog(log_trace,"invaild ts len\n"); - return -1; - } - if(ptr+10>option_end) - { - mylog(log_trace,"ptr+10>option_end for ts\n"); - return -1; - } + char *ptr = option_begin; + // char *option_end=tcp_begin+tcp_hdr_len; + while (ptr < option_end) { + if (*ptr == 0) { + return 0; + } else if (*ptr == 1) { + ptr++; + } else if (*ptr == 8) { + if (ptr + 1 >= option_end) { + mylog(log_trace, "invaild option ptr+1==option_end,for ts\n"); + return -1; + } + if (*(ptr + 1) != 10) { + mylog(log_trace, "invaild ts len\n"); + return -1; + } + if (ptr + 10 > option_end) { + mylog(log_trace, "ptr+10>option_end for ts\n"); + return -1; + } - recv_info.has_ts=1; + recv_info.has_ts = 1; - recv_info.ts= read_u32(ptr+2); - recv_info.ts_ack=read_u32(ptr+6); + recv_info.ts = read_u32(ptr + 2); + recv_info.ts_ack = read_u32(ptr + 6); - //printf("<%d %d>!\n",recv_info.ts,recv_info.ts_ack); + // printf("<%d %d>!\n",recv_info.ts,recv_info.ts_ack); - //return 0;//we currently only parse ts, so just return after its found - ptr+=10; - } - else - { - if(ptr+1>=option_end) - { - mylog(log_trace,"invaild option ptr+1==option_end\n"); - return -1; - } - else - { - int len=(unsigned char)*(ptr+1); - if(len<=1) - { - mylog(log_trace,"invaild option len %d\n",len); - return -1; - } - //omit check - ptr+=len; - } - } - //printf("!"); + // return 0;//we currently only parse ts, so just return after its found + ptr += 10; + } else { + if (ptr + 1 >= option_end) { + mylog(log_trace, "invaild option ptr+1==option_end\n"); + return -1; + } else { + int len = (unsigned char)*(ptr + 1); + if (len <= 1) { + mylog(log_trace, "invaild option len %d\n", len); + return -1; + } + // omit check + ptr += len; + } + } + // printf("!"); } - //printf("\n"); + // printf("\n"); - return 0; + return 0; } -int recv_raw_tcp(raw_info_t &raw_info,char * &payload,int &payloadlen) -{ - const packet_info_t &send_info=raw_info.send_info; - packet_info_t &recv_info=raw_info.recv_info; +int recv_raw_tcp(raw_info_t &raw_info, char *&payload, int &payloadlen) { + const packet_info_t &send_info = raw_info.send_info; + packet_info_t &recv_info = raw_info.recv_info; - //static char recv_raw_tcp_buf[buf_len]; + // static char recv_raw_tcp_buf[buf_len]; - char * ip_payload; - int ip_payloadlen; + char *ip_payload; + int ip_payloadlen; - - if(recv_raw_ip(raw_info,ip_payload,ip_payloadlen)!=0) - { - mylog(log_debug,"recv_raw_ip error\n"); - return -1; - } - - if(recv_info.protocol!=IPPROTO_TCP) - { - //printf("not tcp protocol\n"); - return -1; - } - - - my_tcphdr * tcph=(struct my_tcphdr*)ip_payload; - - unsigned short tcphdrlen = tcph->doff*4; - - if (!(tcphdrlen > 0 && tcphdrlen <=60)) { - mylog(log_debug,"tcph error\n"); - return 0; + if (recv_raw_ip(raw_info, ip_payload, ip_payloadlen) != 0) { + mylog(log_debug, "recv_raw_ip error\n"); + return -1; } - if (tcphdrlen >ip_payloadlen) { - mylog(log_debug,"error,tcphdrlen >ip_payloadlen\n"); - return 0; + if (recv_info.protocol != IPPROTO_TCP) { + // printf("not tcp protocol\n"); + return -1; } + my_tcphdr *tcph = (struct my_tcphdr *)ip_payload; - if(tcph->dest!=ntohs(uint16_t(filter_port))) - { - //printf("%x %x",tcph->dest,); - return -1; + unsigned short tcphdrlen = tcph->doff * 4; + + if (!(tcphdrlen > 0 && tcphdrlen <= 60)) { + mylog(log_debug, "tcph error\n"); + return 0; } - // memcpy(recv_raw_tcp_buf+ sizeof(struct pseudo_header) , ip_payload , ip_payloadlen); + if (tcphdrlen > ip_payloadlen) { + mylog(log_debug, "error,tcphdrlen >ip_payloadlen\n"); + return 0; + } + + if (tcph->dest != ntohs(uint16_t(filter_port))) { + // printf("%x %x",tcph->dest,); + return -1; + } + + // memcpy(recv_raw_tcp_buf+ sizeof(struct pseudo_header) , ip_payload , ip_payloadlen); uint16_t tcp_chk; - int csum_len=ip_payloadlen; - if(raw_ip_version==AF_INET) - { - pseudo_header tmp_header; - struct pseudo_header *psh=&tmp_header ; + int csum_len = ip_payloadlen; + if (raw_ip_version == AF_INET) { + pseudo_header tmp_header; + struct pseudo_header *psh = &tmp_header; - psh->source_address = recv_info.new_src_ip.v4; - psh->dest_address = recv_info.new_dst_ip.v4; - psh->placeholder = 0; - psh->protocol = IPPROTO_TCP; - psh->tcp_length = htons(ip_payloadlen); + psh->source_address = recv_info.new_src_ip.v4; + psh->dest_address = recv_info.new_dst_ip.v4; + psh->placeholder = 0; + psh->protocol = IPPROTO_TCP; + psh->tcp_length = htons(ip_payloadlen); - tcp_chk = csum_with_header((char *)psh,sizeof(pseudo_header), (unsigned short*) ip_payload, csum_len); - } - else - { - assert(raw_ip_version==AF_INET6); + tcp_chk = csum_with_header((char *)psh, sizeof(pseudo_header), (unsigned short *)ip_payload, csum_len); + } else { + assert(raw_ip_version == AF_INET6); - pseudo_header6 tmp_header; - struct pseudo_header6 *psh=&tmp_header ; + pseudo_header6 tmp_header; + struct pseudo_header6 *psh = &tmp_header; - psh->src = recv_info.new_src_ip.v6; - psh->dst = recv_info.new_dst_ip.v6; - psh->placeholder1 = 0; - psh->placeholder2 = 0; - psh->next_header = IPPROTO_TCP; - psh->tcp_length = htons(ip_payloadlen); + psh->src = recv_info.new_src_ip.v6; + psh->dst = recv_info.new_dst_ip.v6; + psh->placeholder1 = 0; + psh->placeholder2 = 0; + psh->next_header = IPPROTO_TCP; + psh->tcp_length = htons(ip_payloadlen); - tcp_chk = csum_with_header((char *)psh,sizeof(pseudo_header6), (unsigned short*) ip_payload, csum_len); - } + tcp_chk = csum_with_header((char *)psh, sizeof(pseudo_header6), (unsigned short *)ip_payload, csum_len); + } /*for(int i=0;i",int(ip_payload[i])); + printf("<%d>",int(ip_payload[i])); } printf("\n");*/ - if(tcp_chk!=0) - { - mylog(log_debug,"tcp_chk:%x, tcp checksum failed, ignored\n",tcp_chk); - //return -1; - + if (tcp_chk != 0) { + mylog(log_debug, "tcp_chk:%x, tcp checksum failed, ignored\n", tcp_chk); + // return -1; } - char *tcp_begin=ip_payload; //ip packet's data part + char *tcp_begin = ip_payload; // ip packet's data part - char *tcp_option=ip_payload+sizeof(my_tcphdr); - char *option_end=ip_payload+tcphdrlen; + char *tcp_option = ip_payload + sizeof(my_tcphdr); + char *option_end = ip_payload + tcphdrlen; /* //old ts parse code @@ -2572,182 +2252,167 @@ int recv_raw_tcp(raw_info_t &raw_info,char * &payload,int &payloadlen) recv_info.ts=0; if(tcph->doff==10) { - if(tcp_option[6]==0x08 &&tcp_option[7]==0x0a) - { - recv_info.has_ts=1; - //recv_info.ts=ntohl(*(u32_t*)(&tcp_option[8])); - memcpy(&recv_info.ts,&tcp_option[8],sizeof(recv_info.ts)); - recv_info.ts=ntohl(recv_info.ts); + if(tcp_option[6]==0x08 &&tcp_option[7]==0x0a) + { + recv_info.has_ts=1; + //recv_info.ts=ntohl(*(u32_t*)(&tcp_option[8])); + memcpy(&recv_info.ts,&tcp_option[8],sizeof(recv_info.ts)); + recv_info.ts=ntohl(recv_info.ts); - //recv_info.ts_ack=ntohl(*(u32_t*)(&tcp_option[12])); - memcpy(&recv_info.ts_ack,&tcp_option[12],sizeof(recv_info.ts_ack)); - recv_info.ts_ack=ntohl(recv_info.ts_ack); + //recv_info.ts_ack=ntohl(*(u32_t*)(&tcp_option[12])); + memcpy(&recv_info.ts_ack,&tcp_option[12],sizeof(recv_info.ts_ack)); + recv_info.ts_ack=ntohl(recv_info.ts_ack); - //g_packet_info_send.ts_ack= ntohl(*(uint32_t*)(&tcp_option[8])); - } - else - { - // mylog(log_info,"\n"); - } + //g_packet_info_send.ts_ack= ntohl(*(uint32_t*)(&tcp_option[8])); + } + else + { + // mylog(log_info,"\n"); + } } else if(tcph->doff==8) { - if(tcp_option[2]==0x08 &&tcp_option[3]==0x0a) - { - recv_info.has_ts=1; - //recv_info.ts=ntohl(*(u32_t*)(&tcp_option[4])); - memcpy(&recv_info.ts,&tcp_option[4],sizeof(recv_info.ts)); - recv_info.ts=ntohl(recv_info.ts); - //recv_info.ts_ack=ntohl(*(u32_t*)(&tcp_option[8])); - memcpy(&recv_info.ts_ack,&tcp_option[8],sizeof(recv_info.ts_ack)); - recv_info.ts_ack=ntohl(recv_info.ts_ack); - //g_packet_info_send.ts_ack= ntohl(*(uint32_t*)(&tcp_option[0])); - } - else - { - //mylog(log_info,"!!!\n"); - } + if(tcp_option[2]==0x08 &&tcp_option[3]==0x0a) + { + recv_info.has_ts=1; + //recv_info.ts=ntohl(*(u32_t*)(&tcp_option[4])); + memcpy(&recv_info.ts,&tcp_option[4],sizeof(recv_info.ts)); + recv_info.ts=ntohl(recv_info.ts); + //recv_info.ts_ack=ntohl(*(u32_t*)(&tcp_option[8])); + memcpy(&recv_info.ts_ack,&tcp_option[8],sizeof(recv_info.ts_ack)); + recv_info.ts_ack=ntohl(recv_info.ts_ack); + //g_packet_info_send.ts_ack= ntohl(*(uint32_t*)(&tcp_option[0])); + } + else + { + //mylog(log_info,"!!!\n"); + } } else { - //mylog(log_info,"tcph->doff= %u\n",tcph->doff); + //mylog(log_info,"tcph->doff= %u\n",tcph->doff); } printf("<%d %d>\n",recv_info.ts,recv_info.ts_ack); */ - parse_tcp_option(tcp_option,option_end,recv_info); + parse_tcp_option(tcp_option, option_end, recv_info); - recv_info.ack=tcph->ack; - recv_info.syn=tcph->syn; - recv_info.rst=tcph->rst; - recv_info.src_port=ntohs(tcph->source); - recv_info.dst_port=ntohs(tcph->dest); + recv_info.ack = tcph->ack; + recv_info.syn = tcph->syn; + recv_info.rst = tcph->rst; + recv_info.src_port = ntohs(tcph->source); + recv_info.dst_port = ntohs(tcph->dest); - recv_info.seq=ntohl(tcph->seq); + recv_info.seq = ntohl(tcph->seq); - // recv_info.last_last_ack_seq=recv_info.last_ack_seq; - //recv_info.last_ack_seq=recv_info.ack_seq; - u32_t last_ack_seq=recv_info.ack_seq; - recv_info.ack_seq=ntohl(tcph->ack_seq); - if(recv_info.ack_seq==last_ack_seq) - { - recv_info.ack_seq_counter++; - } - else - { - recv_info.ack_seq_counter=0; + // recv_info.last_last_ack_seq=recv_info.last_ack_seq; + // recv_info.last_ack_seq=recv_info.ack_seq; + u32_t last_ack_seq = recv_info.ack_seq; + recv_info.ack_seq = ntohl(tcph->ack_seq); + if (recv_info.ack_seq == last_ack_seq) { + recv_info.ack_seq_counter++; + } else { + recv_info.ack_seq_counter = 0; } - recv_info.psh=tcph->psh; + recv_info.psh = tcph->psh; - if(tcph->rst==1) - { - raw_info.rst_received++; + if (tcph->rst == 1) { + raw_info.rst_received++; - if(max_rst_to_show>0) - { - if(raw_info.rst_received < max_rst_to_show) - { - mylog(log_warn,"[%s,%d]rst==1,cnt=%d\n",recv_info.new_src_ip.get_str1(),recv_info.src_port,(int)raw_info.rst_received); - } - else if(raw_info.rst_received == max_rst_to_show) - { - mylog(log_warn,"[%s,%d]rst==1,cnt=%d >=max_rst_to_show, this log will be muted for current connection\n",recv_info.new_src_ip.get_str1(),recv_info.src_port,(int)raw_info.rst_received); - } - else - { - mylog(log_debug,"[%s,%d]rst==1,cnt=%d\n",recv_info.new_src_ip.get_str1(),recv_info.src_port,(int)raw_info.rst_received); - } - } - else if(max_rst_to_show==0) - { - mylog(log_debug,"[%s,%d]rst==1,cnt=%d\n",recv_info.new_src_ip.get_str1(),recv_info.src_port,(int)raw_info.rst_received); - } - else - { - mylog(log_warn,"[%s,%d]rst==1,cnt=%d\n",recv_info.new_src_ip.get_str1(),recv_info.src_port,(int)raw_info.rst_received); - } + if (max_rst_to_show > 0) { + if (raw_info.rst_received < max_rst_to_show) { + mylog(log_warn, "[%s,%d]rst==1,cnt=%d\n", recv_info.new_src_ip.get_str1(), recv_info.src_port, (int)raw_info.rst_received); + } else if (raw_info.rst_received == max_rst_to_show) { + mylog(log_warn, "[%s,%d]rst==1,cnt=%d >=max_rst_to_show, this log will be muted for current connection\n", recv_info.new_src_ip.get_str1(), recv_info.src_port, (int)raw_info.rst_received); + } else { + mylog(log_debug, "[%s,%d]rst==1,cnt=%d\n", recv_info.new_src_ip.get_str1(), recv_info.src_port, (int)raw_info.rst_received); + } + } else if (max_rst_to_show == 0) { + mylog(log_debug, "[%s,%d]rst==1,cnt=%d\n", recv_info.new_src_ip.get_str1(), recv_info.src_port, (int)raw_info.rst_received); + } else { + mylog(log_warn, "[%s,%d]rst==1,cnt=%d\n", recv_info.new_src_ip.get_str1(), recv_info.src_port, (int)raw_info.rst_received); + } - if(max_rst_allowed>=0 && raw_info.rst_received==max_rst_allowed+1 ) - { - mylog(log_warn,"[%s,%d]connection disabled because of rst_received=%d > max_rst_allow=%d\n",recv_info.new_src_ip.get_str1(),recv_info.src_port,(int)raw_info.rst_received,(int)max_rst_allowed ); - raw_info.disabled=1; - } + if (max_rst_allowed >= 0 && raw_info.rst_received == max_rst_allowed + 1) { + mylog(log_warn, "[%s,%d]connection disabled because of rst_received=%d > max_rst_allow=%d\n", recv_info.new_src_ip.get_str1(), recv_info.src_port, (int)raw_info.rst_received, (int)max_rst_allowed); + raw_info.disabled = 1; + } } - /* if(recv_info.has_ts) + /* if(recv_info.has_ts) + { + send_info.ts_ack=recv_info.ts; //////////////////////////////////////////////modify + }*/ + + payloadlen = ip_payloadlen - tcphdrlen; + + payload = tcp_begin + tcphdrlen; + + /*if (recv_info.syn == 0 && recv_info.ack == 1&& payloadlen != 0) //only modify send_info when the packet is not part of handshake { - send_info.ts_ack=recv_info.ts; //////////////////////////////////////////////modify + send_info.ack_seq=recv_info.seq; }*/ - - payloadlen = ip_payloadlen-tcphdrlen; - - payload=tcp_begin+tcphdrlen; - - /*if (recv_info.syn == 0 && recv_info.ack == 1&& payloadlen != 0) //only modify send_info when the packet is not part of handshake - { - send_info.ack_seq=recv_info.seq; - }*/ - raw_info.recv_info.data_len=payloadlen; + raw_info.recv_info.data_len = payloadlen; return 0; } /* int recv_raw_tcp_deprecated(packet_info_t &info,char * &payload,int &payloadlen) { - static char buf[buf_len]; + static char buf[buf_len]; - char raw_recv_buf[buf_len]; - char raw_recv_buf2[buf_len]; - char raw_recv_buf3[buf_len]; + char raw_recv_buf[buf_len]; + char raw_recv_buf2[buf_len]; + char raw_recv_buf3[buf_len]; - iphdr * iph; - tcphdr * tcph; - int size; - struct sockaddr saddr; - socklen_t saddr_size; - saddr_size = sizeof(saddr); + iphdr * iph; + tcphdr * tcph; + int size; + struct sockaddr saddr; + socklen_t saddr_size; + saddr_size = sizeof(saddr); - mylog(log_trace,"raw!\n"); + mylog(log_trace,"raw!\n"); - size = recvfrom(raw_recv_fd, buf, max_data_len, 0 ,&saddr , &saddr_size); + size = recvfrom(raw_recv_fd, buf, max_data_len, 0 ,&saddr , &saddr_size); - if(buf[12]!=8||buf[13]!=0) - { - mylog(log_debug,"not an ipv4 packet!\n"); - return -1; - } + if(buf[12]!=8||buf[13]!=0) + { + mylog(log_debug,"not an ipv4 packet!\n"); + return -1; + } - char *ip_begin=buf+14; + char *ip_begin=buf+14; - iph = (struct iphdr *) (ip_begin); + iph = (struct iphdr *) (ip_begin); if (!(iph->ihl > 0 && iph->ihl <=60)) { - mylog(log_debug,"iph ihl error"); + mylog(log_debug,"iph ihl error"); return -1; } if (iph->protocol != IPPROTO_TCP) { - mylog(log_debug,"iph protocal != tcp\n"); - return -1; + mylog(log_debug,"iph protocal != tcp\n"); + return -1; } - int ip_len=ntohs(iph->tot_len); + int ip_len=ntohs(iph->tot_len); unsigned short iphdrlen =iph->ihl*4; tcph=(struct tcphdr*)(ip_begin+ iphdrlen); unsigned short tcphdrlen = tcph->doff*4; if (!(tcph->doff > 0 && tcph->doff <=60)) { - mylog(log_debug,"tcph error"); - return 0; + mylog(log_debug,"tcph error"); + return 0; } if(tcph->dest!=ntohs(uint16_t(filter_port))) { - //printf("%x %x",tcph->dest,); - return -1; + //printf("%x %x",tcph->dest,); + return -1; } /////ip uint32_t ip_chk=csum ((unsigned short *) ip_begin, iphdrlen); @@ -2773,14 +2438,14 @@ int recv_raw_tcp_deprecated(packet_info_t &info,char * &payload,int &payloadlen) if(ip_chk!=0) { - mylog(log_debug,"ip header error %d\n",ip_chk); - return -1; + mylog(log_debug,"ip header error %d\n",ip_chk); + return -1; } if(tcp_chk!=0) { - mylog(log_debug,"tcp_chk:%x\n",tcp_chk); - mylog(log_debug,"tcp header error\n"); - return -1; + mylog(log_debug,"tcp_chk:%x\n",tcp_chk); + mylog(log_debug,"tcp header error\n"); + return -1; } char *tcp_begin=raw_recv_buf2+sizeof(struct pseudo_header); //ip packet's data part @@ -2791,28 +2456,28 @@ int recv_raw_tcp_deprecated(packet_info_t &info,char * &payload,int &payloadlen) if(tcph->doff==10) { - if(tcp_option[6]==0x08 &&tcp_option[7]==0x0a) - { - info.has_ts=1; - info.ts=ntohl(*(uint32_t*)(&tcp_option[8])); - info.ts_ack=ntohl(*(uint32_t*)(&tcp_option[12])); - //g_packet_info_send.ts_ack= ntohl(*(uint32_t*)(&tcp_option[8])); - } + if(tcp_option[6]==0x08 &&tcp_option[7]==0x0a) + { + info.has_ts=1; + info.ts=ntohl(*(uint32_t*)(&tcp_option[8])); + info.ts_ack=ntohl(*(uint32_t*)(&tcp_option[12])); + //g_packet_info_send.ts_ack= ntohl(*(uint32_t*)(&tcp_option[8])); + } } else if(tcph->doff==8) { - if(tcp_option[3]==0x08 &&tcp_option[4]==0x0a) - { - info.has_ts=1; - info.ts=ntohl(*(uint32_t*)(&tcp_option[0])); - info.ts_ack=ntohl(*(uint32_t*)(&tcp_option[4])); - //g_packet_info_send.ts_ack= ntohl(*(uint32_t*)(&tcp_option[0])); - } + if(tcp_option[3]==0x08 &&tcp_option[4]==0x0a) + { + info.has_ts=1; + info.ts=ntohl(*(uint32_t*)(&tcp_option[0])); + info.ts_ack=ntohl(*(uint32_t*)(&tcp_option[4])); + //g_packet_info_send.ts_ack= ntohl(*(uint32_t*)(&tcp_option[0])); + } } if(tcph->rst==1) { - mylog(log_warn,"%%%%%%%%%%rst==1%%%%%%%%%%%%%\n"); + mylog(log_warn,"%%%%%%%%%%rst==1%%%%%%%%%%%%%\n"); } @@ -2826,7 +2491,7 @@ int recv_raw_tcp_deprecated(packet_info_t &info,char * &payload,int &payloadlen) info.psh=tcph->psh; if(info.has_ts) { - g_packet_info_send.ts_ack=info.ts; + g_packet_info_send.ts_ack=info.ts; } ////tcp end @@ -2837,13 +2502,13 @@ int recv_raw_tcp_deprecated(packet_info_t &info,char * &payload,int &payloadlen) if(payloadlen>0&&payload[0]=='h') { - mylog(log_debug,"recvd <%u %u %d>\n",ntohl(tcph->seq ),ntohl(tcph->ack_seq), payloadlen); + mylog(log_debug,"recvd <%u %u %d>\n",ntohl(tcph->seq ),ntohl(tcph->ack_seq), payloadlen); } if(payloadlen>0&&tcph->syn==0&&tcph->ack==1) { - //if(seq_increse) - g_packet_info_send.ack_seq=ntohl(tcph->seq)+(uint32_t)payloadlen; + //if(seq_increse) + g_packet_info_send.ack_seq=ntohl(tcph->seq)+(uint32_t)payloadlen; } @@ -2852,197 +2517,178 @@ int recv_raw_tcp_deprecated(packet_info_t &info,char * &payload,int &payloadlen) mylog(log_trace,"<%u,%u,%u,%u,%d>\n",(unsigned int)iphdrlen,(unsigned int)tcphdrlen,(unsigned int)tcph->syn,(unsigned int)tcph->ack,payloadlen); - return 0; + return 0; }*/ -int send_raw0(raw_info_t &raw_info,const char * payload,int payloadlen) -{ - if (random_drop != 0) { - if (get_true_random_number() % 10000 < (u32_t) random_drop) { - return 0; - } - } - - packet_info_t &send_info=raw_info.send_info; - packet_info_t &recv_info=raw_info.recv_info; - mylog(log_trace,"send_raw : from %s %d to %s %d\n",send_info.new_src_ip.get_str1(),send_info.src_port,send_info.new_dst_ip.get_str2(),send_info.dst_port); - switch(raw_mode) - { - case mode_faketcp:return send_raw_tcp(raw_info,payload,payloadlen); - case mode_udp: return send_raw_udp(raw_info,payload,payloadlen); - case mode_icmp: return send_raw_icmp(raw_info,payload,payloadlen); - default:return -1; - } +int send_raw0(raw_info_t &raw_info, const char *payload, int payloadlen) { + if (random_drop != 0) { + if (get_true_random_number() % 10000 < (u32_t)random_drop) { + return 0; + } + } + packet_info_t &send_info = raw_info.send_info; + packet_info_t &recv_info = raw_info.recv_info; + mylog(log_trace, "send_raw : from %s %d to %s %d\n", send_info.new_src_ip.get_str1(), send_info.src_port, send_info.new_dst_ip.get_str2(), send_info.dst_port); + switch (raw_mode) { + case mode_faketcp: + return send_raw_tcp(raw_info, payload, payloadlen); + case mode_udp: + return send_raw_udp(raw_info, payload, payloadlen); + case mode_icmp: + return send_raw_icmp(raw_info, payload, payloadlen); + default: + return -1; + } } -int recv_raw0(raw_info_t &raw_info,char * &payload,int &payloadlen) -{ - packet_info_t &send_info=raw_info.send_info; - packet_info_t &recv_info=raw_info.recv_info; - switch(raw_mode) - { - case mode_faketcp:return recv_raw_tcp(raw_info,payload,payloadlen); - case mode_udp: return recv_raw_udp(raw_info,payload,payloadlen); - case mode_icmp: return recv_raw_icmp(raw_info,payload,payloadlen); - default: return -1; - } - +int recv_raw0(raw_info_t &raw_info, char *&payload, int &payloadlen) { + packet_info_t &send_info = raw_info.send_info; + packet_info_t &recv_info = raw_info.recv_info; + switch (raw_mode) { + case mode_faketcp: + return recv_raw_tcp(raw_info, payload, payloadlen); + case mode_udp: + return recv_raw_udp(raw_info, payload, payloadlen); + case mode_icmp: + return recv_raw_icmp(raw_info, payload, payloadlen); + default: + return -1; + } } -int after_send_raw0(raw_info_t &raw_info) -{ - packet_info_t &send_info=raw_info.send_info; - packet_info_t &recv_info=raw_info.recv_info; +int after_send_raw0(raw_info_t &raw_info) { + packet_info_t &send_info = raw_info.send_info; + packet_info_t &recv_info = raw_info.recv_info; - if(raw_mode==mode_faketcp) - { - if (send_info.syn == 0 && send_info.ack == 1&& raw_info.send_info.data_len != 0) //only modify send_info when the packet is not part of handshake - { - if (seq_mode == 0) - { + if (raw_mode == mode_faketcp) { + if (send_info.syn == 0 && send_info.ack == 1 && raw_info.send_info.data_len != 0) // only modify send_info when the packet is not part of handshake + { + if (seq_mode == 0) { + } else if (seq_mode == 1) { + send_info.seq += raw_info.send_info.data_len; //////////////////modify + } else if (seq_mode == 2) { + if (get_true_random_number() % 5 == 3) + send_info.seq += raw_info.send_info.data_len; //////////////////modify + } else if (seq_mode == 3 || seq_mode == 4) { + send_info.seq += raw_info.send_info.data_len; - } else if (seq_mode == 1) - { - send_info.seq += raw_info.send_info.data_len; //////////////////modify - } else if (seq_mode == 2) - { - if (get_true_random_number() % 5 == 3) - send_info.seq += raw_info.send_info.data_len; //////////////////modify - } - else if(seq_mode==3||seq_mode==4) - { - send_info.seq += raw_info.send_info.data_len; + u32_t window_size; - u32_t window_size; + if (seq_mode == 3) { + window_size = (u32_t)((u32_t)receive_window_lower_bound << (u32_t)wscale); + } else // seq_mode==4 + { + window_size = (u32_t)((u32_t)receive_window_lower_bound); + } - if(seq_mode==3) - { - window_size=(u32_t)((u32_t)receive_window_lower_bound<<(u32_t)wscale); - } - else//seq_mode==4 - { - window_size=(u32_t)((u32_t)receive_window_lower_bound); - } - - if(larger_than_u32(send_info.seq+max_data_len,recv_info.ack_seq+window_size)) - { - send_info.seq=raw_info.recv_info.ack_seq; - } - if(recv_info.ack_seq_counter>=3) //simulate tcp fast re-transmit - { - recv_info.ack_seq_counter=0; - send_info.seq=raw_info.recv_info.ack_seq; - } - if(larger_than_u32(raw_info.recv_info.ack_seq,send_info.seq)) //for further use,currently no effect. - { - send_info.seq=raw_info.recv_info.ack_seq; - } - } - } - } - if(raw_mode==mode_icmp) - { - if(program_mode==client_mode) - { - send_info.my_icmp_seq++; - } - } - return 0; + if (larger_than_u32(send_info.seq + max_data_len, recv_info.ack_seq + window_size)) { + send_info.seq = raw_info.recv_info.ack_seq; + } + if (recv_info.ack_seq_counter >= 3) // simulate tcp fast re-transmit + { + recv_info.ack_seq_counter = 0; + send_info.seq = raw_info.recv_info.ack_seq; + } + if (larger_than_u32(raw_info.recv_info.ack_seq, send_info.seq)) // for further use,currently no effect. + { + send_info.seq = raw_info.recv_info.ack_seq; + } + } + } + } + if (raw_mode == mode_icmp) { + if (program_mode == client_mode) { + send_info.my_icmp_seq++; + } + } + return 0; } -int after_recv_raw0(raw_info_t &raw_info) -{ - packet_info_t &send_info=raw_info.send_info; - packet_info_t &recv_info=raw_info.recv_info; +int after_recv_raw0(raw_info_t &raw_info) { + packet_info_t &send_info = raw_info.send_info; + packet_info_t &recv_info = raw_info.recv_info; - if(raw_mode==mode_faketcp) - { - if(recv_info.has_ts) - send_info.ts_ack=recv_info.ts; - if (recv_info.syn == 0 && recv_info.ack == 1 && raw_info.recv_info.data_len != 0) //only modify send_info when the packet is not part of handshake - { - if(seq_mode==0||seq_mode==1||seq_mode==2) - { - if(larger_than_u32(recv_info.seq+raw_info.recv_info.data_len,send_info.ack_seq)) - send_info.ack_seq = recv_info.seq+raw_info.recv_info.data_len;//TODO only update if its larger - } - else if(seq_mode==3||seq_mode==4) - { - if(recv_info.seq==send_info.ack_seq) - { - send_info.ack_seq=recv_info.seq+raw_info.recv_info.data_len;//currently we dont remembr tcp segments,this is the simplest way - //TODO implement tcp segment remembering and SACK. - } - } - } - } - if(raw_mode==mode_icmp) - { - if(program_mode==server_mode) - { - if(larger_than_u16(recv_info.my_icmp_seq,send_info.my_icmp_seq)) - send_info.my_icmp_seq = recv_info.my_icmp_seq; //TODO only update if its larger - } - } - return 0; + if (raw_mode == mode_faketcp) { + if (recv_info.has_ts) + send_info.ts_ack = recv_info.ts; + if (recv_info.syn == 0 && recv_info.ack == 1 && raw_info.recv_info.data_len != 0) // only modify send_info when the packet is not part of handshake + { + if (seq_mode == 0 || seq_mode == 1 || seq_mode == 2) { + if (larger_than_u32(recv_info.seq + raw_info.recv_info.data_len, send_info.ack_seq)) + send_info.ack_seq = recv_info.seq + raw_info.recv_info.data_len; // TODO only update if its larger + } else if (seq_mode == 3 || seq_mode == 4) { + if (recv_info.seq == send_info.ack_seq) { + send_info.ack_seq = recv_info.seq + raw_info.recv_info.data_len; // currently we dont remembr tcp segments,this is the simplest way + // TODO implement tcp segment remembering and SACK. + } + } + } + } + if (raw_mode == mode_icmp) { + if (program_mode == server_mode) { + if (larger_than_u16(recv_info.my_icmp_seq, send_info.my_icmp_seq)) + send_info.my_icmp_seq = recv_info.my_icmp_seq; // TODO only update if its larger + } + } + return 0; } /* int send_raw(raw_info_t &raw_info,const char * payload,int payloadlen) { - packet_info_t &send_info=raw_info.send_info; - packet_info_t &recv_info=raw_info.recv_info; - int ret=send_raw0(raw_info,payload,payloadlen); - if(ret<0) return ret; - else - { - after_send_raw0(raw_info); - return ret; - } + packet_info_t &send_info=raw_info.send_info; + packet_info_t &recv_info=raw_info.recv_info; + int ret=send_raw0(raw_info,payload,payloadlen); + if(ret<0) return ret; + else + { + after_send_raw0(raw_info); + return ret; + } } int recv_raw(raw_info_t &raw_info,char *& payload,int & payloadlen) { - packet_info_t &send_info=raw_info.send_info; - packet_info_t &recv_info=raw_info.recv_info; - int ret=recv_raw0(raw_info,payload,payloadlen); - if(ret<0) return ret; - else - { - after_recv_raw0(raw_info); - return ret; - } + packet_info_t &send_info=raw_info.send_info; + packet_info_t &recv_info=raw_info.recv_info; + int ret=recv_raw0(raw_info,payload,payloadlen); + if(ret<0) return ret; + else + { + after_recv_raw0(raw_info); + return ret; + } }*/ /* int get_src_adress(u32_t &ip,u32_t remote_ip_uint32,int remote_port) //a trick to get src adress for a dest adress,so that we can use the src address in raw socket as source ip { - struct sockaddr_in remote_addr_in={0}; + 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; + 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_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); + 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; - } + 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 sockaddr_in my_addr={0}; - socklen_t len=sizeof(my_addr); + struct sockaddr_in my_addr={0}; + socklen_t len=sizeof(my_addr); if(getsockname(new_udp_fd, (struct sockaddr *) &my_addr, &len)!=0){close(new_udp_fd); return -1;} @@ -3053,44 +2699,45 @@ int get_src_adress(u32_t &ip,u32_t remote_ip_uint32,int remote_port) //a trick return 0; }*/ -int get_src_adress2(address_t &output_addr,address_t remote_addr) -{ - int new_udp_fd=remote_addr.new_connected_udp_fd(); - if(new_udp_fd<0) - { - mylog(log_warn,"create udp_fd error\n"); - return -1; - } +int get_src_adress2(address_t &output_addr, address_t remote_addr) { + int new_udp_fd = remote_addr.new_connected_udp_fd(); + if (new_udp_fd < 0) { + mylog(log_warn, "create udp_fd error\n"); + return -1; + } - socklen_t len=sizeof(output_addr.inner); + socklen_t len = sizeof(output_addr.inner); - if(getsockname(new_udp_fd, (struct sockaddr *) &output_addr.inner, &len)!=0) {close(new_udp_fd); return -1;} + if (getsockname(new_udp_fd, (struct sockaddr *)&output_addr.inner, &len) != 0) { + close(new_udp_fd); + return -1; + } - assert(output_addr.get_type()==remote_addr.get_type()); + assert(output_addr.get_type() == remote_addr.get_type()); close(new_udp_fd); - return 0; + return 0; } /* int try_to_list_and_bind(int &fd,u32_t local_ip_uint32,int port) //try to bind to a port,may fail. { - int old_bind_fd=fd; + int old_bind_fd=fd; - if(raw_mode==mode_faketcp) - { - fd=socket(AF_INET,SOCK_STREAM,0); - } - else if(raw_mode==mode_udp||raw_mode==mode_icmp) - { - fd=socket(AF_INET,SOCK_DGRAM,0); - } + if(raw_mode==mode_faketcp) + { + fd=socket(AF_INET,SOCK_STREAM,0); + } + else if(raw_mode==mode_udp||raw_mode==mode_icmp) + { + fd=socket(AF_INET,SOCK_DGRAM,0); + } if(old_bind_fd!=-1) { - close(old_bind_fd); + close(old_bind_fd); } - struct sockaddr_in temp_bind_addr={0}; + struct sockaddr_in temp_bind_addr={0}; //bzero(&temp_bind_addr, sizeof(temp_bind_addr)); temp_bind_addr.sin_family = AF_INET; @@ -3099,90 +2746,81 @@ int try_to_list_and_bind(int &fd,u32_t local_ip_uint32,int port) //try to bind if (bind(fd, (struct sockaddr*)&temp_bind_addr, sizeof(temp_bind_addr)) !=0) { - mylog(log_debug,"bind fail\n"); - return -1; + mylog(log_debug,"bind fail\n"); + return -1; } - if(raw_mode==mode_faketcp) - { + if(raw_mode==mode_faketcp) + { - if (listen(fd, SOMAXCONN) != 0) { - mylog(log_warn,"listen fail\n"); - return -1; - } - } + if (listen(fd, SOMAXCONN) != 0) { + mylog(log_warn,"listen fail\n"); + return -1; + } + } return 0; }*/ -int try_to_list_and_bind2(int &fd,address_t address) //try to bind to a port,may fail. +int try_to_list_and_bind2(int &fd, address_t address) // try to bind to a port,may fail. { - if(fd!=-1) - { - close(fd); - } - if(raw_mode==mode_faketcp) - { - fd=socket(address.get_type(),SOCK_STREAM,0); - } - else if(raw_mode==mode_udp||raw_mode==mode_icmp) - { - fd=socket(address.get_type(),SOCK_DGRAM,0); - } + if (fd != -1) { + close(fd); + } + if (raw_mode == mode_faketcp) { + fd = socket(address.get_type(), SOCK_STREAM, 0); + } else if (raw_mode == mode_udp || raw_mode == mode_icmp) { + fd = socket(address.get_type(), SOCK_DGRAM, 0); + } - if(fd==-1) - { - mylog(log_debug,"create fd fail\n"); - return -1; - } - /*struct sockaddr_in temp_bind_addr={0}; - //bzero(&temp_bind_addr, sizeof(temp_bind_addr)); + if (fd == -1) { + mylog(log_debug, "create fd fail\n"); + return -1; + } + /*struct sockaddr_in temp_bind_addr={0}; + //bzero(&temp_bind_addr, sizeof(temp_bind_addr)); - temp_bind_addr.sin_family = AF_INET; - temp_bind_addr.sin_port = htons(port); - temp_bind_addr.sin_addr.s_addr = local_ip_uint32;*/ + temp_bind_addr.sin_family = AF_INET; + temp_bind_addr.sin_port = htons(port); + temp_bind_addr.sin_addr.s_addr = local_ip_uint32;*/ - if (::bind(fd, (struct sockaddr*)&address.inner, address.get_len()) !=0) - { - mylog(log_debug,"bind fail\n"); - return -1; - } - if(raw_mode==mode_faketcp&&!use_tcp_dummy_socket) - { - - if (listen(fd, SOMAXCONN) != 0) { - mylog(log_warn,"listen fail\n"); - return -1; - } - } - return 0; + if (::bind(fd, (struct sockaddr *)&address.inner, address.get_len()) != 0) { + mylog(log_debug, "bind fail\n"); + return -1; + } + if (raw_mode == mode_faketcp && !use_tcp_dummy_socket) { + if (listen(fd, SOMAXCONN) != 0) { + mylog(log_warn, "listen fail\n"); + return -1; + } + } + return 0; } /* int client_bind_to_a_new_port(int &fd,u32_t local_ip_uint32)//find a free port and bind to it. { - int raw_send_port=10000+get_true_random_number()%(65535-10000); - for(int i=0;i<1000;i++)//try 1000 times at max,this should be enough - { - if (try_to_list_and_bind(fd,local_ip_uint32,raw_send_port)==0) - { - return raw_send_port; - } - } - mylog(log_fatal,"bind port fail\n"); - myexit(-1); - return -1;////for compiler check + int raw_send_port=10000+get_true_random_number()%(65535-10000); + for(int i=0;i<1000;i++)//try 1000 times at max,this should be enough + { + if (try_to_list_and_bind(fd,local_ip_uint32,raw_send_port)==0) + { + return raw_send_port; + } + } + mylog(log_fatal,"bind port fail\n"); + myexit(-1); + return -1;////for compiler check }*/ -int client_bind_to_a_new_port2(int &fd,const address_t& address)//find a free port and bind to it. +int client_bind_to_a_new_port2(int &fd, const address_t &address) // find a free port and bind to it. { - address_t tmp=address; - for(int i=0;i<1000;i++)//try 1000 times at max,this should be enough - { - int raw_send_port=10000+get_true_random_number()%(65535-10000); - tmp.set_port(raw_send_port); - if (try_to_list_and_bind2(fd,tmp)==0) - { - return raw_send_port; - } - } - mylog(log_fatal,"bind port fail\n"); - myexit(-1); - return -1;////for compiler check + address_t tmp = address; + for (int i = 0; i < 1000; i++) // try 1000 times at max,this should be enough + { + int raw_send_port = 10000 + get_true_random_number() % (65535 - 10000); + tmp.set_port(raw_send_port); + if (try_to_list_and_bind2(fd, tmp) == 0) { + return raw_send_port; + } + } + mylog(log_fatal, "bind port fail\n"); + myexit(-1); + return -1; ////for compiler check } diff --git a/network.h b/network.h index 2e00791..dbeb0bf 100644 --- a/network.h +++ b/network.h @@ -14,7 +14,7 @@ extern int use_tcp_dummy_socket; extern int seq_mode; extern int max_seq_mode; extern int filter_port; -//extern u32_t bind_address_uint32; +// extern u32_t bind_address_uint32; extern int disable_bpf_filter; extern int lower_level; @@ -34,7 +34,7 @@ extern int g_packet_buf_cnt; extern queue_t my_queue; extern ev_async async_watcher; -extern struct ev_loop* g_default_loop; +extern struct ev_loop *g_default_loop; extern pthread_mutex_t queue_mutex; extern int use_pcap_mutex; @@ -47,24 +47,22 @@ extern int send_with_pcap; extern int pcap_header_captured; extern int pcap_header_buf[buf_len]; -struct icmphdr -{ - uint8_t type; - uint8_t code; - uint16_t check_sum; - uint16_t id; - uint16_t seq; +struct icmphdr { + uint8_t type; + uint8_t code; + uint16_t check_sum; + uint16_t id; + uint16_t seq; }; #endif -struct my_iphdr - { +struct my_iphdr { #ifdef UDP2RAW_LITTLE_ENDIAN - unsigned char ihl:4; - unsigned char version:4; + unsigned char ihl : 4; + unsigned char version : 4; #else - unsigned char version:4; - unsigned char ihl:4; + unsigned char version : 4; + unsigned char ihl : 4; #endif u_int8_t tos; u_int16_t tot_len; @@ -76,105 +74,98 @@ struct my_iphdr u_int32_t saddr; u_int32_t daddr; /*The options start here. */ - }; - - -struct my_udphdr -{ - /*__extension__*/ union - { - struct - { - u_int16_t uh_sport; /* source port */ - u_int16_t uh_dport; /* destination port */ - u_int16_t uh_ulen; /* udp length */ - u_int16_t uh_sum; /* udp checksum */ - }; - struct - { - u_int16_t source; - u_int16_t dest; - u_int16_t len; - u_int16_t check; - }; - }; }; - -struct my_tcphdr - { - /*__extension__*/ union - { - struct - { - u_int16_t th_sport; /* source port */ - u_int16_t th_dport; /* destination port */ - u_int32_t th_seq; /* sequence number */ - u_int32_t th_ack; /* acknowledgement number */ -# ifdef UDP2RAW_LITTLE_ENDIAN - u_int8_t th_x2:4; /* (unused) */ - u_int8_t tc_off:4; /* data offset */ -# else - u_int8_t th_off:4; /* data offset */ - u_int8_t th_x2:4; /* (unused) */ -# endif - u_int8_t th_flags; -# define TH_FIN 0x01 -# define TH_SYN 0x02 -# define TH_RST 0x04 -# define TH_PUSH 0x08 -# define TH_ACK 0x10 -# define TH_URG 0x20 - u_int16_t th_win; /* window */ - u_int16_t th_sum; /* checksum */ - u_int16_t th_urp; /* urgent pointer */ - }; - struct - { - u_int16_t source; - u_int16_t dest; - u_int32_t seq; - u_int32_t ack_seq; -# ifdef UDP2RAW_LITTLE_ENDIAN - u_int16_t res1:4; - u_int16_t doff:4; - u_int16_t fin:1; - u_int16_t syn:1; - u_int16_t rst:1; - u_int16_t psh:1; - u_int16_t ack:1; - u_int16_t urg:1; - u_int16_t res2:2; -# else - u_int16_t doff:4; - u_int16_t res1:4; - u_int16_t res2:2; - u_int16_t urg:1; - u_int16_t ack:1; - u_int16_t psh:1; - u_int16_t rst:1; - u_int16_t syn:1; - u_int16_t fin:1; -# endif - u_int16_t window; - u_int16_t check; - u_int16_t urg_ptr; - }; +struct my_udphdr { + /*__extension__*/ union { + struct + { + u_int16_t uh_sport; /* source port */ + u_int16_t uh_dport; /* destination port */ + u_int16_t uh_ulen; /* udp length */ + u_int16_t uh_sum; /* udp checksum */ + }; + struct + { + u_int16_t source; + u_int16_t dest; + u_int16_t len; + u_int16_t check; + }; }; }; -struct my_ip6hdr - { -# ifdef UDP2RAW_LITTLE_ENDIAN - uint8_t traffic_class_high:4; - uint8_t version:4; - uint8_t flow_label_high:4; - uint8_t traffic_class_low:4; +struct my_tcphdr { + /*__extension__*/ union { + struct + { + u_int16_t th_sport; /* source port */ + u_int16_t th_dport; /* destination port */ + u_int32_t th_seq; /* sequence number */ + u_int32_t th_ack; /* acknowledgement number */ +#ifdef UDP2RAW_LITTLE_ENDIAN + u_int8_t th_x2 : 4; /* (unused) */ + u_int8_t tc_off : 4; /* data offset */ #else - uint8_t version:4; - uint8_t traffic_class_high:4; - uint8_t traffic_class_low:4; - uint8_t flow_label_high:4; + u_int8_t th_off : 4; /* data offset */ + u_int8_t th_x2 : 4; /* (unused) */ +#endif + u_int8_t th_flags; +#define TH_FIN 0x01 +#define TH_SYN 0x02 +#define TH_RST 0x04 +#define TH_PUSH 0x08 +#define TH_ACK 0x10 +#define TH_URG 0x20 + u_int16_t th_win; /* window */ + u_int16_t th_sum; /* checksum */ + u_int16_t th_urp; /* urgent pointer */ + }; + struct + { + u_int16_t source; + u_int16_t dest; + u_int32_t seq; + u_int32_t ack_seq; +#ifdef UDP2RAW_LITTLE_ENDIAN + u_int16_t res1 : 4; + u_int16_t doff : 4; + u_int16_t fin : 1; + u_int16_t syn : 1; + u_int16_t rst : 1; + u_int16_t psh : 1; + u_int16_t ack : 1; + u_int16_t urg : 1; + u_int16_t res2 : 2; +#else + u_int16_t doff : 4; + u_int16_t res1 : 4; + u_int16_t res2 : 2; + u_int16_t urg : 1; + u_int16_t ack : 1; + u_int16_t psh : 1; + u_int16_t rst : 1; + u_int16_t syn : 1; + u_int16_t fin : 1; +#endif + u_int16_t window; + u_int16_t check; + u_int16_t urg_ptr; + }; + }; +}; + +struct my_ip6hdr { +#ifdef UDP2RAW_LITTLE_ENDIAN + uint8_t traffic_class_high : 4; + uint8_t version : 4; + uint8_t flow_label_high : 4; + uint8_t traffic_class_low : 4; +#else + uint8_t version : 4; + uint8_t traffic_class_high : 4; + uint8_t traffic_class_low : 4; + uint8_t flow_label_high : 4; #endif u_int16_t flow_label_low; u_int16_t payload_len; @@ -183,15 +174,14 @@ struct my_ip6hdr struct in6_addr src; struct in6_addr dst; - }; +}; -struct my_icmphdr -{ - uint8_t type; - uint8_t code; - uint16_t check_sum; - uint16_t id; - uint16_t seq; +struct my_icmphdr { + uint8_t type; + uint8_t code; + uint16_t check_sum; + uint16_t id; + uint16_t seq; }; struct pseudo_header { @@ -211,57 +201,53 @@ struct pseudo_header6 { u_int8_t next_header; }; -struct packet_info_t //todo change this to union +struct packet_info_t // todo change this to union { - uint8_t protocol; + uint8_t protocol; + // u32_t src_ip; + // u32_t dst_ip; + my_ip_t new_src_ip; + my_ip_t new_dst_ip; - //u32_t src_ip; - //u32_t dst_ip; - my_ip_t new_src_ip; - my_ip_t new_dst_ip; + uint16_t src_port; + uint16_t dst_port; - uint16_t src_port; - uint16_t dst_port; + // tcp_part: + bool syn, ack, psh, rst; - //tcp_part: - bool syn,ack,psh,rst; + u32_t seq, ack_seq; - u32_t seq,ack_seq; + u32_t ack_seq_counter; - u32_t ack_seq_counter; + u32_t ts, ts_ack; - u32_t ts,ts_ack; + uint16_t my_icmp_seq; - - uint16_t my_icmp_seq; - - bool has_ts; + bool has_ts; #ifdef UDP2RAW_LINUX - sockaddr_ll addr_ll; + sockaddr_ll addr_ll; #endif - i32_t data_len; + i32_t data_len; - packet_info_t(); + packet_info_t(); }; -struct raw_info_t -{ - packet_info_t send_info; - packet_info_t recv_info; - //int last_send_len; - //int last_recv_len; - bool peek=0; - //bool csum=1; - u32_t reserved_send_seq; - //uint32_t first_seq,first_ack_seq; - int rst_received=0; - bool disabled=0; - -};//g_raw_info; +struct raw_info_t { + packet_info_t send_info; + packet_info_t recv_info; + // int last_send_len; + // int last_recv_len; + bool peek = 0; + // bool csum=1; + u32_t reserved_send_seq; + // uint32_t first_seq,first_ack_seq; + int rst_received = 0; + bool disabled = 0; +}; // g_raw_info; int init_raw_socket(); @@ -270,56 +256,55 @@ void init_filter(int port); void remove_filter(); #ifdef UDP2RAW_LINUX -int init_ifindex(const char * if_name,int fd,int &index); +int init_ifindex(const char *if_name, int fd, int &index); #endif #ifdef UDP2RAW_MP -int init_ifindex(const char * if_name,int &index); +int init_ifindex(const char *if_name, int &index); #endif -int find_lower_level_info(u32_t ip,u32_t &dest_ip,string &if_name,string &hw); +int find_lower_level_info(u32_t ip, u32_t &dest_ip, string &if_name, string &hw); -int get_src_adress(u32_t &ip,u32_t remote_ip_uint32,int remote_port); //a trick to get src adress for a dest adress,so that we can use the src address in raw socket as source ip -int get_src_adress2(address_t &output_addr,address_t remote_addr); +int get_src_adress(u32_t &ip, u32_t remote_ip_uint32, int remote_port); // a trick to get src adress for a dest adress,so that we can use the src address in raw socket as source ip +int get_src_adress2(address_t &output_addr, address_t remote_addr); -int try_to_list_and_bind(int & bind_fd,u32_t local_ip_uint32,int port); //try to bind to a port,may fail. -int try_to_list_and_bind2(int &fd,address_t address); +int try_to_list_and_bind(int &bind_fd, u32_t local_ip_uint32, int port); // try to bind to a port,may fail. +int try_to_list_and_bind2(int &fd, address_t address); -int client_bind_to_a_new_port(int & bind_fd,u32_t local_ip_uint32);//find a free port and bind to it. -int client_bind_to_a_new_port2(int &fd,const address_t& address); +int client_bind_to_a_new_port(int &bind_fd, u32_t local_ip_uint32); // find a free port and bind to it. +int client_bind_to_a_new_port2(int &fd, const address_t &address); int discard_raw_packet(); int pre_recv_raw_packet(); -int send_raw_ip(raw_info_t &raw_info,const char * payload,int payloadlen); +int send_raw_ip(raw_info_t &raw_info, const char *payload, int payloadlen); int peek_raw(raw_info_t &peek_info); -int recv_raw_ip(raw_info_t &raw_info,char * &payload,int &payloadlen); +int recv_raw_ip(raw_info_t &raw_info, char *&payload, int &payloadlen); -int send_raw_icmp(raw_info_t &raw_info, const char * payload, int payloadlen); +int send_raw_icmp(raw_info_t &raw_info, const char *payload, int payloadlen); -int send_raw_udp(raw_info_t &raw_info, const char * payload, int payloadlen); +int send_raw_udp(raw_info_t &raw_info, const char *payload, int payloadlen); -int send_raw_tcp(raw_info_t &raw_info,const char * payload, int payloadlen); +int send_raw_tcp(raw_info_t &raw_info, const char *payload, int payloadlen); int recv_raw_icmp(raw_info_t &raw_info, char *&payload, int &payloadlen); int recv_raw_udp(raw_info_t &raw_info, char *&payload, int &payloadlen); -int recv_raw_tcp(raw_info_t &raw_info,char * &payload,int &payloadlen); +int recv_raw_tcp(raw_info_t &raw_info, char *&payload, int &payloadlen); -//int send_raw(raw_info_t &raw_info,const char * payload,int payloadlen); +// int send_raw(raw_info_t &raw_info,const char * payload,int payloadlen); -//int recv_raw(raw_info_t &raw_info,char * &payload,int &payloadlen); +// int recv_raw(raw_info_t &raw_info,char * &payload,int &payloadlen); -int send_raw0(raw_info_t &raw_info,const char * payload,int payloadlen); +int send_raw0(raw_info_t &raw_info, const char *payload, int payloadlen); -int recv_raw0(raw_info_t &raw_info,char * &payload,int &payloadlen); +int recv_raw0(raw_info_t &raw_info, char *&payload, int &payloadlen); int after_send_raw0(raw_info_t &raw_info); int after_recv_raw0(raw_info_t &raw_info); - #endif /* NETWORK_H_ */ diff --git a/pcap_wrapper.cpp b/pcap_wrapper.cpp index 0288328..9cb1afe 100644 --- a/pcap_wrapper.cpp +++ b/pcap_wrapper.cpp @@ -2,124 +2,118 @@ #include #include #include -int (*pcap_loop )(pcap_t *, int, pcap_handler, u_char *); -int (*pcap_breakloop )(pcap_t *); +int (*pcap_loop)(pcap_t *, int, pcap_handler, u_char *); +int (*pcap_breakloop)(pcap_t *); -pcap_t* (*pcap_create)(const char *, char *); +pcap_t *(*pcap_create)(const char *, char *); -int (*pcap_set_snaplen) (pcap_t *, int)=0; -int (*pcap_set_promisc) (pcap_t *, int)=0; -int (*pcap_can_set_rfmon) (pcap_t *)=0; -int (*pcap_set_rfmon )(pcap_t *, int)=0; -int (*pcap_set_timeout)(pcap_t *, int)=0; -int (*pcap_set_buffer_size)(pcap_t *, int)=0; -int (*pcap_activate)(pcap_t *)=0; +int (*pcap_set_snaplen)(pcap_t *, int) = 0; +int (*pcap_set_promisc)(pcap_t *, int) = 0; +int (*pcap_can_set_rfmon)(pcap_t *) = 0; +int (*pcap_set_rfmon)(pcap_t *, int) = 0; +int (*pcap_set_timeout)(pcap_t *, int) = 0; +int (*pcap_set_buffer_size)(pcap_t *, int) = 0; +int (*pcap_activate)(pcap_t *) = 0; -int (*pcap_setfilter)(pcap_t *, struct bpf_program *)=0; -int (*pcap_setdirection)(pcap_t *, pcap_direction_t)=0; +int (*pcap_setfilter)(pcap_t *, struct bpf_program *) = 0; +int (*pcap_setdirection)(pcap_t *, pcap_direction_t) = 0; -int (*pcap_datalink)(pcap_t *)=0; +int (*pcap_datalink)(pcap_t *) = 0; -void (*pcap_freecode)(struct bpf_program *)=0; +void (*pcap_freecode)(struct bpf_program *) = 0; -int (*pcap_compile)(pcap_t *, struct bpf_program *, const char *, int, - bpf_u_int32)=0; +int (*pcap_compile)(pcap_t *, struct bpf_program *, const char *, int, + bpf_u_int32) = 0; -char* (*pcap_geterr)(pcap_t *)=0; -int (*pcap_sendpacket)(pcap_t *, const u_char *, int)=0; +char *(*pcap_geterr)(pcap_t *) = 0; +int (*pcap_sendpacket)(pcap_t *, const u_char *, int) = 0; -char* (*pcap_lookupdev)(char *)=0; +char *(*pcap_lookupdev)(char *) = 0; -int (*pcap_findalldevs)(pcap_if_t **, char *)=0; +int (*pcap_findalldevs)(pcap_if_t **, char *) = 0; -struct init_pcap_t -{ - init_pcap_t() - { - init_pcap(); - } - -}do_it; +struct init_pcap_t { + init_pcap_t() { + init_pcap(); + } -static void init_npcap_dll_path() -{ - BOOL(WINAPI *SetDllDirectory)(LPCTSTR); - char sysdir_name[512]; - int len; +} do_it; - SetDllDirectory = (BOOL(WINAPI *)(LPCTSTR)) GetProcAddress(GetModuleHandle("kernel32.dll"), "SetDllDirectoryA"); - if (SetDllDirectory == NULL) { - printf("Error in SetDllDirectory\n"); - } - else { - len = GetSystemDirectory(sysdir_name, 480); // be safe - if (!len) - printf("Error in GetSystemDirectory (%d)\n", (int)GetLastError()); - strcat(sysdir_name, "\\Npcap"); - if (SetDllDirectory(sysdir_name) == 0) - printf("Error in SetDllDirectory(\"System32\\Npcap\")\n"); - } +static void init_npcap_dll_path() { + BOOL(WINAPI * SetDllDirectory) + (LPCTSTR); + char sysdir_name[512]; + int len; + + SetDllDirectory = (BOOL(WINAPI *)(LPCTSTR))GetProcAddress(GetModuleHandle("kernel32.dll"), "SetDllDirectoryA"); + if (SetDllDirectory == NULL) { + printf("Error in SetDllDirectory\n"); + } else { + len = GetSystemDirectory(sysdir_name, 480); // be safe + if (!len) + printf("Error in GetSystemDirectory (%d)\n", (int)GetLastError()); + strcat(sysdir_name, "\\Npcap"); + if (SetDllDirectory(sysdir_name) == 0) + printf("Error in SetDllDirectory(\"System32\\Npcap\")\n"); + } } -#define EXPORT_FUN(XXX) do{ XXX= (__typeof__(XXX)) GetProcAddress(wpcap, #XXX); }while(0) -int init_pcap() -{ - HMODULE wpcap=LoadLibrary("wpcap.dll"); - if(wpcap!=0) - { - printf("using system32/wpcap.dll\n"); - } - else - { - init_npcap_dll_path(); - //SetDllDirectory("C:\\Windows\\System32\\Npcap\\"); - wpcap=LoadLibrary("wpcap.dll"); - if(wpcap!=0) - printf("using system32/npcap/wpcap.dll\n"); - } - if(wpcap==0) - { - printf("cant not open wpcap.dll, make sure winpcap/npcap is installed\n"); - exit(-1); - } - assert(wpcap!=0); - - EXPORT_FUN(pcap_loop); - EXPORT_FUN(pcap_breakloop); - EXPORT_FUN(pcap_create); - EXPORT_FUN(pcap_set_snaplen); - EXPORT_FUN(pcap_set_promisc); - EXPORT_FUN(pcap_set_timeout); - EXPORT_FUN(pcap_activate); - EXPORT_FUN(pcap_setfilter); - EXPORT_FUN(pcap_setdirection); - EXPORT_FUN(pcap_datalink); - EXPORT_FUN(pcap_freecode); - EXPORT_FUN(pcap_compile); - EXPORT_FUN(pcap_geterr); - EXPORT_FUN(pcap_sendpacket); - EXPORT_FUN(pcap_lookupdev); - EXPORT_FUN(pcap_findalldevs); - /* - pcap_loop = (__typeof__(pcap_loop))GetProcAddress(wpcap, "pcap_loop"); - pcap_create = (__typeof__(pcap_create))GetProcAddress(wpcap, "pcap_create"); - pcap_set_snaplen = (__typeof__(pcap_set_snaplen))GetProcAddress(wpcap, "pcap_set_snaplen"); - pcap_set_promisc = (__typeof__(pcap_set_promisc))GetProcAddress(wpcap, "pcap_set_promisc"); - pcap_set_timeout = (__typeof__(pcap_set_timeout))GetProcAddress(wpcap, "pcap_set_timeout"); - pcap_activate = (__typeof__(pcap_activate))GetProcAddress(wpcap, "pcap_activate"); - pcap_setfilter = (__typeof__(pcap_setfilter))GetProcAddress(wpcap, "pcap_setfilter"); - pcap_setdirection = (__typeof__(pcap_setdirection))GetProcAddress(wpcap, "pcap_setdirection"); - pcap_datalink = (__typeof__(pcap_datalink))GetProcAddress(wpcap, "pcap_datalink"); - pcap_freecode = (__typeof__(pcap_freecode))GetProcAddress(wpcap, "pcap_freecode"); - pcap_compile = (__typeof__(pcap_compile))GetProcAddress(wpcap, "pcap_compile"); - pcap_geterr = (__typeof__(pcap_geterr))GetProcAddress(wpcap, "pcap_geterr"); - pcap_sendpacket = (__typeof__(pcap_sendpacket))GetProcAddress(wpcap, "pcap_sendpacket"); - pcap_lookupdev = (__typeof__(pcap_lookupdev))GetProcAddress(wpcap, "pcap_lookupdev"); - pcap_findalldevs = (__typeof__(pcap_findalldevs))GetProcAddress(wpcap, "pcap_findalldevs"); - //pcap_loop = (__typeof__(pcap_loop))GetProcAddress(wpcap, "pcap_loop"); - //pcap_loop = (__typeof__(pcap_loop))GetProcAddress(wpcap, "pcap_loop"); - //pcap_loop = (__typeof__(pcap_loop))GetProcAddress(wpcap, "pcap_loop"); - */ - return 0; +#define EXPORT_FUN(XXX) \ + do { \ + XXX = (__typeof__(XXX))GetProcAddress(wpcap, #XXX); \ + } while (0) +int init_pcap() { + HMODULE wpcap = LoadLibrary("wpcap.dll"); + if (wpcap != 0) { + printf("using system32/wpcap.dll\n"); + } else { + init_npcap_dll_path(); + // SetDllDirectory("C:\\Windows\\System32\\Npcap\\"); + wpcap = LoadLibrary("wpcap.dll"); + if (wpcap != 0) + printf("using system32/npcap/wpcap.dll\n"); + } + if (wpcap == 0) { + printf("cant not open wpcap.dll, make sure winpcap/npcap is installed\n"); + exit(-1); + } + assert(wpcap != 0); + EXPORT_FUN(pcap_loop); + EXPORT_FUN(pcap_breakloop); + EXPORT_FUN(pcap_create); + EXPORT_FUN(pcap_set_snaplen); + EXPORT_FUN(pcap_set_promisc); + EXPORT_FUN(pcap_set_timeout); + EXPORT_FUN(pcap_activate); + EXPORT_FUN(pcap_setfilter); + EXPORT_FUN(pcap_setdirection); + EXPORT_FUN(pcap_datalink); + EXPORT_FUN(pcap_freecode); + EXPORT_FUN(pcap_compile); + EXPORT_FUN(pcap_geterr); + EXPORT_FUN(pcap_sendpacket); + EXPORT_FUN(pcap_lookupdev); + EXPORT_FUN(pcap_findalldevs); + /* + pcap_loop = (__typeof__(pcap_loop))GetProcAddress(wpcap, "pcap_loop"); + pcap_create = (__typeof__(pcap_create))GetProcAddress(wpcap, "pcap_create"); + pcap_set_snaplen = (__typeof__(pcap_set_snaplen))GetProcAddress(wpcap, "pcap_set_snaplen"); + pcap_set_promisc = (__typeof__(pcap_set_promisc))GetProcAddress(wpcap, "pcap_set_promisc"); + pcap_set_timeout = (__typeof__(pcap_set_timeout))GetProcAddress(wpcap, "pcap_set_timeout"); + pcap_activate = (__typeof__(pcap_activate))GetProcAddress(wpcap, "pcap_activate"); + pcap_setfilter = (__typeof__(pcap_setfilter))GetProcAddress(wpcap, "pcap_setfilter"); + pcap_setdirection = (__typeof__(pcap_setdirection))GetProcAddress(wpcap, "pcap_setdirection"); + pcap_datalink = (__typeof__(pcap_datalink))GetProcAddress(wpcap, "pcap_datalink"); + pcap_freecode = (__typeof__(pcap_freecode))GetProcAddress(wpcap, "pcap_freecode"); + pcap_compile = (__typeof__(pcap_compile))GetProcAddress(wpcap, "pcap_compile"); + pcap_geterr = (__typeof__(pcap_geterr))GetProcAddress(wpcap, "pcap_geterr"); + pcap_sendpacket = (__typeof__(pcap_sendpacket))GetProcAddress(wpcap, "pcap_sendpacket"); + pcap_lookupdev = (__typeof__(pcap_lookupdev))GetProcAddress(wpcap, "pcap_lookupdev"); + pcap_findalldevs = (__typeof__(pcap_findalldevs))GetProcAddress(wpcap, "pcap_findalldevs"); + //pcap_loop = (__typeof__(pcap_loop))GetProcAddress(wpcap, "pcap_loop"); + //pcap_loop = (__typeof__(pcap_loop))GetProcAddress(wpcap, "pcap_loop"); + //pcap_loop = (__typeof__(pcap_loop))GetProcAddress(wpcap, "pcap_loop"); + */ + return 0; } diff --git a/pcap_wrapper.h b/pcap_wrapper.h index 3772d6b..ff0fd8d 100644 --- a/pcap_wrapper.h +++ b/pcap_wrapper.h @@ -1,127 +1,117 @@ #pragma once //#ifdef __cplusplus -//extern "C" { +// extern "C" { //#endif //#include //#include -struct bpf_program -{ - char a[4096]; +struct bpf_program { + char a[4096]; }; -struct pcap_t -{ - char a[4096]; +struct pcap_t { + char a[4096]; }; typedef unsigned int bpf_u_int32; typedef struct my_timeval { - int tv_sec; - int tv_usec; + int tv_sec; + int tv_usec; } my_timeval; struct pcap_pkthdr { - struct my_timeval ts; /* time stamp */ - bpf_u_int32 caplen; /* length of portion present */ - bpf_u_int32 len; /* length this packet (off wire) */ + struct my_timeval ts; /* time stamp */ + bpf_u_int32 caplen; /* length of portion present */ + bpf_u_int32 len; /* length this packet (off wire) */ }; typedef enum { - PCAP_D_INOUT = 0, - PCAP_D_IN, - PCAP_D_OUT + PCAP_D_INOUT = 0, + PCAP_D_IN, + PCAP_D_OUT } pcap_direction_t; - struct pcap_addr { - struct pcap_addr *next; - struct sockaddr *addr; /* address */ - struct sockaddr *netmask; /* netmask for that address */ - struct sockaddr *broadaddr; /* broadcast address for that address */ - struct sockaddr *dstaddr; /* P2P destination address for that address */ + struct pcap_addr *next; + struct sockaddr *addr; /* address */ + struct sockaddr *netmask; /* netmask for that address */ + struct sockaddr *broadaddr; /* broadcast address for that address */ + struct sockaddr *dstaddr; /* P2P destination address for that address */ }; struct pcap_if { - struct pcap_if *next; - char *name; /* name to hand to "pcap_open_live()" */ - char *description; /* textual description of interface, or NULL */ - struct pcap_addr *addresses; - bpf_u_int32 flags; /* PCAP_IF_ interface flags */ + struct pcap_if *next; + char *name; /* name to hand to "pcap_open_live()" */ + char *description; /* textual description of interface, or NULL */ + struct pcap_addr *addresses; + bpf_u_int32 flags; /* PCAP_IF_ interface flags */ }; typedef struct pcap_if pcap_if_t; typedef struct pcap_addr pcap_addr_t; - - typedef unsigned char u_char; - #define PCAP_ERRBUF_SIZE 256 -#define DLT_NULL 0 /* BSD loopback encapsulation */ -#define DLT_EN10MB 1 /* Ethernet (10Mb) */ -#define DLT_EN3MB 2 /* Experimental Ethernet (3Mb) */ -#define DLT_AX25 3 /* Amateur Radio AX.25 */ -#define DLT_PRONET 4 /* Proteon ProNET Token Ring */ -#define DLT_CHAOS 5 /* Chaos */ -#define DLT_IEEE802 6 /* 802.5 Token Ring */ -#define DLT_ARCNET 7 /* ARCNET, with BSD-style header */ -#define DLT_SLIP 8 /* Serial Line IP */ -#define DLT_PPP 9 /* Point-to-point Protocol */ -#define DLT_FDDI 10 /* FDDI */ -#define DLT_LINUX_SLL 113 +#define DLT_NULL 0 /* BSD loopback encapsulation */ +#define DLT_EN10MB 1 /* Ethernet (10Mb) */ +#define DLT_EN3MB 2 /* Experimental Ethernet (3Mb) */ +#define DLT_AX25 3 /* Amateur Radio AX.25 */ +#define DLT_PRONET 4 /* Proteon ProNET Token Ring */ +#define DLT_CHAOS 5 /* Chaos */ +#define DLT_IEEE802 6 /* 802.5 Token Ring */ +#define DLT_ARCNET 7 /* ARCNET, with BSD-style header */ +#define DLT_SLIP 8 /* Serial Line IP */ +#define DLT_PPP 9 /* Point-to-point Protocol */ +#define DLT_FDDI 10 /* FDDI */ +#define DLT_LINUX_SLL 113 -#define PCAP_NETMASK_UNKNOWN 0xffffffff +#define PCAP_NETMASK_UNKNOWN 0xffffffff typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *, - const u_char *); + const u_char *); -extern int (*pcap_loop )(pcap_t *, int, pcap_handler, u_char *); +extern int (*pcap_loop)(pcap_t *, int, pcap_handler, u_char *); -extern int (*pcap_breakloop )(pcap_t *); +extern int (*pcap_breakloop)(pcap_t *); -extern pcap_t* (*pcap_create)(const char *, char *); +extern pcap_t *(*pcap_create)(const char *, char *); -extern int (*pcap_set_snaplen) (pcap_t *, int); -extern int (*pcap_set_promisc) (pcap_t *, int); -extern int (*pcap_can_set_rfmon) (pcap_t *); -extern int (*pcap_set_rfmon )(pcap_t *, int); -extern int (*pcap_set_timeout)(pcap_t *, int); -extern int (*pcap_set_buffer_size)(pcap_t *, int); -extern int (*pcap_activate)(pcap_t *); +extern int (*pcap_set_snaplen)(pcap_t *, int); +extern int (*pcap_set_promisc)(pcap_t *, int); +extern int (*pcap_can_set_rfmon)(pcap_t *); +extern int (*pcap_set_rfmon)(pcap_t *, int); +extern int (*pcap_set_timeout)(pcap_t *, int); +extern int (*pcap_set_buffer_size)(pcap_t *, int); +extern int (*pcap_activate)(pcap_t *); -extern int (*pcap_setfilter)(pcap_t *, struct bpf_program *); -extern int (*pcap_setdirection)(pcap_t *, pcap_direction_t); +extern int (*pcap_setfilter)(pcap_t *, struct bpf_program *); +extern int (*pcap_setdirection)(pcap_t *, pcap_direction_t); -extern int (*pcap_datalink)(pcap_t *); +extern int (*pcap_datalink)(pcap_t *); -extern void (*pcap_freecode)(struct bpf_program *); +extern void (*pcap_freecode)(struct bpf_program *); -extern int (*pcap_compile)(pcap_t *, struct bpf_program *, const char *, int, - bpf_u_int32); +extern int (*pcap_compile)(pcap_t *, struct bpf_program *, const char *, int, + bpf_u_int32); -extern char* (*pcap_geterr)(pcap_t *); -extern int (*pcap_sendpacket)(pcap_t *, const u_char *, int); +extern char *(*pcap_geterr)(pcap_t *); +extern int (*pcap_sendpacket)(pcap_t *, const u_char *, int); -extern char* (*pcap_lookupdev)(char *); +extern char *(*pcap_lookupdev)(char *); -extern int (*pcap_findalldevs)(pcap_if_t **, char *); +extern int (*pcap_findalldevs)(pcap_if_t **, char *); -inline int pcap_set_immediate_mode(pcap_t *,int) -{ - return 0; +inline int pcap_set_immediate_mode(pcap_t *, int) { + return 0; } - - //#ifdef __cplusplus //} //#endif int init_pcap(); - diff --git a/server.cpp b/server.cpp index 9ac0728..a117a48 100644 --- a/server.cpp +++ b/server.cpp @@ -16,906 +16,785 @@ #include "encrypt.h" #include "fd_manager.h" -int server_on_timer_multi(conn_info_t &conn_info) //for server. called when a timer is ready in epoll.for server,there will be one timer for every connection +int server_on_timer_multi(conn_info_t &conn_info) // for server. called when a timer is ready in epoll.for server,there will be one timer for every connection // there is also a global timer for server,but its not handled here { - char ip_port[max_addr_len]; - //u32_t ip=conn_info.raw_info.send_info.dst_ip; - //u32_t port=conn_info.raw_info.send_info.dst_port; - - address_t tmp_addr; - tmp_addr.from_ip_port_new(raw_ip_version,&conn_info.raw_info.send_info.new_dst_ip,conn_info.raw_info.send_info.dst_port); - //sprintf(ip_port,"%s:%d",my_ntoa(ip),port); - tmp_addr.to_str(ip_port); - - //keep_iptables_rule(); - mylog(log_trace,"server timer!\n"); - raw_info_t &raw_info=conn_info.raw_info; - - assert(conn_info.state.server_current_state==server_ready); - - - if(conn_info.state.server_current_state==server_ready) - { - conn_info.blob->conv_manager.s.clear_inactive(ip_port); - /* - if( get_current_time()-conn_info.last_hb_recv_time>heartbeat_timeout ) - { - mylog(log_trace,"%lld %lld\n",get_current_time(),conn_info.last_state_time); - conn_info.server_current_state=server_nothing; - - //conn_manager.current_ready_ip=0; - //conn_manager.current_ready_port=0; - - mylog(log_info,"changed state to server_nothing\n"); - return 0; - }*/ //dont need to do this at server,conn_manger will clear expired connections - - if(get_current_time()-conn_info.last_hb_sent_time\n",conn_info.my_id,conn_info.oppsite_id); - } - else - { - mylog(log_fatal,"this shouldnt happen!\n"); - myexit(-1); - } - return 0; - -} -int server_on_raw_recv_ready(conn_info_t &conn_info,char * ip_port,char type,char *data,int data_len) //called while the state for a connection is server_ready -//receives data and heart beat by recv_safer. -{ - - raw_info_t &raw_info = conn_info.raw_info; - packet_info_t &send_info = conn_info.raw_info.send_info; - packet_info_t &recv_info = conn_info.raw_info.recv_info; - //char ip_port[40]; - - //sprintf(ip_port,"%s:%d",my_ntoa(recv_info.src_ip),recv_info.src_port); - - -/* - 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; - }*/ - - if (type == 'h' && data_len >= 0) { - //u32_t tmp = ntohl(*((u32_t *) &data[sizeof(u32_t)])); - mylog(log_debug,"[%s][hb]received hb \n",ip_port); - conn_info.last_hb_recv_time = get_current_time(); - return 0; - } else if (type== 'd' && data_len >=int( sizeof(u32_t) )) - { - - //u32_t tmp_conv_id = ntohl(*((u32_t *) &data[0])); - my_id_t tmp_conv_id; - memcpy(&tmp_conv_id,&data[0],sizeof(tmp_conv_id)); - tmp_conv_id=ntohl(tmp_conv_id); - - - if(hb_mode==0) - conn_info.last_hb_recv_time = get_current_time(); - - mylog(log_trace, "conv:%u\n", tmp_conv_id); - if (!conn_info.blob->conv_manager.s.is_conv_used(tmp_conv_id)) { - if (conn_info.blob->conv_manager.s.get_size() >= max_conv_num) { - mylog(log_warn, - "[%s]ignored new conv %x connect bc max_conv_num exceed\n",ip_port, - tmp_conv_id); - return 0; - } - - /* - 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_udp_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - - - if (new_udp_fd < 0) { - mylog(log_warn, "[%s]create udp_fd error\n",ip_port); - return -1; - } - setnonblocking(new_udp_fd); - set_buf_size(new_udp_fd,socket_buf_size); - - mylog(log_debug, "[%s]created new udp_fd %d\n",ip_port, 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; - }*/ - - int new_udp_fd=remote_addr.new_connected_udp_fd(); - if (new_udp_fd < 0) { - mylog(log_warn, "[%s]new_connected_udp_fd() failed\n",ip_port); - return -1; - } - - struct epoll_event ev; - - fd64_t new_udp_fd64 = fd_manager.create(new_udp_fd); - fd_manager.get_info(new_udp_fd64).p_conn_info=&conn_info; - - mylog(log_trace, "[%s]u64: %lld\n",ip_port, new_udp_fd64); - ev.events = EPOLLIN; - - ev.data.u64 = new_udp_fd64; - - int ret = epoll_ctl(epollfd, EPOLL_CTL_ADD, new_udp_fd, &ev); - - if (ret != 0) { - mylog(log_warn, "[%s]add udp_fd error\n",ip_port); - close(new_udp_fd); - return -1; - } - - conn_info.blob->conv_manager.s.insert_conv(tmp_conv_id, new_udp_fd64); - - - - //assert(conn_manager.udp_fd_mp.find(new_udp_fd)==conn_manager.udp_fd_mp.end()); - - //conn_manager.udp_fd_mp[new_udp_fd] = &conn_info; - - //pack_u64(conn_info.raw_info.recv_info.src_ip,conn_info.raw_info.recv_info.src_port); - - mylog(log_info, "[%s]new conv conv_id=%x, assigned fd=%d\n",ip_port, - tmp_conv_id, new_udp_fd); - - - - } - - fd64_t fd64 = conn_info.blob->conv_manager.s.find_data_by_conv(tmp_conv_id); - - conn_info.blob->conv_manager.s.update_active_time(tmp_conv_id); - - int fd = fd_manager.to_fd(fd64); - - mylog(log_trace, "[%s]received a data from fake tcp,len:%d\n",ip_port, data_len); - int ret = send(fd, data + sizeof(u32_t), - data_len - ( sizeof(u32_t)), 0); - - mylog(log_trace, "[%s]%d byte sent ,fd :%d\n ",ip_port, ret, fd); - if (ret < 0) { - mylog(log_warn, "send returned %d\n", ret); - //perror("what happened????"); - } - return 0; - } - return 0; -} - -int server_on_raw_recv_pre_ready(conn_info_t &conn_info,char * ip_port,u32_t tmp_oppsite_const_id)// do prepare work before state change to server ready for a specifc connection -//connection recovery is also handle here -{ - //u32_t ip;uint16_t port; - //ip=conn_info.raw_info.recv_info.src_ip; - //port=conn_info.raw_info.recv_info.src_port; - //char ip_port[40]; - //sprintf(ip_port,"%s:%d",my_ntoa(ip),port); - - mylog(log_info,"[%s]received handshake oppsite_id:%x my_id:%x\n",ip_port,conn_info.oppsite_id,conn_info.my_id); - - mylog(log_info,"[%s]oppsite const_id:%x \n",ip_port,tmp_oppsite_const_id); - if(conn_manager.const_id_mp.find(tmp_oppsite_const_id)==conn_manager.const_id_mp.end()) - { - //conn_manager.const_id_mp= - - if(conn_manager.ready_num>=max_ready_conn_num) - { - mylog(log_info,"[%s]max_ready_conn_num,cant turn to ready\n",ip_port); - conn_info.state.server_current_state =server_idle; - return 0; - } - - conn_info.prepare(); - conn_info.state.server_current_state = server_ready; - conn_info.oppsite_const_id=tmp_oppsite_const_id; - conn_manager.ready_num++; - conn_manager.const_id_mp[tmp_oppsite_const_id]=&conn_info; - - - //conn_info.last_state_time=get_current_time(); //dont change this!!!!!!!!!!!!!!!!!!!!!!!!! - - //conn_manager.current_ready_ip=ip; - //conn_manager.current_ready_port=port; - - //my_id=conn_info.my_id; - //oppsite_id=conn_info.oppsite_id; - conn_info.last_hb_recv_time = get_current_time(); - - conn_info.last_hb_sent_time = conn_info.last_hb_recv_time;//=get_current_time() - - if(hb_mode==0) - send_safer(conn_info,'h',hb_buf,0);/////////////send - else - send_safer(conn_info,'h',hb_buf,hb_len); - - mylog(log_info, "[%s]changed state to server_ready\n",ip_port); - conn_info.blob->anti_replay.re_init(); - - //g_conn_info=conn_info; - int new_timer_fd; - set_timer_server(epollfd, new_timer_fd,conn_info.timer_fd64); - - fd_manager.get_info(conn_info.timer_fd64).p_conn_info=&conn_info; - //assert(conn_manager.timer_fd_mp.find(new_timer_fd)==conn_manager.timer_fd_mp.end()); - //conn_manager.timer_fd_mp[new_timer_fd] = &conn_info;//pack_u64(ip,port); - - - //timer_fd_mp[new_timer_fd] - /* - if(oppsite_const_id!=0&&tmp_oppsite_const_id!=oppsite_const_id) //TODO MOVE TO READY - { - mylog(log_info,"cleared all conv bc of const id doesnt match\n"); - conv_manager.clear(); - }*/ - //oppsite_const_id=tmp_oppsite_const_id; - } - else - { - - conn_info_t &ori_conn_info=*conn_manager.const_id_mp[tmp_oppsite_const_id]; - - if(ori_conn_info.state.server_current_state==server_ready) - { - if(conn_info.last_state_timeanti_replay.re_init(); - if(hb_mode==0) - send_safer(ori_conn_info,'h',hb_buf,0);/////////////send - else - send_safer(ori_conn_info,'h',hb_buf,hb_len); - - ori_conn_info.last_hb_recv_time=get_current_time(); - - - - conn_info.state.server_current_state=server_idle; - conn_info.oppsite_const_id=0; - - } - else - { - mylog(log_fatal,"[%s]this should never happen\n",ip_port); - myexit(-1); - } - return 0; - } - return 0; -} -int server_on_raw_recv_handshake1(conn_info_t &conn_info,char * ip_port,char * data, int data_len)//called when server received a handshake1 packet from client -{ - 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; - - //u32_t ip=conn_info.raw_info.recv_info.src_ip; - //uint16_t port=conn_info.raw_info.recv_info.src_port; - - //char ip_port[40]; - //sprintf(ip_port,"%s:%d",my_ntoa(ip),port); - - if(data_lenconv_manager.s.clear_inactive(ip_port); + /* + if( get_current_time()-conn_info.last_hb_recv_time>heartbeat_timeout ) + { + mylog(log_trace,"%lld %lld\n",get_current_time(),conn_info.last_state_time); + conn_info.server_current_state=server_nothing; + + //conn_manager.current_ready_ip=0; + //conn_manager.current_ready_port=0; + + mylog(log_info,"changed state to server_nothing\n"); + return 0; + }*/ + // dont need to do this at server,conn_manger will clear expired connections + + if (get_current_time() - conn_info.last_hb_sent_time < heartbeat_interval) { + return 0; + } + + 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(); + + mylog(log_debug, "heart beat sent<%x,%x>\n", conn_info.my_id, conn_info.oppsite_id); + } else { + mylog(log_fatal, "this shouldnt happen!\n"); + myexit(-1); + } return 0; } -int server_on_raw_recv_multi() //called when server received an raw packet +int server_on_raw_recv_ready(conn_info_t &conn_info, char *ip_port, char type, char *data, int data_len) // called while the state for a connection is server_ready +// receives data and heart beat by recv_safer. { - char dummy_buf[buf_len]; - raw_info_t peek_raw_info; - peek_raw_info.peek=1; - packet_info_t &peek_info=peek_raw_info.recv_info; - mylog(log_trace,"got a packet\n"); - if(pre_recv_raw_packet()<0) return -1; - if(peek_raw(peek_raw_info)<0) - { - discard_raw_packet(); - //recv(raw_recv_fd, 0,0, 0 );// - //struct sockaddr saddr; - //socklen_t saddr_size=sizeof(saddr); - ///recvfrom(raw_recv_fd, 0,0, 0 ,&saddr , &saddr_size);// - mylog(log_trace,"peek_raw failed\n"); - return -1; - }else - { - mylog(log_trace,"peek_raw success\n"); - } - //u32_t ip=peek_info.src_ip;uint16_t port=peek_info.src_port; + raw_info_t &raw_info = conn_info.raw_info; + packet_info_t &send_info = conn_info.raw_info.send_info; + packet_info_t &recv_info = conn_info.raw_info.recv_info; + // char ip_port[40]; + // sprintf(ip_port,"%s:%d",my_ntoa(recv_info.src_ip),recv_info.src_port); - int data_len; char *data; + /* + 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; + }*/ - address_t addr; - addr.from_ip_port_new(raw_ip_version,&peek_info.new_src_ip,peek_info.src_port); + if (type == 'h' && data_len >= 0) { + // u32_t tmp = ntohl(*((u32_t *) &data[sizeof(u32_t)])); + mylog(log_debug, "[%s][hb]received hb \n", ip_port); + conn_info.last_hb_recv_time = get_current_time(); + return 0; + } else if (type == 'd' && data_len >= int(sizeof(u32_t))) { + // u32_t tmp_conv_id = ntohl(*((u32_t *) &data[0])); + my_id_t tmp_conv_id; + memcpy(&tmp_conv_id, &data[0], sizeof(tmp_conv_id)); + tmp_conv_id = ntohl(tmp_conv_id); - char ip_port[max_addr_len]; - addr.to_str(ip_port); - //sprintf(ip_port,"%s:%d",my_ntoa(ip),port); - mylog(log_trace,"[%s]peek_raw\n",ip_port); + if (hb_mode == 0) + conn_info.last_hb_recv_time = get_current_time(); - if(raw_mode==mode_faketcp&&peek_info.syn==1) - { - if(!conn_manager.exist(addr)||conn_manager.find_insert(addr).state.server_current_state!=server_ready) - {//reply any syn ,before state become ready + mylog(log_trace, "conv:%u\n", tmp_conv_id); + if (!conn_info.blob->conv_manager.s.is_conv_used(tmp_conv_id)) { + if (conn_info.blob->conv_manager.s.get_size() >= max_conv_num) { + mylog(log_warn, + "[%s]ignored new conv %x connect bc max_conv_num exceed\n", ip_port, + tmp_conv_id); + return 0; + } - raw_info_t tmp_raw_info; - if(recv_raw0(tmp_raw_info,data,data_len)<0) - { - return 0; - } - if(data_len>=max_data_len+1) - { - mylog(log_debug,"data_len=%d >= max_data_len+1,ignored",data_len); - return -1; - } - if(use_tcp_dummy_socket!=0) - return 0; - raw_info_t &raw_info=tmp_raw_info; - packet_info_t &send_info=raw_info.send_info; - packet_info_t &recv_info=raw_info.recv_info; + /* + struct sockaddr_in remote_addr_in={0}; - send_info.new_src_ip=recv_info.new_dst_ip; - send_info.src_port=recv_info.dst_port; - - send_info.dst_port = recv_info.src_port; - send_info.new_dst_ip = recv_info.new_src_ip; - - if(lower_level) - { - handle_lower_level(raw_info); - } - - if(data_len==0&&raw_info.recv_info.syn==1&&raw_info.recv_info.ack==0) - { - send_info.ack_seq = recv_info.seq + 1; - - send_info.psh = 0; - send_info.syn = 1; - send_info.ack = 1; - send_info.ts_ack=recv_info.ts; - - mylog(log_info,"[%s]received syn,sent syn ack back\n",ip_port); - send_raw0(raw_info, 0, 0); - return 0; - } - } - else - { - discard_raw_packet(); - //recv(raw_recv_fd, 0,0,0); - } - return 0; - } - if(!conn_manager.exist(addr)) - { - if(conn_manager.mp.size()>=max_handshake_conn_num) - { - mylog(log_info,"[%s]reached max_handshake_conn_num,ignored new handshake\n",ip_port); - discard_raw_packet(); - //recv(raw_recv_fd, 0,0, 0 );// - return 0; - } - - raw_info_t tmp_raw_info; - - - if(raw_mode==mode_icmp) - { - tmp_raw_info.send_info.dst_port=tmp_raw_info.send_info.src_port=addr.get_port(); - } - if(recv_bare(tmp_raw_info,data,data_len)<0) - { - return 0; - } - if(data_len type_vec; - vector data_vec; - recv_safer_multi(conn_info,type_vec,data_vec); - if(data_vec.empty()) - { - mylog(log_debug,"recv_safer failed!\n"); + int ret = epoll_ctl(epollfd, EPOLL_CTL_ADD, new_udp_fd, &ev); + + if (ret != 0) { + mylog(log_warn, "[%s]add udp_fd error\n", ip_port); + close(new_udp_fd); + return -1; + } + + conn_info.blob->conv_manager.s.insert_conv(tmp_conv_id, new_udp_fd64); + + // assert(conn_manager.udp_fd_mp.find(new_udp_fd)==conn_manager.udp_fd_mp.end()); + + // conn_manager.udp_fd_mp[new_udp_fd] = &conn_info; + + // pack_u64(conn_info.raw_info.recv_info.src_ip,conn_info.raw_info.recv_info.src_port); + + mylog(log_info, "[%s]new conv conv_id=%x, assigned fd=%d\n", ip_port, + tmp_conv_id, new_udp_fd); + } + + fd64_t fd64 = conn_info.blob->conv_manager.s.find_data_by_conv(tmp_conv_id); + + conn_info.blob->conv_manager.s.update_active_time(tmp_conv_id); + + int fd = fd_manager.to_fd(fd64); + + mylog(log_trace, "[%s]received a data from fake tcp,len:%d\n", ip_port, data_len); + int ret = send(fd, data + sizeof(u32_t), + data_len - (sizeof(u32_t)), 0); + + mylog(log_trace, "[%s]%d byte sent ,fd :%d\n ", ip_port, ret, fd); + if (ret < 0) { + mylog(log_warn, "send returned %d\n", ret); + // perror("what happened????"); + } + return 0; + } + return 0; +} + +int server_on_raw_recv_pre_ready(conn_info_t &conn_info, char *ip_port, u32_t tmp_oppsite_const_id) // do prepare work before state change to server ready for a specifc connection +// connection recovery is also handle here +{ + // u32_t ip;uint16_t port; + // ip=conn_info.raw_info.recv_info.src_ip; + // port=conn_info.raw_info.recv_info.src_port; + // char ip_port[40]; + // sprintf(ip_port,"%s:%d",my_ntoa(ip),port); + + mylog(log_info, "[%s]received handshake oppsite_id:%x my_id:%x\n", ip_port, conn_info.oppsite_id, conn_info.my_id); + + mylog(log_info, "[%s]oppsite const_id:%x \n", ip_port, tmp_oppsite_const_id); + if (conn_manager.const_id_mp.find(tmp_oppsite_const_id) == conn_manager.const_id_mp.end()) { + // conn_manager.const_id_mp= + + if (conn_manager.ready_num >= max_ready_conn_num) { + mylog(log_info, "[%s]max_ready_conn_num,cant turn to ready\n", ip_port); + conn_info.state.server_current_state = server_idle; + return 0; + } + + conn_info.prepare(); + conn_info.state.server_current_state = server_ready; + conn_info.oppsite_const_id = tmp_oppsite_const_id; + conn_manager.ready_num++; + conn_manager.const_id_mp[tmp_oppsite_const_id] = &conn_info; + + // conn_info.last_state_time=get_current_time(); //dont change this!!!!!!!!!!!!!!!!!!!!!!!!! + + // conn_manager.current_ready_ip=ip; + // conn_manager.current_ready_port=port; + + // my_id=conn_info.my_id; + // oppsite_id=conn_info.oppsite_id; + conn_info.last_hb_recv_time = get_current_time(); + + conn_info.last_hb_sent_time = conn_info.last_hb_recv_time; //=get_current_time() + + if (hb_mode == 0) + send_safer(conn_info, 'h', hb_buf, 0); /////////////send + else + send_safer(conn_info, 'h', hb_buf, hb_len); + + mylog(log_info, "[%s]changed state to server_ready\n", ip_port); + conn_info.blob->anti_replay.re_init(); + + // g_conn_info=conn_info; + int new_timer_fd; + set_timer_server(epollfd, new_timer_fd, conn_info.timer_fd64); + + fd_manager.get_info(conn_info.timer_fd64).p_conn_info = &conn_info; + // assert(conn_manager.timer_fd_mp.find(new_timer_fd)==conn_manager.timer_fd_mp.end()); + // conn_manager.timer_fd_mp[new_timer_fd] = &conn_info;//pack_u64(ip,port); + + // timer_fd_mp[new_timer_fd] + /* + if(oppsite_const_id!=0&&tmp_oppsite_const_id!=oppsite_const_id) //TODO MOVE TO READY + { + mylog(log_info,"cleared all conv bc of const id doesnt match\n"); + conv_manager.clear(); + }*/ + // oppsite_const_id=tmp_oppsite_const_id; + } else { + conn_info_t &ori_conn_info = *conn_manager.const_id_mp[tmp_oppsite_const_id]; + + if (ori_conn_info.state.server_current_state == server_ready) { + if (conn_info.last_state_time < ori_conn_info.last_state_time) { + mylog(log_info, "[%s]conn_info.last_state_timeanti_replay.re_init(); + if (hb_mode == 0) + send_safer(ori_conn_info, 'h', hb_buf, 0); /////////////send + else + send_safer(ori_conn_info, 'h', hb_buf, hb_len); + + ori_conn_info.last_hb_recv_time = get_current_time(); + + conn_info.state.server_current_state = server_idle; + conn_info.oppsite_const_id = 0; + + } else { + mylog(log_fatal, "[%s]this should never happen\n", ip_port); + myexit(-1); + } + return 0; + } + return 0; +} +int server_on_raw_recv_handshake1(conn_info_t &conn_info, char *ip_port, char *data, int data_len) // called when server received a handshake1 packet from client +{ + 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; + + // u32_t ip=conn_info.raw_info.recv_info.src_ip; + // uint16_t port=conn_info.raw_info.recv_info.src_port; + + // char ip_port[40]; + // sprintf(ip_port,"%s:%d",my_ntoa(ip),port); + + if (data_len < int(3 * sizeof(my_id_t))) { + mylog(log_debug, "[%s] data_len=%d too short to be a handshake\n", ip_port, data_len); + return -1; + } + // id_t tmp_oppsite_id= ntohl(* ((u32_t *)&data[0])); + my_id_t tmp_oppsite_id; + memcpy(&tmp_oppsite_id, (u32_t *)&data[0], sizeof(tmp_oppsite_id)); + tmp_oppsite_id = ntohl(tmp_oppsite_id); + + // id_t tmp_my_id=ntohl(* ((u32_t *)&data[sizeof(id_t)])); + my_id_t tmp_my_id; + memcpy(&tmp_my_id, &data[sizeof(my_id_t)], sizeof(tmp_my_id)); + tmp_my_id = ntohl(tmp_my_id); + + if (tmp_my_id == 0) // received init handshake again + { + if (raw_mode == mode_faketcp) { + send_info.seq = recv_info.ack_seq; + send_info.ack_seq = recv_info.seq + raw_info.recv_info.data_len; + send_info.ts_ack = recv_info.ts; + } + if (raw_mode == mode_icmp) { + send_info.my_icmp_seq = recv_info.my_icmp_seq; + } + send_handshake(raw_info, conn_info.my_id, tmp_oppsite_id, const_id); //////////////send + + mylog(log_info, "[%s]changed state to server_handshake1,my_id is %x\n", ip_port, conn_info.my_id); + } else if (tmp_my_id == conn_info.my_id) { + conn_info.oppsite_id = tmp_oppsite_id; + // id_t tmp_oppsite_const_id=ntohl(* ((u32_t *)&data[sizeof(id_t)*2])); + + my_id_t tmp_oppsite_const_id; + memcpy(&tmp_oppsite_const_id, &data[sizeof(my_id_t) * 2], sizeof(tmp_oppsite_const_id)); + tmp_oppsite_const_id = ntohl(tmp_oppsite_const_id); + + if (raw_mode == mode_faketcp) { + send_info.seq = recv_info.ack_seq; + send_info.ack_seq = recv_info.seq + raw_info.recv_info.data_len; + send_info.ts_ack = recv_info.ts; + } + + if (raw_mode == mode_icmp) { + send_info.my_icmp_seq = recv_info.my_icmp_seq; + } + + server_on_raw_recv_pre_ready(conn_info, ip_port, tmp_oppsite_const_id); + + } else { + mylog(log_debug, "[%s]invalid my_id %x,my_id is %x\n", ip_port, tmp_my_id, conn_info.my_id); + } + return 0; +} +int server_on_recv_safer_multi(conn_info_t &conn_info, char type, char *data, int data_len) { + return 0; +} +int server_on_raw_recv_multi() // called when server received an raw packet +{ + char dummy_buf[buf_len]; + raw_info_t peek_raw_info; + peek_raw_info.peek = 1; + packet_info_t &peek_info = peek_raw_info.recv_info; + mylog(log_trace, "got a packet\n"); + if (pre_recv_raw_packet() < 0) return -1; + if (peek_raw(peek_raw_info) < 0) { + discard_raw_packet(); + // recv(raw_recv_fd, 0,0, 0 );// + // struct sockaddr saddr; + // socklen_t saddr_size=sizeof(saddr); + /// recvfrom(raw_recv_fd, 0,0, 0 ,&saddr , &saddr_size);// + mylog(log_trace, "peek_raw failed\n"); + return -1; + } else { + mylog(log_trace, "peek_raw success\n"); + } + // u32_t ip=peek_info.src_ip;uint16_t port=peek_info.src_port; + + int data_len; + char *data; + + address_t addr; + addr.from_ip_port_new(raw_ip_version, &peek_info.new_src_ip, peek_info.src_port); + + char ip_port[max_addr_len]; + addr.to_str(ip_port); + // sprintf(ip_port,"%s:%d",my_ntoa(ip),port); + mylog(log_trace, "[%s]peek_raw\n", ip_port); + + if (raw_mode == mode_faketcp && peek_info.syn == 1) { + if (!conn_manager.exist(addr) || conn_manager.find_insert(addr).state.server_current_state != server_ready) { // reply any syn ,before state become ready + + raw_info_t tmp_raw_info; + if (recv_raw0(tmp_raw_info, data, data_len) < 0) { + return 0; + } + if (data_len >= max_data_len + 1) { + mylog(log_debug, "data_len=%d >= max_data_len+1,ignored", data_len); + return -1; + } + if (use_tcp_dummy_socket != 0) + return 0; + raw_info_t &raw_info = tmp_raw_info; + packet_info_t &send_info = raw_info.send_info; + packet_info_t &recv_info = raw_info.recv_info; + + send_info.new_src_ip = recv_info.new_dst_ip; + send_info.src_port = recv_info.dst_port; + + send_info.dst_port = recv_info.src_port; + send_info.new_dst_ip = recv_info.new_src_ip; + + if (lower_level) { + handle_lower_level(raw_info); + } + + if (data_len == 0 && raw_info.recv_info.syn == 1 && raw_info.recv_info.ack == 0) { + send_info.ack_seq = recv_info.seq + 1; + + send_info.psh = 0; + send_info.syn = 1; + send_info.ack = 1; + send_info.ts_ack = recv_info.ts; + + mylog(log_info, "[%s]received syn,sent syn ack back\n", ip_port); + send_raw0(raw_info, 0, 0); + return 0; + } + } else { + discard_raw_packet(); + // recv(raw_recv_fd, 0,0,0); + } + return 0; + } + if (!conn_manager.exist(addr)) { + if (conn_manager.mp.size() >= max_handshake_conn_num) { + mylog(log_info, "[%s]reached max_handshake_conn_num,ignored new handshake\n", ip_port); + discard_raw_packet(); + // recv(raw_recv_fd, 0,0, 0 );// + return 0; + } + + raw_info_t tmp_raw_info; + + if (raw_mode == mode_icmp) { + tmp_raw_info.send_info.dst_port = tmp_raw_info.send_info.src_port = addr.get_port(); + } + if (recv_bare(tmp_raw_info, data, data_len) < 0) { + return 0; + } + if (data_len < int(3 * sizeof(my_id_t))) { + mylog(log_debug, "[%s]too short to be a handshake\n", ip_port); return -1; } - for(int i=0;i<(int)type_vec.size();i++) - { - char type=type_vec[i]; - char *data=(char *)data_vec[i].c_str(); //be careful, do not append data to it - int data_len=data_vec[i].length(); - server_on_raw_recv_ready(conn_info,ip_port,type,data,data_len); + // id_t zero=ntohl(* ((u32_t *)&data[sizeof(id_t)])); + my_id_t zero; + memcpy(&zero, &data[sizeof(my_id_t)], sizeof(zero)); + zero = ntohl(zero); + + if (zero != 0) { + mylog(log_debug, "[%s]not a invalid initial handshake\n", ip_port); + return -1; + } + + mylog(log_info, "[%s]got packet from a new ip\n", ip_port); + + conn_info_t &conn_info = conn_manager.find_insert(addr); + conn_info.raw_info = tmp_raw_info; + raw_info_t &raw_info = conn_info.raw_info; + + packet_info_t &send_info = conn_info.raw_info.send_info; + packet_info_t &recv_info = conn_info.raw_info.recv_info; + + // conn_info.ip_port.ip=ip; + // conn_info.ip_port.port=port; + + send_info.new_src_ip = recv_info.new_dst_ip; + send_info.src_port = recv_info.dst_port; + + send_info.dst_port = recv_info.src_port; + send_info.new_dst_ip = recv_info.new_src_ip; + + if (lower_level) { + handle_lower_level(raw_info); + } + + // id_t tmp_oppsite_id= ntohl(* ((u32_t *)&data[0])); + // mylog(log_info,"[%s]handshake1 received %x\n",ip_port,tmp_oppsite_id); + + conn_info.my_id = get_true_random_number_nz(); + + mylog(log_info, "[%s]created new conn,state: server_handshake1,my_id is %x\n", ip_port, conn_info.my_id); + + conn_info.state.server_current_state = server_handshake1; + conn_info.last_state_time = get_current_time(); + + server_on_raw_recv_handshake1(conn_info, ip_port, data, data_len); + return 0; + } + + conn_info_t &conn_info = conn_manager.find_insert(addr); // insert if not exist + 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; + + if (conn_info.state.server_current_state == server_handshake1) { + if (recv_bare(raw_info, data, data_len) != 0) { + return -1; + } + return server_on_raw_recv_handshake1(conn_info, ip_port, data, data_len); + } + if (conn_info.state.server_current_state == server_ready) { + vector type_vec; + vector data_vec; + recv_safer_multi(conn_info, type_vec, data_vec); + if (data_vec.empty()) { + mylog(log_debug, "recv_safer failed!\n"); + return -1; + } + + for (int i = 0; i < (int)type_vec.size(); i++) { + char type = type_vec[i]; + char *data = (char *)data_vec[i].c_str(); // be careful, do not append data to it + int data_len = data_vec[i].length(); + server_on_raw_recv_ready(conn_info, ip_port, type, data, data_len); } return 0; + } - } - - if(conn_info.state.server_current_state==server_idle) - { - discard_raw_packet(); - //recv(raw_recv_fd, 0,0, 0 );// - return 0; - } - mylog(log_fatal,"we should never run to here\n"); - myexit(-1); - return -1; + if (conn_info.state.server_current_state == server_idle) { + discard_raw_packet(); + // recv(raw_recv_fd, 0,0, 0 );// + return 0; + } + mylog(log_fatal, "we should never run to here\n"); + myexit(-1); + return -1; } -int server_on_udp_recv(conn_info_t &conn_info,fd64_t fd64) -{ - char buf[buf_len]; +int server_on_udp_recv(conn_info_t &conn_info, fd64_t fd64) { + char buf[buf_len]; - if(conn_info.state.server_current_state!=server_ready)//TODO remove this for peformance - { - mylog(log_fatal,"p_conn_info->state.server_current_state!=server_ready!!!this shouldnt happen\n"); - myexit(-1); - } + if (conn_info.state.server_current_state != server_ready) // TODO remove this for peformance + { + mylog(log_fatal, "p_conn_info->state.server_current_state!=server_ready!!!this shouldnt happen\n"); + myexit(-1); + } - //conn_info_t &conn_info=*p_conn_info; + // conn_info_t &conn_info=*p_conn_info; - assert(conn_info.blob->conv_manager.s.is_data_used(fd64)); + assert(conn_info.blob->conv_manager.s.is_data_used(fd64)); - u32_t conv_id=conn_info.blob->conv_manager.s.find_conv_by_data(fd64); + u32_t conv_id = conn_info.blob->conv_manager.s.find_conv_by_data(fd64); - int fd=fd_manager.to_fd(fd64); + int fd = fd_manager.to_fd(fd64); - int recv_len=recv(fd,buf,max_data_len+1,0); + int recv_len = recv(fd, buf, max_data_len + 1, 0); - mylog(log_trace,"received a packet from udp_fd,len:%d\n",recv_len); + mylog(log_trace, "received a packet from udp_fd,len:%d\n", recv_len); - if(recv_len==max_data_len+1) - { - mylog(log_warn,"huge packet, data_len > %d,dropped\n",max_data_len); - return -1; - } + if (recv_len == max_data_len + 1) { + mylog(log_warn, "huge packet, data_len > %d,dropped\n", max_data_len); + return -1; + } - if(recv_len<0) - { - mylog(log_debug,"udp fd,recv_len<0 continue,%s\n",strerror(errno)); - return -1; - } + if (recv_len < 0) { + mylog(log_debug, "udp fd,recv_len<0 continue,%s\n", strerror(errno)); + return -1; + } - 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); - } + 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); + } - //conn_info.conv_manager->update_active_time(conv_id); server dosnt update from upd side,only update from raw side. (client updates at both side) + // conn_info.conv_manager->update_active_time(conv_id); server dosnt update from upd side,only update from raw side. (client updates at both side) - if(conn_info.state.server_current_state==server_ready) - { - send_data_safer(conn_info,buf,recv_len,conv_id); - //send_data(g_packet_info_send,buf,recv_len,my_id,oppsite_id,conv_id); - mylog(log_trace,"send_data_safer ,sent !!\n"); - } + if (conn_info.state.server_current_state == server_ready) { + send_data_safer(conn_info, buf, recv_len, conv_id); + // send_data(g_packet_info_send,buf,recv_len,my_id,oppsite_id,conv_id); + mylog(log_trace, "send_data_safer ,sent !!\n"); + } - - return 0; + return 0; } +int server_event_loop() { + char buf[buf_len]; -int server_event_loop() -{ - char buf[buf_len]; + int i, j, k; + int ret; - int i, j, k;int ret; + if (raw_ip_version == AF_INET) { + if (local_addr.inner.ipv4.sin_addr.s_addr != 0) { + bind_addr_used = 1; + bind_addr.v4 = local_addr.inner.ipv4.sin_addr.s_addr; + } + } else { + assert(raw_ip_version == AF_INET6); + char zero_arr[16] = {0}; + if (memcmp(&local_addr.inner.ipv6.sin6_addr, zero_arr, 16) != 0) { + bind_addr_used = 1; + bind_addr.v6 = local_addr.inner.ipv6.sin6_addr; + } + } + // bind_address_uint32=local_ip_uint32;//only server has bind adress,client sets it to zero - if(raw_ip_version==AF_INET) - { - if(local_addr.inner.ipv4.sin_addr.s_addr!=0) - { - bind_addr_used=1; - bind_addr.v4=local_addr.inner.ipv4.sin_addr.s_addr; - } - } - else - { - assert(raw_ip_version==AF_INET6); - char zero_arr[16]={0}; - if(memcmp(&local_addr.inner.ipv6.sin6_addr,zero_arr,16)!=0) - { - bind_addr_used=1; - bind_addr.v6=local_addr.inner.ipv6.sin6_addr; - } - } - //bind_address_uint32=local_ip_uint32;//only server has bind adress,client sets it to zero + if (lower_level) { + if (lower_level_manual) { + init_ifindex(if_name, raw_send_fd, ifindex); + mylog(log_info, "we are running at lower-level (manual) mode\n"); + } else { + mylog(log_info, "we are running at lower-level (auto) mode\n"); + } + } - if(lower_level) - { - if(lower_level_manual) - { - init_ifindex(if_name,raw_send_fd,ifindex); - mylog(log_info,"we are running at lower-level (manual) mode\n"); - } - else - { - mylog(log_info,"we are running at lower-level (auto) mode\n"); - } + if (raw_mode == mode_faketcp) { + bind_fd = socket(local_addr.get_type(), SOCK_STREAM, 0); + } else if (raw_mode == mode_udp || raw_mode == mode_icmp) // bind an adress to avoid collision,for icmp,there is no port,just bind a udp port + { + bind_fd = socket(local_addr.get_type(), SOCK_DGRAM, 0); + } - } - - if(raw_mode==mode_faketcp) - { - bind_fd=socket(local_addr.get_type(),SOCK_STREAM,0); - } - else if(raw_mode==mode_udp||raw_mode==mode_icmp)//bind an adress to avoid collision,for icmp,there is no port,just bind a udp port - { - bind_fd=socket(local_addr.get_type(),SOCK_DGRAM,0); - } - - //struct sockaddr_in temp_bind_addr={0}; + // struct sockaddr_in temp_bind_addr={0}; // bzero(&temp_bind_addr, sizeof(temp_bind_addr)); - //temp_bind_addr.sin_family = AF_INET; - //temp_bind_addr.sin_port = local_addr.get_port(); - //temp_bind_addr.sin_addr.s_addr = local_addr.inner.ipv4.sin_addr.s_addr; + // temp_bind_addr.sin_family = AF_INET; + // temp_bind_addr.sin_port = local_addr.get_port(); + // temp_bind_addr.sin_addr.s_addr = local_addr.inner.ipv4.sin_addr.s_addr; - if (bind(bind_fd, (struct sockaddr*)&local_addr.inner, local_addr.get_len()) !=0) - { - mylog(log_fatal,"bind fail\n"); - myexit(-1); - } + if (bind(bind_fd, (struct sockaddr *)&local_addr.inner, local_addr.get_len()) != 0) { + mylog(log_fatal, "bind fail\n"); + myexit(-1); + } - if(raw_mode==mode_faketcp) - { + if (raw_mode == mode_faketcp) { + if (listen(bind_fd, SOMAXCONN) != 0) { + mylog(log_fatal, "listen fail\n"); + myexit(-1); + } + } - if(listen(bind_fd, SOMAXCONN) != 0 ) - { - mylog(log_fatal,"listen fail\n"); - myexit(-1); - } - } + // init_raw_socket(); + init_filter(local_addr.get_port()); // bpf filter + 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); + } - //init_raw_socket(); - init_filter(local_addr.get_port());//bpf filter + ev.events = EPOLLIN; + ev.data.u64 = raw_recv_fd; - epollfd = epoll_create1(0); - const int max_events = 4096; + ret = epoll_ctl(epollfd, EPOLL_CTL_ADD, raw_recv_fd, &ev); + if (ret != 0) { + mylog(log_fatal, "add raw_fd error\n"); + myexit(-1); + } + int timer_fd; - struct epoll_event ev, events[max_events]; - if (epollfd < 0) { - mylog(log_fatal,"epoll return %d\n", epollfd); - myexit(-1); - } + set_timer(epollfd, timer_fd); - ev.events = EPOLLIN; - ev.data.u64 = raw_recv_fd; + u64_t begin_time = 0; + u64_t end_time = 0; - ret = epoll_ctl(epollfd, EPOLL_CTL_ADD, raw_recv_fd, &ev); - if (ret!= 0) { - mylog(log_fatal,"add raw_fd error\n"); - myexit(-1); - } - int timer_fd; + mylog(log_info, "now listening at %s\n", local_addr.get_str()); - set_timer(epollfd,timer_fd); + int fifo_fd = -1; - u64_t begin_time=0; - u64_t end_time=0; + if (fifo_file[0] != 0) { + fifo_fd = create_fifo(fifo_file); + ev.events = EPOLLIN; + ev.data.u64 = fifo_fd; - mylog(log_info,"now listening at %s\n",local_addr.get_str()); + ret = epoll_ctl(epollfd, EPOLL_CTL_ADD, fifo_fd, &ev); + if (ret != 0) { + mylog(log_fatal, "add fifo_fd to epoll error %s\n", strerror(errno)); + myexit(-1); + } + mylog(log_info, "fifo_file=%s\n", fifo_file); + } - int fifo_fd=-1; + while (1) //////////////////////// + { + if (about_to_exit) myexit(0); - if(fifo_file[0]!=0) - { - fifo_fd=create_fifo(fifo_file); - ev.events = EPOLLIN; - ev.data.u64 = fifo_fd; + int nfds = epoll_wait(epollfd, events, max_events, 180 * 1000); + if (nfds < 0) { // allow zero + if (errno == EINTR) { + mylog(log_info, "epoll interrupted by signal,continue\n"); + // myexit(0); + } else { + mylog(log_fatal, "epoll_wait return %d,%s\n", nfds, strerror(errno)); + myexit(-1); + } + } + int idx; + for (idx = 0; idx < nfds; ++idx) { + // mylog(log_debug,"ndfs: %d \n",nfds); + epoll_trigger_counter++; + // printf("%d %d %d %d\n",timer_fd,raw_recv_fd,raw_send_fd,n); + if ((events[idx].data.u64) == (u64_t)timer_fd) { + if (debug_flag) begin_time = get_current_time(); + conn_manager.clear_inactive(); + u64_t dummy; + int unused = read(timer_fd, &dummy, 8); + // current_time_rough=get_current_time(); + if (debug_flag) { + end_time = get_current_time(); + mylog(log_debug, "timer_fd,%llu,%llu,%llu\n", begin_time, end_time, end_time - begin_time); + } - ret = epoll_ctl(epollfd, EPOLL_CTL_ADD, fifo_fd, &ev); - if (ret!= 0) { - mylog(log_fatal,"add fifo_fd to epoll error %s\n",strerror(errno)); - myexit(-1); - } - mylog(log_info,"fifo_file=%s\n",fifo_file); - } + mylog(log_trace, "epoll_trigger_counter: %d \n", epoll_trigger_counter); + epoll_trigger_counter = 0; - - while(1)//////////////////////// - { - - if(about_to_exit) myexit(0); - - int nfds = epoll_wait(epollfd, events, max_events, 180 * 1000); - if (nfds < 0) { //allow zero - if(errno==EINTR ) - { - mylog(log_info,"epoll interrupted by signal,continue\n"); - //myexit(0); - } - else - { - mylog(log_fatal,"epoll_wait return %d,%s\n", nfds,strerror(errno)); - myexit(-1); - } - } - int idx; - for (idx = 0; idx < nfds; ++idx) - { - //mylog(log_debug,"ndfs: %d \n",nfds); - epoll_trigger_counter++; - //printf("%d %d %d %d\n",timer_fd,raw_recv_fd,raw_send_fd,n); - if ((events[idx].data.u64 ) == (u64_t)timer_fd) - { - if(debug_flag)begin_time=get_current_time(); - conn_manager.clear_inactive(); - u64_t dummy; - int unused=read(timer_fd, &dummy, 8); - //current_time_rough=get_current_time(); - if(debug_flag) - { - end_time=get_current_time(); - mylog(log_debug,"timer_fd,%llu,%llu,%llu\n",begin_time,end_time,end_time-begin_time); - } - - mylog(log_trace,"epoll_trigger_counter: %d \n",epoll_trigger_counter); - epoll_trigger_counter=0; - - } - else if (events[idx].data.u64 == (u64_t)raw_recv_fd) - { - if(debug_flag)begin_time=get_current_time(); - server_on_raw_recv_multi(); - if(debug_flag) - { - end_time=get_current_time(); - mylog(log_debug,"raw_recv_fd,%llu,%llu,%llu \n",begin_time,end_time,end_time-begin_time); - } - } - else if (events[idx].data.u64 == (u64_t)fifo_fd) - { - int len=read (fifo_fd, buf, sizeof (buf)); - if(len<0) - { - mylog(log_warn,"fifo read failed len=%d,errno=%s\n",len,strerror(errno)); - continue; - } - //assert(len>=0); - 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); - mylog(log_info,"unknown command\n"); - } - else if (events[idx].data.u64>u32_t(-1) ) - { - - fd64_t fd64=events[idx].data.u64; - if(!fd_manager.exist(fd64)) - { - mylog(log_trace ,"fd64 no longer exist\n"); - return -1; - } - assert(fd_manager.exist_info(fd64)); - conn_info_t* p_conn_info=fd_manager.get_info(fd64).p_conn_info; - conn_info_t &conn_info=*p_conn_info; - if(fd64==conn_info.timer_fd64)//////////timer_fd64 - { - - if(debug_flag)begin_time=get_current_time(); - int fd=fd_manager.to_fd(fd64); - u64_t dummy; - int unused=read(fd, &dummy, 8); - assert(conn_info.state.server_current_state == server_ready); //TODO remove this for peformance - server_on_timer_multi(conn_info); - if(debug_flag) - { - end_time=get_current_time(); - mylog(log_debug,"(events[idx].data.u64 >>32u) == 2u ,%llu,%llu,%llu \n",begin_time,end_time,end_time-begin_time); - } - } - else//udp_fd64 - { - if(debug_flag)begin_time=get_current_time(); - server_on_udp_recv(conn_info,fd64); - if(debug_flag) - { - end_time=get_current_time(); - mylog(log_debug,"(events[idx].data.u64 >>32u) == 1u,%lld,%lld,%lld \n",begin_time,end_time,end_time-begin_time); - } - } - } - else - { - mylog(log_fatal,"unknown fd,this should never happen\n"); - myexit(-1); - } - - } - } - return 0; + } else if (events[idx].data.u64 == (u64_t)raw_recv_fd) { + if (debug_flag) begin_time = get_current_time(); + server_on_raw_recv_multi(); + if (debug_flag) { + end_time = get_current_time(); + mylog(log_debug, "raw_recv_fd,%llu,%llu,%llu \n", begin_time, end_time, end_time - begin_time); + } + } else if (events[idx].data.u64 == (u64_t)fifo_fd) { + int len = read(fifo_fd, buf, sizeof(buf)); + if (len < 0) { + mylog(log_warn, "fifo read failed len=%d,errno=%s\n", len, strerror(errno)); + continue; + } + // assert(len>=0); + 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); + mylog(log_info, "unknown command\n"); + } else if (events[idx].data.u64 > u32_t(-1)) { + fd64_t fd64 = events[idx].data.u64; + if (!fd_manager.exist(fd64)) { + mylog(log_trace, "fd64 no longer exist\n"); + return -1; + } + assert(fd_manager.exist_info(fd64)); + conn_info_t *p_conn_info = fd_manager.get_info(fd64).p_conn_info; + conn_info_t &conn_info = *p_conn_info; + if (fd64 == conn_info.timer_fd64) //////////timer_fd64 + { + if (debug_flag) begin_time = get_current_time(); + int fd = fd_manager.to_fd(fd64); + u64_t dummy; + int unused = read(fd, &dummy, 8); + assert(conn_info.state.server_current_state == server_ready); // TODO remove this for peformance + server_on_timer_multi(conn_info); + if (debug_flag) { + end_time = get_current_time(); + mylog(log_debug, "(events[idx].data.u64 >>32u) == 2u ,%llu,%llu,%llu \n", begin_time, end_time, end_time - begin_time); + } + } else // udp_fd64 + { + if (debug_flag) begin_time = get_current_time(); + server_on_udp_recv(conn_info, fd64); + if (debug_flag) { + end_time = get_current_time(); + mylog(log_debug, "(events[idx].data.u64 >>32u) == 1u,%lld,%lld,%lld \n", begin_time, end_time, end_time - begin_time); + } + } + } else { + mylog(log_fatal, "unknown fd,this should never happen\n"); + myexit(-1); + } + } + } + return 0; } #endif