From 79dccfd697fe37a877de357bf9abbf3e75e89ca8 Mon Sep 17 00:00:00 2001 From: llorx Date: Mon, 4 Nov 2019 22:46:41 +0100 Subject: [PATCH 1/4] Bind to address Allow binding to address before sending UDP packets. --- common.cpp | 9 ++++++++- common.h | 2 +- main.cpp | 1 + misc.cpp | 10 ++++++++-- misc.h | 3 ++- tunnel_client.cpp | 2 +- tunnel_server.cpp | 2 +- 7 files changed, 22 insertions(+), 7 deletions(-) diff --git a/common.cpp b/common.cpp index a81fce8..8462336 100644 --- a/common.cpp +++ b/common.cpp @@ -964,13 +964,20 @@ int new_listen_socket2(int &fd,address_t &addr) 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) { fd = socket(addr.get_type(), SOCK_DGRAM, IPPROTO_UDP); if (fd < 0) { mylog(log_warn, "[%s]create udp_fd error\n", addr.get_str()); return -1; } + + if (bind_enabled && ::bind(fd, (struct sockaddr*) &bind_addr.inner, bind_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); diff --git a/common.h b/common.h index 3be975f..1772293 100644 --- a/common.h +++ b/common.h @@ -446,7 +446,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); +int new_connected_socket2(int &fd,address_t &addr,bool bind_enabled,address_t &bind_addr); struct not_copy_able_t { diff --git a/main.cpp b/main.cpp index 9212333..7164058 100644 --- a/main.cpp +++ b/main.cpp @@ -37,6 +37,7 @@ static void print_help() printf(" --report turn on send/recv report, and set a period for reporting, unit: s\n"); printf("advanced options:\n"); + printf(" -b,--bind ip:port force all output packets to go through this ip. Set port to 0 to use a random one.\n"); printf(" --mode 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(" --mtu mtu. for mode 0, the program will split packet to segment smaller than mtu value.\n"); diff --git a/misc.cpp b/misc.cpp index 634b334..5c25e0c 100644 --- a/misc.cpp +++ b/misc.cpp @@ -28,7 +28,8 @@ int output_interval_max=0*1000; int fix_latency=0; -address_t local_addr,remote_addr; +bool has_b=false; +address_t local_addr,remote_addr,bind_addr; //u32_t local_ip_uint32,remote_ip_uint32=0; //char local_ip[100], remote_ip[100]; //int local_port = -1, remote_port = -1; @@ -654,6 +655,7 @@ void process_arg(int argc, char *argv[]) {"queue-len", required_argument, 0,'q'}, {"fec", required_argument, 0,'f'}, {"jitter", required_argument, 0,'j'}, + {"bind", required_argument, 0,'b'}, {"header-overhead", required_argument, 0, 1}, //{"debug-fec", no_argument, 0, 1}, {"debug-fec-enc", no_argument, 0, 1}, @@ -717,7 +719,7 @@ void process_arg(int argc, char *argv[]) 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; //opt_key+=opt; @@ -824,6 +826,10 @@ void process_arg(int argc, char *argv[]) no_r = 0; remote_addr.from_str(optarg); break; + case 'b': + has_b = true; + bind_addr.from_str(optarg); + break; case 'h': break; case 1: diff --git a/misc.h b/misc.h index 23928bc..f7cda35 100644 --- a/misc.h +++ b/misc.h @@ -39,7 +39,8 @@ extern int fix_latency; //extern char local_ip[100], remote_ip[100]; //extern int local_port, remote_port; -extern address_t local_addr,remote_addr; +extern bool has_b; +extern address_t local_addr,remote_addr,bind_addr; extern conn_manager_t conn_manager; extern delay_manager_t delay_manager; diff --git a/tunnel_client.cpp b/tunnel_client.cpp index 0c46d61..a7458e0 100644 --- a/tunnel_client.cpp +++ b/tunnel_client.cpp @@ -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_socket2(remote_fd,remote_addr)==0); + assert(new_connected_socket2(remote_fd,remote_addr,has_b,bind_addr)==0); remote_fd64=fd_manager.create(remote_fd); mylog(log_debug,"remote_fd64=%llu\n",remote_fd64); diff --git a/tunnel_server.cpp b/tunnel_server.cpp index 6689705..9285a87 100644 --- a/tunnel_server.cpp +++ b/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; - ret=new_connected_socket2(new_udp_fd,remote_addr); + ret=new_connected_socket2(new_udp_fd,remote_addr,has_b,bind_addr); if (ret != 0) { mylog(log_warn, "[%s]new_connected_socket failed\n",addr.get_str()); From 939b347129dcbbab71264e2d9cba73f803a966ab Mon Sep 17 00:00:00 2001 From: llorx Date: Mon, 4 Nov 2019 23:26:11 +0100 Subject: [PATCH 2/4] Bind to interface Allow binding to interface instead of IP with SO_BINDTODEVICE. --- common.cpp | 10 +++++++++- common.h | 2 +- main.cpp | 3 ++- misc.cpp | 13 +++++++++++++ misc.h | 2 ++ tunnel_client.cpp | 2 +- tunnel_server.cpp | 2 +- 7 files changed, 29 insertions(+), 5 deletions(-) diff --git a/common.cpp b/common.cpp index 8462336..58e9cc1 100644 --- a/common.cpp +++ b/common.cpp @@ -964,7 +964,7 @@ int new_listen_socket2(int &fd,address_t &addr) return 0; } -int new_connected_socket2(int &fd,address_t &addr,bool bind_enabled,address_t &bind_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); if (fd < 0) { @@ -978,6 +978,14 @@ int new_connected_socket2(int &fd,address_t &addr,bool bind_enabled,address_t &b myexit(1); } + if (strlen(interface_string) > 0) { + if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, interface_string, strlen(interface_string)) < 0) { + mylog(log_fatal,"socket interface bind error\n"); + //perror("socket bind error"); + myexit(1); + } + } + setnonblocking(fd); set_buf_size(fd, socket_buf_size); diff --git a/common.h b/common.h index 1772293..7c551b7 100644 --- a/common.h +++ b/common.h @@ -446,7 +446,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,bool bind_enabled,address_t &bind_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 { diff --git a/main.cpp b/main.cpp index 7164058..1285de2 100644 --- a/main.cpp +++ b/main.cpp @@ -37,7 +37,8 @@ static void print_help() printf(" --report turn on send/recv report, and set a period for reporting, unit: s\n"); printf("advanced options:\n"); - printf(" -b,--bind ip:port force all output packets to go through this ip. Set port to 0 to use a random one.\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 force all output packets to go through this interface.\n"); printf(" --mode 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(" --mtu mtu. for mode 0, the program will split packet to segment smaller than mtu value.\n"); diff --git a/misc.cpp b/misc.cpp index 5c25e0c..f60d8da 100644 --- a/misc.cpp +++ b/misc.cpp @@ -28,6 +28,8 @@ int output_interval_max=0*1000; int fix_latency=0; +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; @@ -649,6 +651,7 @@ void process_arg(int argc, char *argv[]) {"report", required_argument, 0, 1}, {"delay-capacity", required_argument, 0, 1}, {"mtu", required_argument, 0, 1}, + {"interface", required_argument, 0, 1}, {"mode", required_argument, 0,1}, {"timeout", required_argument, 0,1}, {"decode-buf", required_argument, 0,1}, @@ -950,6 +953,16 @@ void process_arg(int argc, char *argv[]) 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) { sscanf(optarg,"%d",&g_fec_par.timeout); diff --git a/misc.h b/misc.h index f7cda35..1bfd495 100644 --- a/misc.h +++ b/misc.h @@ -39,6 +39,8 @@ extern int fix_latency; //extern char local_ip[100], remote_ip[100]; //extern int local_port, remote_port; +extern char interface_string[16]; + extern bool has_b; extern address_t local_addr,remote_addr,bind_addr; diff --git a/tunnel_client.cpp b/tunnel_client.cpp index a7458e0..93a4bde 100644 --- a/tunnel_client.cpp +++ b/tunnel_client.cpp @@ -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_socket2(remote_fd,remote_addr,has_b,bind_addr)==0); + assert(new_connected_socket2(remote_fd,remote_addr,has_b,bind_addr,interface_string)==0); remote_fd64=fd_manager.create(remote_fd); mylog(log_debug,"remote_fd64=%llu\n",remote_fd64); diff --git a/tunnel_server.cpp b/tunnel_server.cpp index 9285a87..97e674b 100644 --- a/tunnel_server.cpp +++ b/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; - ret=new_connected_socket2(new_udp_fd,remote_addr,has_b,bind_addr); + ret=new_connected_socket2(new_udp_fd,remote_addr,has_b,bind_addr,interface_string); if (ret != 0) { mylog(log_warn, "[%s]new_connected_socket failed\n",addr.get_str()); From c6b0c3e5bc00fdeb5e9a995ebbc93c25ed2090c1 Mon Sep 17 00:00:00 2001 From: llorx Date: Mon, 4 Nov 2019 23:44:22 +0100 Subject: [PATCH 3/4] Small condition merge --- common.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/common.cpp b/common.cpp index 58e9cc1..aecc815 100644 --- a/common.cpp +++ b/common.cpp @@ -978,12 +978,10 @@ int new_connected_socket2(int &fd,address_t &addr,bool bind_enabled,address_t &b myexit(1); } - if (strlen(interface_string) > 0) { - if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, interface_string, strlen(interface_string)) < 0) { - mylog(log_fatal,"socket interface bind error\n"); - //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\n"); + //perror("socket bind error"); + myexit(1); } setnonblocking(fd); From b2701990312100cb6c78bde3b80d936b8d06b80e Mon Sep 17 00:00:00 2001 From: llorx Date: Tue, 5 Nov 2019 00:04:02 +0100 Subject: [PATCH 4/4] Error reporting --- common.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/common.cpp b/common.cpp index aecc815..9411d01 100644 --- a/common.cpp +++ b/common.cpp @@ -953,7 +953,7 @@ int new_listen_socket2(int &fd,address_t &addr) int yes = 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"); myexit(1); } @@ -973,13 +973,13 @@ int new_connected_socket2(int &fd,address_t &addr,bool bind_enabled,address_t &b } if (bind_enabled && ::bind(fd, (struct sockaddr*) &bind_addr.inner, bind_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"); 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\n"); + 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); }