summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Brown2006-12-22 13:24:12 +0100
committerMichael Brown2006-12-22 13:24:12 +0100
commita2e3357825968e34ce4ba0adf7a6ada9d9b19b92 (patch)
treeb72afaa23e867345319b0149037de480614937ac
parentFix prototype of random() and move to stdlib.h (diff)
downloadipxe-a2e3357825968e34ce4ba0adf7a6ada9d9b19b92.tar.gz
ipxe-a2e3357825968e34ce4ba0adf7a6ada9d9b19b92.tar.xz
ipxe-a2e3357825968e34ce4ba0adf7a6ada9d9b19b92.zip
Cannot immediately overwrite the peer address when we parse
TargetAddress from the login response, because we still need the old address while we close the connection!
-rw-r--r--src/include/gpxe/iscsi.h10
-rw-r--r--src/net/tcp/iscsi.c11
-rw-r--r--src/tests/iscsiboot.c8
3 files changed, 20 insertions, 9 deletions
diff --git a/src/include/gpxe/iscsi.h b/src/include/gpxe/iscsi.h
index 635fe269..1b9ef926 100644
--- a/src/include/gpxe/iscsi.h
+++ b/src/include/gpxe/iscsi.h
@@ -504,9 +504,15 @@ struct iscsi_session {
int retry_count;
/** Initiator IQN */
- const char *initiator;
+ const char *initiator_iqn;
+ /** Target address
+ *
+ * Kept separate from the TCP connection structure because we
+ * may need to handle login redirection.
+ */
+ struct sockaddr_tcpip target;
/** Target IQN */
- const char *target;
+ const char *target_iqn;
/** Logical Unit Number (LUN) */
uint64_t lun;
diff --git a/src/net/tcp/iscsi.c b/src/net/tcp/iscsi.c
index d38c20e7..27e394cf 100644
--- a/src/net/tcp/iscsi.c
+++ b/src/net/tcp/iscsi.c
@@ -395,8 +395,8 @@ static int iscsi_build_login_request_strings ( struct iscsi_session *iscsi,
"TargetName=%s%c"
"SessionType=Normal%c"
"AuthMethod=CHAP,None%c",
- iscsi->initiator, 0, iscsi->target, 0,
- 0, 0 );
+ iscsi->initiator_iqn, 0,
+ iscsi->target_iqn, 0, 0, 0 );
}
if ( iscsi->status & ISCSI_STATUS_STRINGS_CHAP_ALGORITHM ) {
@@ -497,7 +497,7 @@ static void iscsi_tx_login_request ( struct iscsi_session *iscsi,
static void iscsi_handle_targetaddress_value ( struct iscsi_session *iscsi,
const char *value ) {
struct in_addr address;
- struct sockaddr_in *sin = ( struct sockaddr_in * ) &iscsi->tcp.peer;
+ struct sockaddr_in *sin = ( struct sockaddr_in * ) &iscsi->target;
if ( inet_aton ( value, &address ) == 0 ) {
DBG ( "iSCSI %p received invalid TargetAddress \"%s\"\n",
@@ -1121,6 +1121,9 @@ static void iscsi_closed ( struct tcp_connection *conn, int status ) {
/* Retry connection if within the retry limit, otherwise fail */
if ( ++iscsi->retry_count <= ISCSI_MAX_RETRIES ) {
DBG ( "iSCSI %p retrying connection\n", iscsi );
+ /* Re-copy address to handle redirection */
+ memcpy ( &iscsi->tcp.peer, &iscsi->target,
+ sizeof ( iscsi->tcp.peer ) );
tcp_connect ( conn );
} else {
printf ( "iSCSI %p retry count exceeded\n", iscsi );
@@ -1190,6 +1193,8 @@ struct async_operation * iscsi_issue ( struct iscsi_session *iscsi,
} else {
/* Session not open: initiate login */
iscsi->tcp.tcp_op = &iscsi_tcp_operations;
+ memcpy ( &iscsi->tcp.peer, &iscsi->target,
+ sizeof ( iscsi->tcp.peer ) );
tcp_connect ( &iscsi->tcp );
}
diff --git a/src/tests/iscsiboot.c b/src/tests/iscsiboot.c
index 65a820a9..ce847856 100644
--- a/src/tests/iscsiboot.c
+++ b/src/tests/iscsiboot.c
@@ -21,10 +21,10 @@ int test_iscsiboot ( const char *initiator_iqn,
int rc;
memset ( &test_iscsidev, 0, sizeof ( test_iscsidev ) );
- memcpy ( &test_iscsidev.iscsi.tcp.peer, target,
- sizeof ( test_iscsidev.iscsi.tcp.peer ) );
- test_iscsidev.iscsi.initiator = initiator_iqn;
- test_iscsidev.iscsi.target = target_iqn;
+ memcpy ( &test_iscsidev.iscsi.target, target,
+ sizeof ( test_iscsidev.iscsi.target ) );
+ test_iscsidev.iscsi.initiator_iqn = initiator_iqn;
+ test_iscsidev.iscsi.target_iqn = target_iqn;
test_iscsidev.iscsi.lun = lun;
test_iscsidev.iscsi.username = username;
test_iscsidev.iscsi.password = password;