Author: trasz
Date: Thu Sep 11 20:01:57 2014
New Revision: 271437
URL: http://svnweb.freebsd.org/changeset/base/271437

Log:
  Don't blindly assume the target agreed to transition to Full Feature Phase;
  if we got a Login Response PDU without the "T" bit set, try again with
  an empty request.  This fixes interoperability with COMSTAR.
  
  Reviewed by:  mav@
  Tested by:    mav@
  MFC after:    1 week

Modified:
  head/usr.sbin/iscsid/login.c

Modified: head/usr.sbin/iscsid/login.c
==============================================================================
--- head/usr.sbin/iscsid/login.c        Thu Sep 11 19:54:30 2014        
(r271436)
+++ head/usr.sbin/iscsid/login.c        Thu Sep 11 20:01:57 2014        
(r271437)
@@ -575,7 +575,7 @@ login_negotiate(struct connection *conn)
        struct pdu *request, *response;
        struct keys *request_keys, *response_keys;
        struct iscsi_bhs_login_response *bhslr;
-       int i;
+       int i, nrequests = 0;
 
        log_debugx("beginning operational parameter negotiation");
        request = login_new_request(conn, BHSLR_STAGE_OPERATIONAL_NEGOTIATION);
@@ -629,19 +629,41 @@ login_negotiate(struct connection *conn)
                    response_keys->keys_names[i], 
response_keys->keys_values[i]);
        }
 
-       bhslr = (struct iscsi_bhs_login_response *)response->pdu_bhs;
-       if ((bhslr->bhslr_flags & BHSLR_FLAGS_TRANSIT) == 0)
-               log_warnx("received final login response "
-                   "without the \"T\" flag");
-       else if (login_nsg(response) != BHSLR_STAGE_FULL_FEATURE_PHASE)
+       keys_delete(response_keys);
+       response_keys = NULL;
+
+       for (;;) {
+               bhslr = (struct iscsi_bhs_login_response *)response->pdu_bhs;
+               if ((bhslr->bhslr_flags & BHSLR_FLAGS_TRANSIT) != 0)
+                       break;
+
+               nrequests++;
+               if (nrequests > 5) {
+                       log_warnx("received login response "
+                           "without the \"T\" flag too many times; giving up");
+                       break;
+               }
+
+               log_debugx("received login response "
+                   "without the \"T\" flag; sending another request");
+
+               pdu_delete(response);
+
+               request = login_new_request(conn,
+                   BHSLR_STAGE_OPERATIONAL_NEGOTIATION);
+               pdu_send(request);
+               pdu_delete(request);
+
+               response = login_receive(conn);
+       }
+
+       if (login_nsg(response) != BHSLR_STAGE_FULL_FEATURE_PHASE)
                log_warnx("received final login response with wrong NSG 0x%x",
                    login_nsg(response));
+       pdu_delete(response);
 
        log_debugx("operational parameter negotiation done; "
            "transitioning to Full Feature phase");
-
-       keys_delete(response_keys);
-       pdu_delete(response);
 }
 
 static void
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "[email protected]"

Reply via email to