Ver Fonte

prepare for ipv6

wangyu- há 7 anos atrás
pai
commit
9c1a8c859d
9 ficheiros alterados com 609 adições e 220 exclusões
  1. 365 127
      common.cpp
  2. 175 14
      common.h
  3. 2 1
      connection.h
  4. 3 3
      main.cpp
  5. 6 28
      misc.cpp
  6. 5 3
      misc.h
  7. 14 5
      packet.cpp
  8. 12 12
      tunnel_client.cpp
  9. 27 27
      tunnel_server.cpp

+ 365 - 127
common.cpp

@@ -76,6 +76,52 @@ return 0;
 }
 
 #if defined(__MINGW32__)
+int inet_pton(int af, const char *src, void *dst)
+{
+  struct sockaddr_storage ss;
+  int size = sizeof(ss);
+  char src_copy[INET6_ADDRSTRLEN+1];
+
+  ZeroMemory(&ss, sizeof(ss));
+  /* stupid non-const API */
+  strncpy (src_copy, src, INET6_ADDRSTRLEN+1);
+  src_copy[INET6_ADDRSTRLEN] = 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];
@@ -155,6 +201,252 @@ struct my_random_t
 	}*/
 }my_random;
 
+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;
+}
+
+int address_t::from_str_ip_only(char * str)
+{
+	clear();
+
+	u32_t type;
+
+	if(strchr(str,':')==NULL)
+		type=AF_INET;
+	else
+		type=AF_INET6;
+
+	((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);
+	}
+
+	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;
+}
+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;
+}
+
+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);
+	}
+
+	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;
+}
+
+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 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;
+}
+
 void get_fake_random_chars(char * s,int len)
 {
 	char *p=s;
@@ -288,45 +580,6 @@ char * my_ntoa(u32_t ip)
 	return inet_ntoa(a);
 }
 
-
-int add_iptables_rule(char * s)
-{
-	strcpy(iptables_rule,s);
-	char buf[300]="iptables -I ";
-	strcat(buf,s);
-	if(system(buf)==0)
-	{
-		mylog(log_warn,"auto added iptables rule by:  %s\n",buf);
-	}
-	else
-	{
-		mylog(log_fatal,"auto added iptables failed by: %s\n",buf);
-		myexit(-1);
-	}
-	return 0;
-}
-
-int clear_iptables_rule()
-{
-	if(iptables_rule[0]!=0)
-	{
-		char buf[300]="iptables -D ";
-		strcat(buf,iptables_rule);
-		if(system(buf)==0)
-		{
-			mylog(log_warn,"iptables rule cleared by: %s \n",buf);
-		}
-		else
-		{
-			mylog(log_error,"clear iptables failed by: %s\n",buf);
-		}
-
-	}
-	return 0;
-}
-
-
-
 u64_t get_fake_random_number_64()
 {
 	//u64_t ret;
@@ -465,35 +718,17 @@ unsigned short tcp_csum(const pseudo_header & ph,const unsigned short *ptr,int n
     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(0)
+	if(setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &socket_buf_size, sizeof(socket_buf_size))<0)
 	{
-/*
-		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);
-		}
-*/
+		mylog(log_fatal,"SO_SNDBUF fail  socket_buf_size=%d  errno=%s\n",socket_buf_size,get_sock_error());
+		myexit(1);
 	}
-	else
+	if(setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &socket_buf_size, sizeof(socket_buf_size))<0)
 	{
-		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);
-		}
+		mylog(log_fatal,"SO_RCVBUF fail  socket_buf_size=%d  errno=%s\n",socket_buf_size,get_sock_error());
+		myexit(1);
 	}
 	return 0;
 }
@@ -538,69 +773,6 @@ int char_to_numbers(const char * data,int len,id_t &id1,id_t &id2,id_t &id3)
 	return 0;
 }
 */
