SOCKET add option to bind to connection to interface(s)
This commit is contained in:
@@ -68,6 +68,7 @@ struct iscsi_context {
|
||||
char connected_portal[MAX_STRING_SIZE+1];
|
||||
char portal[MAX_STRING_SIZE+1];
|
||||
char alias[MAX_STRING_SIZE+1];
|
||||
char bind_interfaces[MAX_STRING_SIZE+1];
|
||||
|
||||
char user[MAX_STRING_SIZE+1];
|
||||
char passwd[MAX_STRING_SIZE+1];
|
||||
@@ -102,6 +103,7 @@ struct iscsi_context {
|
||||
int login_attempts;
|
||||
int is_loggedin;
|
||||
int is_reconnecting;
|
||||
int bind_interface_cnt;
|
||||
|
||||
int chap_a;
|
||||
int chap_i;
|
||||
|
||||
@@ -1028,6 +1028,13 @@ iscsi_set_tcp_keepintvl(struct iscsi_context *iscsi, int value);
|
||||
EXTERN void
|
||||
iscsi_set_tcp_syncnt(struct iscsi_context *iscsi, int value);
|
||||
|
||||
/*
|
||||
* This function is to set the interface that outbound connections for this socket are bound to.
|
||||
* You max specify more than one interface here separated by comma.
|
||||
*/
|
||||
EXTERN void
|
||||
iscsi_set_bind_interfaces(struct iscsi_context *iscsi, char * interfaces);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -134,6 +134,10 @@ iscsi_create_context(const char *initiator_name)
|
||||
iscsi_set_tcp_syncnt(iscsi,atoi(getenv("LIBISCSI_TCP_SYNCNT")));
|
||||
}
|
||||
|
||||
if (getenv("LIBISCSI_BIND_INTERFACES") != NULL) {
|
||||
iscsi_set_bind_interfaces(iscsi,getenv("LIBISCSI_BIND_INTERFACES"));
|
||||
}
|
||||
|
||||
return iscsi;
|
||||
}
|
||||
|
||||
|
||||
@@ -79,6 +79,7 @@ iscsi_set_tcp_keepidle
|
||||
iscsi_set_tcp_keepcnt
|
||||
iscsi_set_tcp_keepintvl
|
||||
iscsi_set_tcp_syncnt
|
||||
iscsi_set_bind_interface
|
||||
iscsi_startstopunit_sync
|
||||
iscsi_startstopunit_task
|
||||
iscsi_synchronizecache10_sync
|
||||
|
||||
@@ -77,6 +77,7 @@ iscsi_set_tcp_keepidle
|
||||
iscsi_set_tcp_keepcnt
|
||||
iscsi_set_tcp_keepintvl
|
||||
iscsi_set_tcp_syncnt
|
||||
iscsi_set_bind_interface
|
||||
iscsi_startstopunit_sync
|
||||
iscsi_startstopunit_task
|
||||
iscsi_synchronizecache10_sync
|
||||
|
||||
42
lib/socket.c
42
lib/socket.c
@@ -216,6 +216,30 @@ iscsi_connect_async(struct iscsi_context *iscsi, const char *portal,
|
||||
set_tcp_syncnt(iscsi);
|
||||
}
|
||||
|
||||
#if __linux
|
||||
if (iscsi->bind_interfaces[0]) {
|
||||
char *pchr = iscsi->bind_interfaces, *pchr2;
|
||||
int iface_n = rand()%iscsi->bind_interface_cnt;
|
||||
int iface_c = 0;
|
||||
do {
|
||||
pchr2 = strchr(pchr,',');
|
||||
if (iface_c == iface_n) {
|
||||
if (pchr2) pchr2[0]=0x00;
|
||||
break;
|
||||
}
|
||||
if (pchr2) {pchr=pchr2+1;}
|
||||
} while (pchr2);
|
||||
|
||||
int res = setsockopt(iscsi->fd, SOL_SOCKET, SO_BINDTODEVICE, pchr, strlen(pchr));
|
||||
if (res < 0) {
|
||||
DPRINTF(iscsi,1,"failed to bind to interface '%s': %s",pchr,strerror(errno));
|
||||
} else {
|
||||
DPRINTF(iscsi,3,"successfully bound to interface '%s'",pchr);
|
||||
}
|
||||
if (pchr2) pchr2[0]=',';
|
||||
}
|
||||
#endif
|
||||
|
||||
if (connect(iscsi->fd, ai->ai_addr, socksize) != 0
|
||||
&& errno != EINPROGRESS) {
|
||||
iscsi_set_error(iscsi, "Connect failed with errno : "
|
||||
@@ -647,3 +671,21 @@ int iscsi_set_tcp_keepalive(struct iscsi_context *iscsi, int idle, int count, in
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void iscsi_set_bind_interfaces(struct iscsi_context *iscsi, char * interfaces)
|
||||
{
|
||||
#if __linux
|
||||
strncpy(iscsi->bind_interfaces,interfaces,MAX_STRING_SIZE);
|
||||
iscsi->bind_interface_cnt=0;
|
||||
char * pchr = interfaces;
|
||||
char * pchr2 = NULL;
|
||||
do {
|
||||
pchr2 = strchr(pchr,',');
|
||||
if (pchr2) {pchr=pchr2+1;}
|
||||
iscsi->bind_interface_cnt++;
|
||||
} while (pchr2);
|
||||
DPRINTF(iscsi,2,"will bind to one of the following %d interface(s) on next socket creation: %s",iscsi->bind_interface_cnt,interfaces);
|
||||
#else
|
||||
DPRINTF(iscsi,1,"binding to an interface is not supported on your OS");
|
||||
#endif
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user