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
This commit is contained in:
Edward Tomasz Napierala 2014-09-11 20:01:57 +00:00
parent aaa995f25c
commit 0686a20b8a
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=271437

View File

@ -575,7 +575,7 @@ login_negotiate(struct connection *conn)
struct pdu *request, *response; struct pdu *request, *response;
struct keys *request_keys, *response_keys; struct keys *request_keys, *response_keys;
struct iscsi_bhs_login_response *bhslr; struct iscsi_bhs_login_response *bhslr;
int i; int i, nrequests = 0;
log_debugx("beginning operational parameter negotiation"); log_debugx("beginning operational parameter negotiation");
request = login_new_request(conn, BHSLR_STAGE_OPERATIONAL_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]); response_keys->keys_names[i], response_keys->keys_values[i]);
} }
bhslr = (struct iscsi_bhs_login_response *)response->pdu_bhs; keys_delete(response_keys);
if ((bhslr->bhslr_flags & BHSLR_FLAGS_TRANSIT) == 0) response_keys = NULL;
log_warnx("received final login response "
"without the \"T\" flag"); for (;;) {
else if (login_nsg(response) != BHSLR_STAGE_FULL_FEATURE_PHASE) 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", log_warnx("received final login response with wrong NSG 0x%x",
login_nsg(response)); login_nsg(response));
pdu_delete(response);
log_debugx("operational parameter negotiation done; " log_debugx("operational parameter negotiation done; "
"transitioning to Full Feature phase"); "transitioning to Full Feature phase");
keys_delete(response_keys);
pdu_delete(response);
} }
static void static void