-bool larger_than_u32(u32_t a,u32_t b)
-{
-
-	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)
-{
-
-	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;
-		}
-	}
-}
-
-
 
 
 /*
@@ -783,3 +955,69 @@ int new_connected_socket(int &fd,u32_t ip,int port)
 	return 0;
 }
 
+int new_listen_socket2(int &fd,address_t &addr)
+{
+	fd =socket(addr.get_type(), SOCK_DGRAM, IPPROTO_UDP);
+
+	int yes = 1;
+
+	if (::bind(fd, (struct sockaddr*) &addr.inner, addr.get_len()) == -1) {
+		mylog(log_fatal,"socket bind error\n");
+		//perror("socket bind error");
+		myexit(1);
+	}
+	setnonblocking(fd);
+    set_buf_size(fd,socket_buf_size);
+
+    mylog(log_debug,"local_listen_fd=%d\n",fd);
+
+	return 0;
+}
+int new_connected_socket2(int &fd,address_t &addr)
+{
+	fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+	if (fd < 0) {
+		mylog(log_warn, "[%s]create udp_fd error\n", addr.get_str());
+		return -1;
+	}
+	setnonblocking(fd);
+	set_buf_size(fd, socket_buf_size);
+
+	mylog(log_debug, "[%s]created new udp_fd %d\n", addr.get_str(), fd);
+	int ret = connect(fd, (struct sockaddr *) &addr.inner, addr.get_len());
+	if (ret != 0) {
+		mylog(log_warn, "[%s]fd connect fail\n",addr.get_str());
+		sock_close(fd);
+		return -1;
+	}
+	return 0;
+}
+
+
+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;
+ }
+

+ 175 - 14
common.h

@@ -65,7 +65,10 @@ typedef int i32_t;
 typedef unsigned short u16_t;
 typedef short i16_t;
 
+
 #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)
 #endif
 
@@ -96,7 +99,7 @@ struct my_itimerspec {
 
 typedef u64_t my_time_t;
 
-
+const int max_addr_len=100;
 const int max_data_len=3600;
 const int buf_len=max_data_len+200;
 
@@ -169,8 +172,9 @@ typedef u64_t anti_replay_seq_t;
 typedef u64_t fd64_t;
 
 //enum dest_type{none=0,type_fd64_ip_port,type_fd64,type_fd64_ip_port_conv,type_fd64_conv/*,type_fd*/};
-enum dest_type{none=0,type_fd64_ip_port,type_fd64,type_fd,type_write_fd,type_fd_ip_port/*,type_fd*/};
+enum dest_type{none=0,type_fd64_addr,type_fd64,type_fd,type_write_fd,type_fd_addr/*,type_fd*/};
 
+/*
 struct ip_port_t
 {
 	u32_t ip;
@@ -189,13 +193,175 @@ struct fd_ip_port_t
 {
 	int fd;
 	ip_port_t ip_port;
+};*/
+
+
+struct pseudo_header {
+    u32_t source_address;
+    u32_t dest_address;
+    unsigned char placeholder;
+    unsigned char protocol;
+    unsigned short tcp_length;
+};
+
+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_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_INET;
+			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();
+};
+
+namespace std {
+template <>
+ struct hash<address_t>
+ {
+   std::size_t operator()(const address_t& key) const
+   {
+
+	 //return address_t::hash_function(k);
+	   return sdbm((unsigned char*)&key.inner,sizeof(key.inner));
+   }
+ };
+}
+
+struct fd64_addr_t
+{
+	fd64_t fd64;
+	address_t addr;
+};
+struct fd_addr_t
+{
+	int fd;
+	address_t addr;
 };
 union inner_t
 {
 	fd64_t fd64;
 	int fd;
-	fd64_ip_port_t fd64_ip_port;
-	fd_ip_port_t fd_ip_port;
+	fd64_addr_t fd64_addr;
+	fd_addr_t fd_addr;
 };
 struct dest_t
 {
@@ -207,18 +373,10 @@ struct dest_t
 
 struct fd_info_t
 {
-	ip_port_t ip_port;
+	address_t addr;
 	ev_io io_watcher;
 };
 
-struct pseudo_header {
-    u32_t source_address;
-    u32_t dest_address;
-    unsigned char placeholder;
-    unsigned char protocol;
-    unsigned short tcp_length;
-};
-
 u64_t get_current_time();
 u64_t get_current_time_rough();
 u64_t get_current_time_us();
@@ -249,7 +407,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=0);
+int set_buf_size(int fd,int socket_buf_size);
 
 unsigned short csum(const unsigned short *ptr,int nbytes);
 unsigned short tcp_csum(const pseudo_header & ph,const unsigned short *ptr,int nbytes);
@@ -279,4 +437,7 @@ int new_listen_socket(int &fd,u32_t ip,int port);
 
 int new_connected_socket(int &fd,u32_t ip,int port);
 
