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 connected_portal[MAX_STRING_SIZE+1];
|
||||||
char portal[MAX_STRING_SIZE+1];
|
char portal[MAX_STRING_SIZE+1];
|
||||||
char alias[MAX_STRING_SIZE+1];
|
char alias[MAX_STRING_SIZE+1];
|
||||||
|
char bind_interfaces[MAX_STRING_SIZE+1];
|
||||||
|
|
||||||
char user[MAX_STRING_SIZE+1];
|
char user[MAX_STRING_SIZE+1];
|
||||||
char passwd[MAX_STRING_SIZE+1];
|
char passwd[MAX_STRING_SIZE+1];
|
||||||
@@ -102,6 +103,7 @@ struct iscsi_context {
|
|||||||
int login_attempts;
|
int login_attempts;
|
||||||
int is_loggedin;
|
int is_loggedin;
|
||||||
int is_reconnecting;
|
int is_reconnecting;
|
||||||
|
int bind_interface_cnt;
|
||||||
|
|
||||||
int chap_a;
|
int chap_a;
|
||||||
int chap_i;
|
int chap_i;
|
||||||
|
|||||||
@@ -1028,6 +1028,13 @@ iscsi_set_tcp_keepintvl(struct iscsi_context *iscsi, int value);
|
|||||||
EXTERN void
|
EXTERN void
|
||||||
iscsi_set_tcp_syncnt(struct iscsi_context *iscsi, int value);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -134,6 +134,10 @@ iscsi_create_context(const char *initiator_name)
|
|||||||
iscsi_set_tcp_syncnt(iscsi,atoi(getenv("LIBISCSI_TCP_SYNCNT")));
|
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;
|
return iscsi;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ iscsi_set_tcp_keepidle
|
|||||||
iscsi_set_tcp_keepcnt
|
iscsi_set_tcp_keepcnt
|
||||||
iscsi_set_tcp_keepintvl
|
iscsi_set_tcp_keepintvl
|
||||||
iscsi_set_tcp_syncnt
|
iscsi_set_tcp_syncnt
|
||||||
|
iscsi_set_bind_interface
|
||||||
iscsi_startstopunit_sync
|
iscsi_startstopunit_sync
|
||||||
iscsi_startstopunit_task
|
iscsi_startstopunit_task
|
||||||
iscsi_synchronizecache10_sync
|
iscsi_synchronizecache10_sync
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ iscsi_set_tcp_keepidle
|
|||||||
iscsi_set_tcp_keepcnt
|
iscsi_set_tcp_keepcnt
|
||||||
iscsi_set_tcp_keepintvl
|
iscsi_set_tcp_keepintvl
|
||||||
iscsi_set_tcp_syncnt
|
iscsi_set_tcp_syncnt
|
||||||
|
iscsi_set_bind_interface
|
||||||
iscsi_startstopunit_sync
|
iscsi_startstopunit_sync
|
||||||
iscsi_startstopunit_task
|
iscsi_startstopunit_task
|
||||||
iscsi_synchronizecache10_sync
|
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);
|
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
|
if (connect(iscsi->fd, ai->ai_addr, socksize) != 0
|
||||||
&& errno != EINPROGRESS) {
|
&& errno != EINPROGRESS) {
|
||||||
iscsi_set_error(iscsi, "Connect failed with errno : "
|
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;
|
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