소스 검색

Merge pull request #227 from Llorx/branch_libev

Bind to address
wangyu- 5 년 전
부모
커밋
5bb65af72c
7개의 변경된 파일45개의 추가작업 그리고 8개의 파일을 삭제
  1. 15 2
      common.cpp
  2. 1 1
      common.h
  3. 2 0
      main.cpp
  4. 21 2
      misc.cpp
  5. 4 1
      misc.h
  6. 1 1
      tunnel_client.cpp
  7. 1 1
      tunnel_server.cpp

+ 15 - 2
common.cpp

@@ -953,7 +953,7 @@ int new_listen_socket2(int &fd,address_t &addr)
 	int yes = 1;
 	int yes = 1;
 
 
 	if (::bind(fd, (struct sockaddr*) &addr.inner, addr.get_len()) == -1) {
 	if (::bind(fd, (struct sockaddr*) &addr.inner, addr.get_len()) == -1) {
-		mylog(log_fatal,"socket bind error\n");
+		mylog(log_fatal,"socket bind error=%s\n",get_sock_error());
 		//perror("socket bind error");
 		//perror("socket bind error");
 		myexit(1);
 		myexit(1);
 	}
 	}
@@ -964,13 +964,26 @@ int new_listen_socket2(int &fd,address_t &addr)
 
 
 	return 0;
 	return 0;
 }
 }
