diff --git a/include/iscsi-private.h b/include/iscsi-private.h index c16d672..5655d9e 100644 --- a/include/iscsi-private.h +++ b/include/iscsi-private.h @@ -103,7 +103,7 @@ struct iscsi_context { int login_attempts; int is_loggedin; int is_reconnecting; - int bind_interface_cnt; + int bind_interfaces_cnt; int chap_a; int chap_i; @@ -304,6 +304,8 @@ struct scsi_task *iscsi_scsi_get_task_from_pdu(struct iscsi_pdu *pdu); void iscsi_set_noautoreconnect(struct iscsi_context *iscsi, int state); +void iscsi_decrement_iface_rr(); + #ifdef __cplusplus } #endif diff --git a/lib/connect.c b/lib/connect.c index 32b3316..76000be 100644 --- a/lib/connect.c +++ b/lib/connect.c @@ -91,6 +91,7 @@ iscsi_login_cb(struct iscsi_context *iscsi, int status, void *command_data _U_, if (status == SCSI_STATUS_REDIRECT && iscsi->target_address[0]) { iscsi_disconnect(iscsi); + if (iscsi->bind_interfaces[0]) iscsi_decrement_iface_rr(); if (iscsi_connect_async(iscsi, iscsi->target_address, iscsi_connect_cb, iscsi->connect_data) != 0) { iscsi_free(iscsi, ct); return; @@ -238,6 +239,9 @@ try_again: strncpy(iscsi->portal,old_iscsi->portal,MAX_STRING_SIZE); + strncpy(iscsi->bind_interfaces,old_iscsi->bind_interfaces,MAX_STRING_SIZE); + iscsi->bind_interfaces_cnt = old_iscsi->bind_interfaces_cnt; + iscsi->debug = old_iscsi->debug; iscsi->tcp_user_timeout = old_iscsi->tcp_user_timeout; diff --git a/lib/socket.c b/lib/socket.c index 7d1f014..a611d8e 100644 --- a/lib/socket.c +++ b/lib/socket.c @@ -46,6 +46,12 @@ #include "iscsi-private.h" #include "slist.h" +static uint32_t iface_rr = 0; + +void iscsi_decrement_iface_rr() { + iface_rr--; +} + static void set_nonblocking(int fd) { #if defined(WIN32) @@ -219,7 +225,7 @@ iscsi_connect_async(struct iscsi_context *iscsi, const char *portal, #if __linux if (iscsi->bind_interfaces[0]) { char *pchr = iscsi->bind_interfaces, *pchr2; - int iface_n = rand()%iscsi->bind_interface_cnt; + int iface_n = iface_rr++%iscsi->bind_interfaces_cnt; int iface_c = 0; do { pchr2 = strchr(pchr,','); @@ -677,15 +683,16 @@ 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; + iscsi->bind_interfaces_cnt=0; char * pchr = interfaces; char * pchr2 = NULL; do { pchr2 = strchr(pchr,','); if (pchr2) {pchr=pchr2+1;} - iscsi->bind_interface_cnt++; + iscsi->bind_interfaces_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); + DPRINTF(iscsi,2,"will bind to one of the following %d interface(s) on next socket creation: %s",iscsi->bind_interfaces_cnt,interfaces); + if (!iface_rr) iface_rr=rand()%iscsi->bind_interfaces_cnt+1; #else DPRINTF(iscsi,1,"binding to an interface is not supported on your OS"); #endif