diff --git a/iscsi-pdu.cpp b/iscsi-pdu.cpp index fa3bbbb..1e4b52e 100644 --- a/iscsi-pdu.cpp +++ b/iscsi-pdu.cpp @@ -252,6 +252,7 @@ bool iscsi_pdu_login_request::set_data(std::pair d auto kvs_in = data_to_text_array(data.first, data.second); uint32_t max_burst = ~0; + uint32_t max_seg_len = 8192; std::string target_name; bool discovery = false; for(auto & kv: kvs_in) { @@ -265,6 +266,8 @@ bool iscsi_pdu_login_request::set_data(std::pair d max_burst = std::min(max_burst, uint32_t(std::stoi(parts[1]))); else if (parts[0] == "FirstBurstLength") max_burst = std::min(max_burst, uint32_t(std::stoi(parts[1]))); + else if (parts[0] == "MaxRecvDataSegmentLength") + max_seg_len = uint32_t(std::stoi(parts[1])); else if (parts[0] == "InitiatorName") initiator = parts[1]; else if (parts[0] == "TargetName") @@ -277,6 +280,8 @@ bool iscsi_pdu_login_request::set_data(std::pair d ses->set_data_digest(has_CRC32C(parts[1])); } + ses->set_max_seg_len(max_seg_len); + if (max_burst < uint32_t(~0)) { DOLOG(logging::ll_debug, "iscsi_pdu_login_request::set_data", ses->get_endpoint_name(), "set max-burst to %u", max_burst); ses->set_ack_interval(max_burst); diff --git a/server.cpp b/server.cpp index 24ce512..c932de3 100644 --- a/server.cpp +++ b/server.cpp @@ -403,7 +403,7 @@ bool server::push_response(com_client *const cc, session *const ses, iscsi_pdu_b uint64_t current_lba = stream_parameters.lba; uint32_t offset = 0; - uint32_t offset_end = std::min(scsi_has, iscsi_wants); + uint32_t offset_end = std::min(std::min(scsi_has, iscsi_wants), ses->get_max_seg_len()); if (offset_end == 0) { auto *temp = new iscsi_pdu_scsi_response(ses) /* 0x21 */; diff --git a/session.h b/session.h index 5aab2a0..2d57b10 100644 --- a/session.h +++ b/session.h @@ -21,6 +21,8 @@ class session uint64_t bytes_rx { 0 }; uint64_t bytes_tx { 0 }; + uint32_t max_seg_len { 8192 }; + bool header_digest { false }; bool data_digest { false }; @@ -41,6 +43,9 @@ class session bool get_header_digest() const { return header_digest; } bool get_data_digest () const { return data_digest; } + void set_max_seg_len(const uint32_t v) { max_seg_len = v; } + uint32_t get_max_seg_len() const { return max_seg_len; } + void add_bytes_rx(const uint64_t n) { bytes_rx += n; } uint64_t get_bytes_rx() const { return bytes_rx; } void reset_bytes_rx() { bytes_rx = 0; }