+int new_listen_socket2(int &fd,address_t &addr);
+int new_connected_socket2(int &fd,address_t &addr);
+
 #endif /* COMMON_H_ */

+ 2 - 1
connection.h

@@ -118,7 +118,8 @@ struct conn_info_t     //stores info for a raw connection.for client ,there is o
 	int remote_fd;  //only used for client
 	fd64_t remote_fd64;//only used for client
 
-	ip_port_t ip_port;//only used for server
+	//ip_port_t ip_port;
+	address_t  addr;//only used for server
 
 	conn_info_t()
 	{

+ 3 - 3
main.cpp

@@ -144,9 +144,9 @@ int main(int argc, char *argv[])
 	process_arg(argc,argv);
 
 	delay_manager.set_capacity(delay_capacity);
-	local_ip_uint32=inet_addr(local_ip);
-	remote_ip_uint32=inet_addr(remote_ip);
-	sub_net_uint32=inet_addr(sub_net);
+	//local_ip_uint32=inet_addr(local_ip);
+	//remote_ip_uint32=inet_addr(remote_ip);
+	sub_net_uint32=inet_addr(sub_net);// used only in tinyfecVPN
 
 	if(strlen(tun_dev)==0)
 	{

+ 6 - 28
misc.cpp

@@ -27,9 +27,10 @@ int output_interval_max=0*1000;
 
 int fix_latency=0;
 
-u32_t local_ip_uint32,remote_ip_uint32=0;
-char local_ip[100], remote_ip[100];
-int local_port = -1, remote_port = -1;
+address_t local_addr,remote_addr;
+//u32_t local_ip_uint32,remote_ip_uint32=0;
+//char local_ip[100], remote_ip[100];
+//int local_port = -1, remote_port = -1;
 
 conn_manager_t conn_manager;
 delay_manager_t delay_manager;
@@ -773,34 +774,11 @@ void process_arg(int argc, char *argv[])
 			break;
 		case 'l':
 			no_l = 0;
-			if (strchr(optarg, ':') != 0)
-			{
-				sscanf(optarg, "%[^:]:%d", local_ip, &local_port);
-			}
-			else
-			{
-				mylog(log_fatal,"-l ip:port\n");
-				myexit(1);
-				strcpy(local_ip, "127.0.0.1");
-				sscanf(optarg, "%d", &local_port);
-			}
+			local_addr.from_str(optarg);
 			break;
 		case 'r':
 			no_r = 0;
-			if (strchr(optarg, ':') != 0)
-			{
-				//printf("in :\n");
-				//printf("%s\n",optarg);
-				sscanf(optarg, "%[^:]:%d", remote_ip, &remote_port);
-				//printf("%d\n",remote_port);
-			}
-			else
-			{
-				mylog(log_fatal," -r ip:port\n");
-				myexit(1);
-				strcpy(remote_ip, "127.0.0.1");
-				sscanf(optarg, "%d", &remote_port);
-			}
+			remote_addr.from_str(optarg);
 			break;
 		case 'h':
 			break;

+ 5 - 3
misc.h

@@ -34,9 +34,11 @@ extern int output_interval_max;
 
 extern int fix_latency;
 
-extern u32_t local_ip_uint32,remote_ip_uint32;
-extern char local_ip[100], remote_ip[100];
-extern int local_port, remote_port;
+//extern u32_t local_ip_uint32,remote_ip_uint32;
+//extern char local_ip[100], remote_ip[100];
+//extern int local_port, remote_port;
+
+extern address_t local_addr,remote_addr;
 
 extern conn_manager_t conn_manager;
 extern delay_manager_t delay_manager;

+ 14 - 5
packet.cpp

@@ -146,7 +146,7 @@ int de_obscure_old(const char * input, int in_len,char *output,int &out_len)
 	return 0;
 }
 
-
+/*
 int sendto_fd_ip_port (int fd,u32_t ip,int port,char * buf, int len,int flags)
 {
 
@@ -161,6 +161,15 @@ int sendto_fd_ip_port (int fd,u32_t ip,int port,char * buf, int len,int flags)
 			len , 0,
 			(struct sockaddr *) &tmp_sockaddr,
 			sizeof(tmp_sockaddr));
+}*/
+
+int sendto_fd_addr (int fd,address_t addr,char * buf, int len,int flags)
+{
+
+	return sendto(fd, buf,
+			len , 0,
+			(struct sockaddr *) &addr.inner,
+			addr.get_len());
 }
 /*
 int sendto_ip_port (u32_t ip,int port,char * buf, int len,int flags)
@@ -181,17 +190,17 @@ int my_send(const dest_t &dest,char *data,int len)
 	}
 	switch(dest.type)
 	{
-		case type_fd_ip_port:
+		case type_fd_addr:
 		{
-			return sendto_fd_ip_port(dest.inner.fd,dest.inner.fd_ip_port.ip_port.ip,dest.inner.fd_ip_port.ip_port.port,data,len,0);
+			return sendto_fd_addr(dest.inner.fd,dest.inner.fd_addr.addr,data,len,0);
 			break;
 		}
-		case type_fd64_ip_port:
+		case type_fd64_addr:
 		{
 			if(!fd_manager.exist(dest.inner.fd64)) return -1;
 			int fd=fd_manager.to_fd(dest.inner.fd64);
 
-			return sendto_fd_ip_port(fd,dest.inner.fd64_ip_port.ip_port.ip,dest.inner.fd64_ip_port.ip_port.port,data,len,0);
+			return sendto_fd_addr(fd,dest.inner.fd64_addr.addr,data,len,0);
 			break;
 		}
 		case type_fd:

+ 12 - 12
tunnel_client.cpp

@@ -7,7 +7,7 @@ void data_from_local_or_fec_timeout(conn_info_t & conn_info,int is_time_out)
 
 	char data[buf_len];
 	int data_len;
-	ip_port_t ip_port;
+	address_t addr;
 	u32_t conv;
 	int  out_n;char **out_arr;int *out_len;my_time_t *out_delay;
 	dest_t dest;
@@ -42,8 +42,8 @@ void data_from_local_or_fec_timeout(conn_info_t & conn_info,int is_time_out)
 	else//events[idx].data.u64 == (u64_t)local_listen_fd
 	{
 		mylog(log_trace,"events[idx].data.u64 == (u64_t)local_listen_fd\n");
-		struct sockaddr_in udp_new_addr_in={0};
-		socklen_t udp_new_addr_len = sizeof(sockaddr_in);
+		address_t::storage_t udp_new_addr_in={0};
+		socklen_t udp_new_addr_len = sizeof(address_t::storage_t);
 		if ((data_len = recvfrom(local_listen_fd, data, max_data_len, 0,
 				(struct sockaddr *) &udp_new_addr_in, &udp_new_addr_len)) == -1) {
 			mylog(log_debug,"recv_from error,this shouldnt happen,err=%s,but we can try to continue\n",get_sock_error());
@@ -54,11 +54,11 @@ void data_from_local_or_fec_timeout(conn_info_t & conn_info,int is_time_out)
 		{
 			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 ",data_len,mtu_warn);
 		}
-		mylog(log_trace,"Received packet from %s:%d,len: %d\n", inet_ntoa(udp_new_addr_in.sin_addr),
-				ntohs(udp_new_addr_in.sin_port),data_len);
 
-		ip_port.ip=udp_new_addr_in.sin_addr.s_addr;
-		ip_port.port=ntohs(udp_new_addr_in.sin_port);
+
+		addr.from_sockaddr((struct sockaddr *) &udp_new_addr_in,udp_new_addr_len);
+
+		mylog(log_trace,"Received packet from %s, len: %d\n", addr.get_str(),data_len);
 
 		u64_t u64=ip_port.to_u64();
 
@@ -71,7 +71,7 @@ void data_from_local_or_fec_timeout(conn_info_t & conn_info,int is_time_out)
 			}
 			conv=conn_info.conv_manager.get_new_conv();
 			conn_info.conv_manager.insert_conv(conv,u64);
-			mylog(log_info,"new packet from %s:%d,conv_id=%x\n",inet_ntoa(udp_new_addr_in.sin_addr),ntohs(udp_new_addr_in.sin_port),conv);
+			mylog(log_info,"new packet from %s,conv_id=%x\n",addr.get_str(),conv);
 		}
 		else
 		{
@@ -170,9 +170,9 @@ static void remote_cb(struct ev_loop *loop, struct ev_io *watcher, int revents)
 
 		u64_t u64=conn_info.conv_manager.find_u64_by_conv(conv);
 		dest_t dest;
-		dest.inner.fd_ip_port.fd=conn_info.local_listen_fd;
+		dest.inner.fd_addr.fd=conn_info.local_listen_fd;
 		dest.inner.fd_ip_port.ip_port.from_u64(u64);
-		dest.type=type_fd_ip_port;
+		dest.type=type_fd_addr;
 
 		delay_send(out_delay[i],dest,new_data,new_len);
 	}
@@ -262,7 +262,7 @@ int tunnel_client_event_loop()
     conn_info_t &conn_info=*conn_info_p;  //huge size of conn_info,do not allocate on stack
 
 	int &local_listen_fd=conn_info.local_listen_fd;
-    new_listen_socket(local_listen_fd,local_ip_uint32,local_port);
+    new_listen_socket2(local_listen_fd,local_addr);
 
 	//epoll_fd = epoll_create1(0);
 	//assert(epoll_fd>0);
@@ -295,7 +295,7 @@ int tunnel_client_event_loop()
     int & remote_fd=conn_info.remote_fd;
     fd64_t &remote_fd64=conn_info.remote_fd64;
 
-	assert(new_connected_socket(remote_fd,remote_ip_uint32,remote_port)==0);
+	assert(new_connected_socket2(remote_fd,remote_addr)==0);
 	remote_fd64=fd_manager.create(remote_fd);
 
 	mylog(log_debug,"remote_fd64=%llu\n",remote_fd64);

+ 27 - 27
tunnel_server.cpp

@@ -29,17 +29,17 @@ void data_from_remote_or_fec_timeout_or_conn_timer(conn_info_t & conn_info,fd64_
 
 
 	//conn_info_t &conn_info=conn_manager.find(ip_port);
-	ip_port_t &ip_port=conn_info.ip_port;
-	assert(conn_manager.exist(ip_port));
+	address_t &addr=conn_info.addr;
+	assert(conn_manager.exist(addr));
 
 	int &local_listen_fd=conn_info.local_listen_fd;
 
 	int  out_n=-2;char **out_arr;int *out_len;my_time_t *out_delay;
 
 	dest_t dest;
-	dest.inner.fd_ip_port.fd=local_listen_fd;
-	dest.inner.fd_ip_port.ip_port=ip_port;
-	dest.type=type_fd_ip_port;
+	dest.inner.fd_addr.fd=local_listen_fd;
+	dest.inner.fd_addr.addr=addr;
+	dest.type=type_fd_addr;
 	dest.cook=1;
 
 	if(mode==is_fec_timeout)
@@ -70,7 +70,7 @@ void data_from_remote_or_fec_timeout_or_conn_timer(conn_info_t & conn_info,fd64_
 		from_normal_to_fec(conn_info,0,0,out_n,out_arr,out_len,out_delay);
 		}
 
-		conn_info.stat.report_as_server(ip_port);
+		conn_info.stat.report_as_server(addr);
 		return;
 	}
 	else if(mode==is_from_remote)
@@ -133,15 +133,18 @@ static void local_listen_cb(struct ev_loop *loop, struct ev_io *watcher, int rev
 	mylog(log_trace,"events[idx].data.u64 == (u64_t)local_listen_fd\n");
 	char data[buf_len];
 	int data_len;
-	struct sockaddr_in udp_new_addr_in={0};
-	socklen_t udp_new_addr_len = sizeof(sockaddr_in);
+	address_t::storage_t udp_new_addr_in={0};
+	socklen_t udp_new_addr_len = sizeof(address_t::storage_t);
 	if ((data_len = recvfrom(local_listen_fd, data, max_data_len, 0,
 			(struct sockaddr *) &udp_new_addr_in, &udp_new_addr_len)) == -1) {
 		mylog(log_error,"recv_from error,this shouldnt happen,err=%s,but we can try to continue\n",get_sock_error());
 		return;
 	};
-	mylog(log_trace,"Received packet from %s:%d,len: %d\n", inet_ntoa(udp_new_addr_in.sin_addr),
-			ntohs(udp_new_addr_in.sin_port),data_len);
+
+	address_t addr;
+	addr.from_sockaddr((struct sockaddr *) &udp_new_addr_in,udp_new_addr_len);
+
+	mylog(log_trace,"Received packet from %s,len: %d\n", addr.get_str(),data_len);
 
 	if(!disable_mtu_warn&&data_len>=mtu_warn)///////////////////////delete this for type 0 in furture
 	{
@@ -156,21 +159,18 @@ static void local_listen_cb(struct ev_loop *loop, struct ev_io *watcher, int rev
 	}
 
 
-	ip_port_t ip_port;
-	ip_port.ip=udp_new_addr_in.sin_addr.s_addr;
-	ip_port.port=ntohs(udp_new_addr_in.sin_port);
-	mylog(log_trace,"ip_port= %s\n",ip_port.to_s());
-	if(!conn_manager.exist(ip_port))
+
+	if(!conn_manager.exist(addr))
 	{
 		if(conn_manager.mp.size() >=max_conn_num)
 		{
-			mylog(log_warn,"new connection %s ignored bc max_conn_num exceed\n",ip_port.to_s());
+			mylog(log_warn,"new connection %s ignored bc max_conn_num exceed\n",addr.get_str());
 			return;
 		}
 
-		conn_manager.insert(ip_port);
-		conn_info_t &conn_info=conn_manager.find(ip_port);
-		conn_info.ip_port=ip_port;
+		conn_manager.insert(addr);
+		conn_info_t &conn_info=conn_manager.find(addr);
+		conn_info.addr=addr;
 		conn_info.loop=ev_default_loop(0);
 		conn_info.local_listen_fd=local_listen_fd;
 
@@ -201,10 +201,10 @@ static void local_listen_cb(struct ev_loop *loop, struct ev_io *watcher, int rev
 	    conn_info.fec_encode_manager.set_loop_and_cb(loop,fec_encode_cb);
 
 
-		mylog(log_info,"new connection from %s\n",ip_port.to_s());
+		mylog(log_info,"new connection from %s\n",addr.get_str());
 
 	}
-	conn_info_t &conn_info=conn_manager.find(ip_port);
+	conn_info_t &conn_info=conn_manager.find(addr);
 
 	conn_info.update_active_time();
 	int  out_n;char **out_arr;int *out_len;my_time_t *out_delay;
@@ -232,10 +232,10 @@ static void local_listen_cb(struct ev_loop *loop, struct ev_io *watcher, int rev
 			}
 
 			int new_udp_fd;
-			ret=new_connected_socket(new_udp_fd,remote_ip_uint32,remote_port);
+			ret=new_connected_socket2(new_udp_fd,remote_addr);
 
 			if (ret != 0) {
-				mylog(log_warn, "[%s]new_connected_socket failed\n",ip_port.to_s());
+				mylog(log_warn, "[%s]new_connected_socket failed\n",addr.get_str());
 				continue;
 			}
 
@@ -245,7 +245,7 @@ static void local_listen_cb(struct ev_loop *loop, struct ev_io *watcher, int rev
 			//ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, new_udp_fd, &ev);
 
 			conn_info.conv_manager.insert_conv(conv, fd64);
-			fd_manager.get_info(fd64).ip_port=ip_port;
+			fd_manager.get_info(fd64).addr=addr;
 
 			ev_io &io_watcher=fd_manager.get_info(fd64).io_watcher;
 			io_watcher.u64=fd64;
@@ -256,7 +256,7 @@ static void local_listen_cb(struct ev_loop *loop, struct ev_io *watcher, int rev
 			ev_io_start(conn_info.loop,&io_watcher);
 
 
-			mylog(log_info,"[%s]new conv %x,fd %d created,fd64=%llu\n",ip_port.to_s(),conv,new_udp_fd,fd64);
+			mylog(log_info,"[%s]new conv %x,fd %d created,fd64=%llu\n",addr.get_str(),conv,new_udp_fd,fd64);
 		}
 		conn_info.conv_manager.update_active_time(conv);
 		fd64_t fd64= conn_info.conv_manager.find_u64_by_conv(conv);
@@ -350,7 +350,7 @@ int tunnel_server_event_loop()
 	//int remote_fd;
 
 	int local_listen_fd;
-    new_listen_socket(local_listen_fd,local_ip_uint32,local_port);
+    new_listen_socket2(local_listen_fd,local_addr);
 
 	//epoll_fd = epoll_create1(0);
 	//assert(epoll_fd>0);
@@ -388,7 +388,7 @@ int tunnel_server_event_loop()
 
 	//mylog(log_debug," delay_manager.get_timer_fd() =%d\n", delay_manager.get_timer_fd());
 
-	mylog(log_info,"now listening at %s:%d\n",my_ntoa(local_ip_uint32),local_port);
+	mylog(log_info,"now listening at %s:%d\n",local_addr.get_str());
 
 	//my_timer_t timer;
 	//timer.add_fd_to_epoll(epoll_fd);