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());