Changeset View
Changeset View
Standalone View
Standalone View
usr.sbin/ctld/login.c
Show First 20 Lines • Show All 544 Lines • ▼ Show 20 Lines | if (strcmp(name, "InitiatorName") == 0) { | ||||
} | } | ||||
} else if (strcmp(name, "MaxRecvDataSegmentLength") == 0) { | } else if (strcmp(name, "MaxRecvDataSegmentLength") == 0) { | ||||
tmp = strtoul(value, NULL, 10); | tmp = strtoul(value, NULL, 10); | ||||
if (tmp <= 0) { | if (tmp <= 0) { | ||||
login_send_error(request, 0x02, 0x00); | login_send_error(request, 0x02, 0x00); | ||||
log_errx(1, "received invalid " | log_errx(1, "received invalid " | ||||
"MaxRecvDataSegmentLength"); | "MaxRecvDataSegmentLength"); | ||||
} | } | ||||
if (tmp > conn->conn_data_segment_limit) { | |||||
log_debugx("capping MaxRecvDataSegmentLength " | /* | ||||
"from %zd to %zd", tmp, conn->conn_data_segment_limit); | * MaxRecvDataSegmentLength is a direction-specific parameter. | ||||
tmp = conn->conn_data_segment_limit; | * We'll limit our _send_ to what the initiator can handle but | ||||
* our MaxRecvDataSegmentLength is not influenced by the | |||||
* initiator in any way. | |||||
*/ | |||||
if ((int)tmp > conn->conn_max_send_data_segment_length) { | |||||
log_debugx("capping max_send_data_segment_length " | |||||
"from %zd to %d", tmp, | |||||
conn->conn_max_send_data_segment_length); | |||||
tmp = conn->conn_max_send_data_segment_length; | |||||
} | } | ||||
conn->conn_max_data_segment_length = tmp; | conn->conn_max_send_data_segment_length = tmp; | ||||
keys_add_int(response_keys, name, conn->conn_data_segment_limit); | keys_add_int(response_keys, name, | ||||
conn->conn_max_recv_data_segment_length); | |||||
} else if (strcmp(name, "MaxBurstLength") == 0) { | } else if (strcmp(name, "MaxBurstLength") == 0) { | ||||
tmp = strtoul(value, NULL, 10); | tmp = strtoul(value, NULL, 10); | ||||
if (tmp <= 0) { | if (tmp <= 0) { | ||||
login_send_error(request, 0x02, 0x00); | login_send_error(request, 0x02, 0x00); | ||||
log_errx(1, "received invalid MaxBurstLength"); | log_errx(1, "received invalid MaxBurstLength"); | ||||
} | } | ||||
if (tmp > MAX_BURST_LENGTH) { | if ((int)tmp > conn->conn_max_burst_length) { | ||||
log_debugx("capping MaxBurstLength from %zd to %d", | log_debugx("capping MaxBurstLength from %zd to %d", | ||||
tmp, MAX_BURST_LENGTH); | tmp, conn->conn_max_burst_length); | ||||
tmp = MAX_BURST_LENGTH; | tmp = conn->conn_max_burst_length; | ||||
} | } | ||||
conn->conn_max_burst_length = tmp; | conn->conn_max_burst_length = tmp; | ||||
keys_add_int(response_keys, name, tmp); | keys_add_int(response_keys, name, tmp); | ||||
} else if (strcmp(name, "FirstBurstLength") == 0) { | } else if (strcmp(name, "FirstBurstLength") == 0) { | ||||
tmp = strtoul(value, NULL, 10); | tmp = strtoul(value, NULL, 10); | ||||
if (tmp <= 0) { | if (tmp <= 0) { | ||||
login_send_error(request, 0x02, 0x00); | login_send_error(request, 0x02, 0x00); | ||||
log_errx(1, "received invalid FirstBurstLength"); | log_errx(1, "received invalid FirstBurstLength"); | ||||
} | } | ||||
if (tmp > FIRST_BURST_LENGTH) { | if ((int)tmp > conn->conn_first_burst_length) { | ||||
log_debugx("capping FirstBurstLength from %zd to %d", | log_debugx("capping FirstBurstLength from %zd to %d", | ||||
tmp, FIRST_BURST_LENGTH); | tmp, conn->conn_first_burst_length); | ||||
tmp = FIRST_BURST_LENGTH; | tmp = conn->conn_first_burst_length; | ||||
} | } | ||||
conn->conn_first_burst_length = tmp; | conn->conn_first_burst_length = tmp; | ||||
keys_add_int(response_keys, name, tmp); | keys_add_int(response_keys, name, tmp); | ||||
} else if (strcmp(name, "DefaultTime2Wait") == 0) { | } else if (strcmp(name, "DefaultTime2Wait") == 0) { | ||||
keys_add(response_keys, name, value); | keys_add(response_keys, name, value); | ||||
} else if (strcmp(name, "DefaultTime2Retain") == 0) { | } else if (strcmp(name, "DefaultTime2Retain") == 0) { | ||||
keys_add(response_keys, name, "0"); | keys_add(response_keys, name, "0"); | ||||
} else if (strcmp(name, "MaxOutstandingR2T") == 0) { | } else if (strcmp(name, "MaxOutstandingR2T") == 0) { | ||||
▲ Show 20 Lines • Show All 85 Lines • ▼ Show 20 Lines | login_negotiate(struct connection *conn, struct pdu *request) | ||||
struct pdu *response; | struct pdu *response; | ||||
struct iscsi_bhs_login_response *bhslr2; | struct iscsi_bhs_login_response *bhslr2; | ||||
struct keys *request_keys, *response_keys; | struct keys *request_keys, *response_keys; | ||||
int i; | int i; | ||||
bool redirected, skipped_security; | bool redirected, skipped_security; | ||||
if (conn->conn_session_type == CONN_SESSION_TYPE_NORMAL) { | if (conn->conn_session_type == CONN_SESSION_TYPE_NORMAL) { | ||||
/* | /* | ||||
* Query the kernel for MaxDataSegmentLength it can handle. | * Query the kernel for various size limits. In case of | ||||
* In case of offload, it depends on hardware capabilities. | * offload, it depends on hardware capabilities. | ||||
*/ | */ | ||||
assert(conn->conn_target != NULL); | assert(conn->conn_target != NULL); | ||||
kernel_limits(conn->conn_portal->p_portal_group->pg_offload, | kernel_limits(conn->conn_portal->p_portal_group->pg_offload, | ||||
&conn->conn_data_segment_limit); | &conn->conn_max_recv_data_segment_length, | ||||
&conn->conn_max_send_data_segment_length, | |||||
&conn->conn_max_burst_length, | |||||
&conn->conn_first_burst_length); | |||||
/* We expect legal, usable values at this point. */ | |||||
assert(conn->conn_max_recv_data_segment_length >= 512); | |||||
assert(conn->conn_max_recv_data_segment_length < (1 << 24)); | |||||
assert(conn->conn_max_burst_length >= 512); | |||||
assert(conn->conn_max_burst_length < (1 << 24)); | |||||
assert(conn->conn_first_burst_length >= 512); | |||||
assert(conn->conn_first_burst_length < (1 << 24)); | |||||
assert(conn->conn_first_burst_length <= | |||||
conn->conn_max_burst_length); | |||||
} else { | } else { | ||||
conn->conn_data_segment_limit = MAX_DATA_SEGMENT_LENGTH; | conn->conn_max_recv_data_segment_length = | ||||
MAX_DATA_SEGMENT_LENGTH; | |||||
conn->conn_max_send_data_segment_length = | |||||
MAX_DATA_SEGMENT_LENGTH; | |||||
} | } | ||||
if (request == NULL) { | if (request == NULL) { | ||||
log_debugx("beginning operational parameter negotiation; " | log_debugx("beginning operational parameter negotiation; " | ||||
"waiting for Login PDU"); | "waiting for Login PDU"); | ||||
request = login_receive(conn, false); | request = login_receive(conn, false); | ||||
skipped_security = false; | skipped_security = false; | ||||
} else | } else | ||||
Show All 32 Lines | login_negotiate(struct connection *conn, struct pdu *request) | ||||
for (i = 0; i < KEYS_MAX; i++) { | for (i = 0; i < KEYS_MAX; i++) { | ||||
if (request_keys->keys_names[i] == NULL) | if (request_keys->keys_names[i] == NULL) | ||||
break; | break; | ||||
login_negotiate_key(request, request_keys->keys_names[i], | login_negotiate_key(request, request_keys->keys_names[i], | ||||
request_keys->keys_values[i], skipped_security, | request_keys->keys_values[i], skipped_security, | ||||
response_keys); | response_keys); | ||||
} | |||||
/* | |||||
* We'd started with usable values at our end. But a bad initiator | |||||
* could have presented a large FirstBurstLength and then a smaller | |||||
* MaxBurstLength (in that order) and because we process the key/value | |||||
* pairs in the order they are in the request we might have ended up | |||||
* with illegal values here. | |||||
bcr: s/iLLegal/illegal/ | |||||
Not Done Inline ActionsGood catch, thanks. I'll fix it in the next iteration of the patch. np: Good catch, thanks. I'll fix it in the next iteration of the patch. | |||||
*/ | |||||
if (conn->conn_session_type == CONN_SESSION_TYPE_NORMAL && | |||||
conn->conn_first_burst_length > conn->conn_max_burst_length) { | |||||
log_errx(1, "initiator sent FirstBurstLength > MaxBurstLength"); | |||||
} | } | ||||
log_debugx("operational parameter negotiation done; " | log_debugx("operational parameter negotiation done; " | ||||
"transitioning to Full Feature Phase"); | "transitioning to Full Feature Phase"); | ||||
keys_save(response_keys, response); | keys_save(response_keys, response); | ||||
pdu_send(response); | pdu_send(response); | ||||
pdu_delete(response); | pdu_delete(response); | ||||
▲ Show 20 Lines • Show All 254 Lines • Show Last 20 Lines |
s/iLLegal/illegal/