summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMichael Brown2006-12-22 13:24:12 +0100
committerMichael Brown2006-12-22 13:24:12 +0100
commita2e3357825968e34ce4ba0adf7a6ada9d9b19b92 (patch)
treeb72afaa23e867345319b0149037de480614937ac /src
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!
Diffstat (limited to 'src')
-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 635fe2699..1b9ef9261 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 d38c20e7a..27e394cf7 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 65a820a90..ce8478563 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;