Bind to interface

Allow binding to interface instead of IP with SO_BINDTODEVICE.
This commit is contained in:
llorx 2019-11-04 23:26:11 +01:00
parent 79dccfd697
commit 939b347129
7 changed files with 29 additions and 5 deletions

View File

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

View File

@ -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
{

View File

@ -37,7 +37,8 @@ static void print_help()
printf(" --report <number> 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 <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 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");

View File

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

2
misc.h
View File

@ -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;

View File

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

View File

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