From bec9c959991ace65d14de2a27e6b6b748e1c15a3 Mon Sep 17 00:00:00 2001 From: wangyu- Date: Tue, 17 Jul 2018 02:31:14 -0500 Subject: [PATCH] ipv6 prepare --- common.cpp | 202 ++++++++++++++++++++++++++++++++++++++++++++++++++++- common.h | 75 ++++++++++++++++++-- main.cpp | 4 +- misc.cpp | 11 +-- misc.h | 12 ++-- 5 files changed, 285 insertions(+), 19 deletions(-) diff --git a/common.cpp b/common.cpp index 73fbe45..77fdafc 100644 --- a/common.cpp +++ b/common.cpp @@ -12,6 +12,177 @@ static int random_number_fd=-1; +int force_socket_buf=0; + +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); + } + + 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); + } + + 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); + } + } + + return 0; +} + +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); + } + + if(ret==0) //NULL on failure + { + mylog(log_error,"inet_ntop failed\n"); + myexit(-1); + } + + 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); + } + + //return res; +} + +int address_t::from_sockaddr(sockaddr * addr,socklen_t slen) +{ + memset(&inner,0,sizeof(inner)); + if(addr->sa_family==AF_INET6) + { + assert(slen==sizeof(sockaddr_in6)); + inner.ipv6= *( (sockaddr_in6*) addr ); + + } + else if(addr->sa_family==AF_INET) + { + assert(slen==sizeof(sockaddr_in)); + inner.ipv4= *( (sockaddr_in*) addr ); + } + else + { + assert(0==1); + } + return 0; +} + +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); + + 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; +} + + u64_t get_current_time() { timespec tmp_time; @@ -149,7 +320,7 @@ unsigned short csum(const unsigned short *ptr,int nbytes) {//works both for big return(answer); } -int set_buf_size(int fd,int socket_buf_size,int force_socket_buf) +int set_buf_size(int fd,int socket_buf_size) { if(force_socket_buf) { @@ -593,6 +764,7 @@ int create_fifo(char * file) return fifo_fd; } +/* void ip_port_t::from_u64(u64_t u64) { ip=get_u64_h(u64); @@ -607,7 +779,7 @@ char * ip_port_t::to_s() static char res[40]; sprintf(res,"%s:%d",my_ntoa(ip),port); return res; -} +}*/ @@ -622,6 +794,32 @@ void print_binary_chars(const char * a,int len) } +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; + } + +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 9a63ed9..b4020a3 100644 --- a/common.h +++ b/common.h @@ -71,7 +71,11 @@ typedef u64_t padding_t; typedef u64_t anti_replay_seq_t; +const int max_addr_len=100; +extern int force_socket_buf; + +/* struct ip_port_t { u32_t ip; @@ -79,13 +83,74 @@ struct ip_port_t 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); + +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)); + } + }; + + 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_str(char * str); + + int from_sockaddr(sockaddr *,socklen_t); + + char* get_str(); + void to_str(char *); + + inline u32_t get_type() + { + return ((sockaddr*)&inner)->sa_family; + } + + 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; + } + + 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(); +}; + const int max_data_len=1800; const int buf_len=max_data_len+400; @@ -109,7 +174,7 @@ u64_t hton64(u64_t a); 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 force_socket_buf); +int set_buf_size(int fd,int socket_buf_size); void myexit(int a); diff --git a/main.cpp b/main.cpp index fda25ca..555ecd2 100755 --- a/main.cpp +++ b/main.cpp @@ -841,7 +841,7 @@ int server_on_raw_recv_ready(conn_info_t &conn_info,char * ip_port,char type,cha return -1; } setnonblocking(new_udp_fd); - set_buf_size(new_udp_fd,socket_buf_size,force_socket_buf); + 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, @@ -1178,7 +1178,7 @@ int client_event_loop() //g_packet_info.src_port=source_port; udp_fd=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - set_buf_size(udp_fd,socket_buf_size,force_socket_buf); + set_buf_size(udp_fd,socket_buf_size); int yes = 1; //setsockopt(udp_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)); diff --git a/misc.cpp b/misc.cpp index a1e359b..8247540 100644 --- a/misc.cpp +++ b/misc.cpp @@ -28,10 +28,11 @@ 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 +//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; int force_source_ip=0; //if --source-ip is enabled @@ -80,7 +81,7 @@ int about_to_exit=0; int socket_buf_size=1024*1024; -int force_socket_buf=0; + //char lower_level_arg[1000]; int process_lower_level_arg()//handle --lower-level option diff --git a/misc.h b/misc.h index 3f43a9d..f30132c 100644 --- a/misc.h +++ b/misc.h @@ -73,10 +73,12 @@ union current_state_t 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; extern int force_source_ip; //if --source-ip is enabled @@ -113,7 +115,7 @@ extern unordered_map raw_mode_tostring ; extern int about_to_exit; extern int socket_buf_size; -extern int force_socket_buf; + extern pthread_t keep_thread; extern int keep_thread_running;