Negotiation of MaxBurstLength, FirstBurstLength, MaxRecvDataSegmentLength

Add these settings to the iscsi context structure and initialize them to
sane valued.
When sending login commands to the target, use these values instead
of hardcoded values.
Parse when the target sends a login reply back to us and update these variables
if the target asks us to.

This allows us to detect when our defaults are too big for the target
and adjust the settings we use so we match the target.

Some targets have a very small accepted default for some settings.
During login, we will initially send these keys with our dafult values.
These targets will then respond back by refusing to transition to the next
login phase, and by telling us back what the maximum of these values should be.
In this case we have to try the login again but use the smaller values we got
from the target.
Othervise, if we try again, ignoring the value from the target, and just repeat
using our defaults the target will abort the login with a "initiator error".
This commit is contained in:
Ronnie Sahlberg
2011-01-01 09:51:16 +11:00
parent a0acddb627
commit a3328a85ef
3 changed files with 29 additions and 6 deletions

View File

@@ -82,6 +82,10 @@ struct iscsi_context {
struct iscsi_in_pdu *incoming;
struct iscsi_in_pdu *inqueue;
uint32_t max_burst_length;
uint32_t first_burst_length;
uint32_t max_recv_data_segment_length;
};
#define ISCSI_PDU_IMMEDIATE 0x40

View File

@@ -58,6 +58,10 @@ iscsi_create_context(const char *initiator_name)
iscsi->next_phase = ISCSI_PDU_LOGIN_NSG_OPNEG;
iscsi->secneg_phase = ISCSI_LOGIN_SECNEG_PHASE_OFFER_CHAP;
iscsi->max_burst_length = 262144;
iscsi->first_burst_length = 262144;
iscsi->max_recv_data_segment_length = 262144;
return iscsi;
}

View File

@@ -249,13 +249,14 @@ iscsi_login_add_maxburstlength(struct iscsi_context *iscsi, struct iscsi_pdu *pd
return 0;
}
str = (char *)"MaxBurstLength=262144";
asprintf(&str, "MaxBurstLength=%d", iscsi->max_burst_length);
if (iscsi_pdu_add_data(iscsi, pdu, (unsigned char *)str, strlen(str)+1)
!= 0) {
iscsi_set_error(iscsi, "Out-of-memory: pdu add data failed.");
free(str);
return -1;
}
free(str);
return 0;
}
@@ -269,13 +270,14 @@ iscsi_login_add_firstburstlength(struct iscsi_context *iscsi, struct iscsi_pdu *
return 0;
}
str = (char *)"FirstBurstLength=262144";
asprintf(&str, "FirstBurstLength=%d", iscsi->first_burst_length);
if (iscsi_pdu_add_data(iscsi, pdu, (unsigned char *)str, strlen(str)+1)
!= 0) {
iscsi_set_error(iscsi, "Out-of-memory: pdu add data failed.");
free(str);
return -1;
}
free(str);
return 0;
}
@@ -289,13 +291,14 @@ iscsi_login_add_maxrecvdatasegmentlength(struct iscsi_context *iscsi, struct isc
return 0;
}
str = (char *)"MaxRecvDataSegmentLength=262144";
asprintf(&str, "MaxRecvDataSegmentLength=%d", iscsi->max_recv_data_segment_length);
if (iscsi_pdu_add_data(iscsi, pdu, (unsigned char *)str, strlen(str)+1)
!= 0) {
iscsi_set_error(iscsi, "Out-of-memory: pdu add data failed.");
free(str);
return -1;
}
free(str);
return 0;
}
@@ -752,6 +755,18 @@ iscsi_process_login_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu,
}
}
if (!strncmp((char *)ptr, "FirstBurstLength=", 17)) {
iscsi->first_burst_length = strtol((char *)ptr + 17, NULL, 10);
}
if (!strncmp((char *)ptr, "MaxBurstLength=", 15)) {
iscsi->max_burst_length = strtol((char *)ptr + 15, NULL, 10);
}
if (!strncmp((char *)ptr, "MaxRecvDataSegmentLength=", 25)) {
iscsi->max_recv_data_segment_length = strtol((char *)ptr + 25, NULL, 10);
}
if (!strncmp((char *)ptr, "AuthMethod=", 11)) {
if (!strcmp((char *)ptr + 11, "CHAP")) {
iscsi->secneg_phase = ISCSI_LOGIN_SECNEG_PHASE_SELECT_ALGORITHM;