-int new_connected_socket2(int &fd,address_t &addr)
+int new_connected_socket2(int &fd,address_t &addr,bool bind_enabled,address_t &bind_addr,char interface_string[])
 {
 {
 	fd = socket(addr.get_type(), SOCK_DGRAM, IPPROTO_UDP);
 	fd = socket(addr.get_type(), SOCK_DGRAM, IPPROTO_UDP);
 	if (fd < 0) {
 	if (fd < 0) {
 		mylog(log_warn, "[%s]create udp_fd error\n", addr.get_str());
 		mylog(log_warn, "[%s]create udp_fd error\n", addr.get_str());
 		return -1;
 		return -1;
 	}
 	}
+
+	if (bind_enabled && ::bind(fd, (struct sockaddr*) &bind_addr.inner, bind_addr.get_len()) == -1) {
+		mylog(log_fatal,"socket bind error=%s\n", get_sock_error());
+		//perror("socket bind error");
+		myexit(1);
+	}
+
+	if (strlen(interface_string) > 0 && ::setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, interface_string, strlen(interface_string)) < 0) {
+		mylog(log_fatal,"socket interface bind error=%s\n", get_sock_error());
+		//perror("socket bind error");
+		myexit(1);
+	}
+
 	setnonblocking(fd);
 	setnonblocking(fd);
 	set_buf_size(fd, socket_buf_size);
 	set_buf_size(fd, socket_buf_size);
 
 

+ 1 - 1
common.h

@@ -451,7 +451,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_connected_socket(int &fd,u32_t ip,int port);
 
 
 int new_listen_socket2(int &fd,address_t &addr);
 int new_listen_socket2(int &fd,address_t &addr);
-int new_connected_socket2(int &fd,address_t &addr);
+int new_connected_socket2(int &fd,address_t &addr,bool bind_enabled,address_t &bind_addr,char interface_string[]);
 
 
 struct not_copy_able_t
 struct not_copy_able_t
 {
 {

+ 2 - 0
main.cpp

@@ -37,6 +37,8 @@ static void print_help()
 	printf("    --report              <number>        turn on send/recv report, and set a period for reporting, unit: s\n");
 	printf("    --report              <number>        turn on send/recv report, and set a period for reporting, unit: s\n");
 
 
 	printf("advanced options:\n");
 	printf("advanced options:\n");
+	printf("    -b,--bind             ip:port         force all output packets to go through this address. Set port to 0 to use a random one.\n");
+	printf("    --interface           <string>        force all output packets to go through this interface.\n");
 	printf("    --mode                <number>        fec-mode,available values: 0,1; mode 0(default) costs less bandwidth,no mtu problem.\n");
 	printf("    --mode                <number>        fec-mode,available values: 0,1; mode 0(default) costs less bandwidth,no mtu problem.\n");
 	printf("                                          mode 1 usually introduces less latency, but you have to care about mtu.\n");
 	printf("                                          mode 1 usually introduces less latency, but you have to care about mtu.\n");
 	printf("    --mtu                 <number>        mtu. for mode 0, the program will split packet to segment smaller than mtu value.\n");
 	printf("    --mtu                 <number>        mtu. for mode 0, the program will split packet to segment smaller than mtu value.\n");

+ 21 - 2
misc.cpp

@@ -28,7 +28,10 @@ int output_interval_max=0*1000;
 
 
 int fix_latency=0;
 int fix_latency=0;
 
 
-address_t local_addr,remote_addr;
+char interface_string[16];
+
+bool has_b=false;
+address_t local_addr,remote_addr,bind_addr;
 //u32_t local_ip_uint32,remote_ip_uint32=0;
 //u32_t local_ip_uint32,remote_ip_uint32=0;
 //char local_ip[100], remote_ip[100];
 //char local_ip[100], remote_ip[100];
 //int local_port = -1, remote_port = -1;
 //int local_port = -1, remote_port = -1;
@@ -648,12 +651,14 @@ void process_arg(int argc, char *argv[])
 		{"report", required_argument,    0, 1},
 		{"report", required_argument,    0, 1},
 		{"delay-capacity", required_argument,    0, 1},
 		{"delay-capacity", required_argument,    0, 1},
 		{"mtu", required_argument,    0, 1},
 		{"mtu", required_argument,    0, 1},
+		{"interface", required_argument,    0, 1},
 		{"mode", required_argument,   0,1},
 		{"mode", required_argument,   0,1},
 		{"timeout", required_argument,   0,1},
 		{"timeout", required_argument,   0,1},
 		{"decode-buf", required_argument,   0,1},
 		{"decode-buf", required_argument,   0,1},
 		{"queue-len", required_argument,   0,'q'},
 		{"queue-len", required_argument,   0,'q'},
 		{"fec", required_argument,   0,'f'},
 		{"fec", required_argument,   0,'f'},
 		{"jitter", required_argument,   0,'j'},
 		{"jitter", required_argument,   0,'j'},
+		{"bind", required_argument,   0,'b'},
 		{"header-overhead", required_argument,    0, 1},
 		{"header-overhead", required_argument,    0, 1},
 		//{"debug-fec", no_argument,    0, 1},
 		//{"debug-fec", no_argument,    0, 1},
 		{"debug-fec-enc", no_argument,    0, 1},
 		{"debug-fec-enc", no_argument,    0, 1},
@@ -717,7 +722,7 @@ void process_arg(int argc, char *argv[])
 
 
 
 
 	int no_l = 1, no_r = 1;
 	int no_l = 1, no_r = 1;
-	while ((opt = getopt_long(argc, argv, "l:r:hcsk:j:f:p:n:i:q:",long_options,&option_index)) != -1)
+	while ((opt = getopt_long(argc, argv, "l:r:hcsk:j:f:p:n:i:q:b",long_options,&option_index)) != -1)
 	{
 	{
 		//string opt_key;
 		//string opt_key;
 		//opt_key+=opt;
 		//opt_key+=opt;
@@ -824,6 +829,10 @@ void process_arg(int argc, char *argv[])
 			no_r = 0;
 			no_r = 0;
 			remote_addr.from_str(optarg);
 			remote_addr.from_str(optarg);
 			break;
 			break;
+		case 'b':
+			has_b = true;
+			bind_addr.from_str(optarg);
+			break;
 		case 'h':
 		case 'h':
 			break;
 			break;
 		case 1:
 		case 1:
@@ -944,6 +953,16 @@ void process_arg(int argc, char *argv[])
 					myexit(-1);
 					myexit(-1);
 				}
 				}
 			}
 			}
+			else if(strcmp(long_options[option_index].name,"interface")==0)
+			{
+				sscanf(optarg,"%s\n",interface_string);
+				mylog(log_debug,"interface=%s\n",interface_string);
+				if(strlen(interface_string)==0)
+				{
+					mylog(log_fatal,"interface_string len=0??\n");
+					myexit(-1);
+				}
+			}
 			else if(strcmp(long_options[option_index].name,"timeout")==0)
 			else if(strcmp(long_options[option_index].name,"timeout")==0)
 			{
 			{
 				sscanf(optarg,"%d",&g_fec_par.timeout);
 				sscanf(optarg,"%d",&g_fec_par.timeout);

+ 4 - 1
misc.h

@@ -39,7 +39,10 @@ extern int fix_latency;
 //extern char local_ip[100], remote_ip[100];
 //extern char local_ip[100], remote_ip[100];
 //extern int local_port, remote_port;
 //extern int local_port, remote_port;
 
 
-extern address_t local_addr,remote_addr;
+extern char interface_string[16];
+
+extern bool has_b;
+extern address_t local_addr,remote_addr,bind_addr;
 
 
 extern conn_manager_t conn_manager;
 extern conn_manager_t conn_manager;
 extern delay_manager_t delay_manager;
 extern delay_manager_t delay_manager;

+ 1 - 1
tunnel_client.cpp

@@ -295,7 +295,7 @@ int tunnel_client_event_loop()
     int & remote_fd=conn_info.remote_fd;
     int & remote_fd=conn_info.remote_fd;
     fd64_t &remote_fd64=conn_info.remote_fd64;
     fd64_t &remote_fd64=conn_info.remote_fd64;
 
 
-	assert(new_connected_socket2(remote_fd,remote_addr)==0);
+	assert(new_connected_socket2(remote_fd,remote_addr,has_b,bind_addr,interface_string)==0);
 	remote_fd64=fd_manager.create(remote_fd);
 	remote_fd64=fd_manager.create(remote_fd);
 
 
 	mylog(log_debug,"remote_fd64=%llu\n",remote_fd64);
 	mylog(log_debug,"remote_fd64=%llu\n",remote_fd64);

+ 1 - 1
tunnel_server.cpp

@@ -232,7 +232,7 @@ static void local_listen_cb(struct ev_loop *loop, struct ev_io *watcher, int rev
 			}
 			}
 
 
 			int new_udp_fd;
 			int new_udp_fd;
-			ret=new_connected_socket2(new_udp_fd,remote_addr);
+			ret=new_connected_socket2(new_udp_fd,remote_addr,has_b,bind_addr,interface_string);
 
 
 			if (ret != 0) {
 			if (ret != 0) {
 				mylog(log_warn, "[%s]new_connected_socket failed\n",addr.get_str());
 				mylog(log_warn, "[%s]new_connected_socket failed\n",addr.get_str());