SOCKET add option to bind to connection to interface(s)

This commit is contained in:
Peter Lieven
2012-11-06 14:53:55 +01:00
parent 0d8819e68f
commit 6cad82532a
6 changed files with 57 additions and 0 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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