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:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
27
lib/login.c
27
lib/login.c
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user