From cbba36e15068339bedd35818d32838961d7e6f28 Mon Sep 17 00:00:00 2001 From: lishiao144 <1447175116@qq.com> Date: Thu, 12 Jun 2025 18:26:19 +0800 Subject: [PATCH 1/3] fix ExpStatSN handling for Data-Out PDUs --- lib/socket.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/socket.c b/lib/socket.c index 8992e65..0b45663 100644 --- a/lib/socket.c +++ b/lib/socket.c @@ -887,7 +887,10 @@ iscsi_write_to_socket(struct iscsi_context *iscsi) iscsi->outqueue_current = iscsi->outqueue; /* set exp statsn */ - iscsi_pdu_set_expstatsn(iscsi->outqueue_current, iscsi->statsn + 1); + if((iscsi->outqueue->outdata.data[0] & 0x3f) != ISCSI_PDU_DATA_OUT) + iscsi_pdu_set_expstatsn(iscsi->outqueue_current, iscsi->statsn + 1); + else + iscsi_pdu_set_expstatsn(iscsi->outqueue_current, iscsi->statsn); /* calculate header checksum */ if (iscsi->header_digest != ISCSI_HEADER_DIGEST_NONE && From a81eacc0b16552fe63ea1536cffec547c6e3db53 Mon Sep 17 00:00:00 2001 From: lishiao <1447175116@qq.com> Date: Tue, 17 Jun 2025 11:57:38 +0800 Subject: [PATCH 2/3] iscsi: compute Data Digest for out_data segments --- include/iscsi-private.h | 2 ++ lib/socket.c | 24 ++++++++++++++++++++---- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/include/iscsi-private.h b/include/iscsi-private.h index 1fce36a..69c9e3b 100644 --- a/include/iscsi-private.h +++ b/include/iscsi-private.h @@ -20,6 +20,7 @@ #include #include #include +#include #if defined(_WIN32) #include @@ -316,6 +317,7 @@ struct iscsi_pdu { uint32_t expxferlen; uint32_t calculated_data_digest; + bool outdata_digest_computed; }; struct iscsi_pdu *iscsi_allocate_pdu(struct iscsi_context *iscsi, diff --git a/lib/socket.c b/lib/socket.c index 0b45663..9100064 100644 --- a/lib/socket.c +++ b/lib/socket.c @@ -839,13 +839,12 @@ static int iscsi_pdu_update_headerdigest(struct iscsi_context *iscsi, struct isc static int iscsi_write_to_socket(struct iscsi_context *iscsi) { - ssize_t count; + ssize_t count, data_segment_len; size_t total; struct iscsi_pdu *pdu; static char padding_buf[3]; int socket_flags = 0; - bool do_data_digest = (iscsi->data_digest != ISCSI_DATA_DIGEST_NONE); - + bool do_data_digest = (iscsi->data_digest != ISCSI_DATA_DIGEST_NONE), execute_data_digest; #ifdef MSG_NOSIGNAL socket_flags |= MSG_NOSIGNAL; #elif SO_NOSIGPIPE @@ -935,6 +934,23 @@ iscsi_write_to_socket(struct iscsi_context *iscsi) return 0; } + data_segment_len = iscsi_get_pdu_data_size(pdu->outdata.data); + if (do_data_digest && + data_segment_len && + !pdu->payload_len) + execute_data_digest = true; + else + execute_data_digest = false; + + if (execute_data_digest && !pdu->outdata_digest_computed) + { + uint8_t ahslen = pdu->outdata.data[4]; + uint8_t head_len = iscsi->header_digest != ISCSI_HEADER_DIGEST_NONE ? 52 : 48; + uint32_t offset = head_len + ahslen * 4; + pdu->calculated_data_digest = crc32c_chain(pdu->calculated_data_digest, pdu->outdata.data + offset, pdu->outdata.size - offset); + pdu->outdata_digest_computed = true; + } + /* Write any iovectors that might have been passed to us */ while (pdu->payload_written < pdu->payload_len) { struct scsi_iovector* iovector_out; @@ -991,7 +1007,7 @@ iscsi_write_to_socket(struct iscsi_context *iscsi) * 1. DataDigest has been negociated, and * 2. We have actually written some data */ - if (do_data_digest && pdu->payload_written) { + if (execute_data_digest || (do_data_digest && pdu->payload_written)) { uint32_t data_digest = crc32c_chain_done(pdu->calculated_data_digest); char data_digest_buf[ISCSI_DIGEST_SIZE]; From 8ebfb20c5592e880a4ed204db64700bcf2c17468 Mon Sep 17 00:00:00 2001 From: lishiao <1447175116@qq.com> Date: Tue, 17 Jun 2025 12:24:40 +0800 Subject: [PATCH 3/3] Optimize the judgment conditions --- lib/socket.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/lib/socket.c b/lib/socket.c index 9100064..021a236 100644 --- a/lib/socket.c +++ b/lib/socket.c @@ -934,13 +934,16 @@ iscsi_write_to_socket(struct iscsi_context *iscsi) return 0; } - data_segment_len = iscsi_get_pdu_data_size(pdu->outdata.data); - if (do_data_digest && - data_segment_len && - !pdu->payload_len) - execute_data_digest = true; - else - execute_data_digest = false; + + if (do_data_digest) + { + data_segment_len = iscsi_get_pdu_data_size(pdu->outdata.data); + + if (data_segment_len && !pdu->payload_len) + execute_data_digest = true; + else + execute_data_digest = false; + } if (execute_data_digest && !pdu->outdata_digest_computed) {