Cannot immediately overwrite the peer address when we parse
authorMichael Brown <mcb30@etherboot.org>
Fri, 22 Dec 2006 12:24:12 +0000 (12:24 +0000)
committerMichael Brown <mcb30@etherboot.org>
Fri, 22 Dec 2006 12:24:12 +0000 (12:24 +0000)
TargetAddress from the login response, because we still need the old
address while we close the connection!

src/include/gpxe/iscsi.h
src/net/tcp/iscsi.c
src/tests/iscsiboot.c

index 635fe26..1b9ef92 100644 (file)
@@ -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;
 
index d38c20e..27e394c 100644 (file)
@@ -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 );
        }
 
index 65a820a..ce84785 100644 (file)
@@ -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;