Skip to main content

iscsi_client_rs/client/
common.rs

1// SPDX-License-Identifier: AGPL-3.0-or-later
2// Copyright (C) 2012-2025 Andrei Maltsev
3
4use std::time::Duration;
5
6use anyhow::Result;
7use bytes::Bytes;
8use thiserror::Error;
9use tokio::time::timeout;
10use tokio_util::sync::CancellationToken;
11
12use crate::models::common::HEADER_LEN;
13
14#[derive(Debug, Error)]
15pub enum ClientIoError {
16    #[error("{label} cancelled")]
17    Cancelled { label: &'static str },
18    #[error("{label} timeout")]
19    Timeout { label: &'static str },
20}
21
22pub(super) fn is_timeout_error(error: &anyhow::Error) -> bool {
23    error
24        .downcast_ref::<ClientIoError>()
25        .is_some_and(|client_error| matches!(client_error, ClientIoError::Timeout { .. }))
26}
27
28pub(super) async fn io_with_timeout<F, T>(
29    label: &'static str,
30    fut: F,
31    io_timeout: Duration,
32    cancel: &CancellationToken,
33) -> Result<T>
34where
35    F: Future<Output = std::io::Result<T>>,
36{
37    tokio::select! {
38        _ = cancel.cancelled() => Err(ClientIoError::Cancelled { label }.into()),
39        res = timeout(io_timeout, fut) => {
40            match res {
41                Ok(Ok(v)) => Ok(v),
42                Ok(Err(e)) => Err(e.into()),
43                Err(_) => Err(ClientIoError::Timeout { label }.into()),
44            }
45        }
46    }
47}
48
49/// Represents a raw, unparsed iSCSI PDU (Protocol Data Unit).
50///
51/// This structure contains the raw bytes of an iSCSI PDU split into header and
52/// payload sections. The PDU format follows the iSCSI RFC specification with a
53/// fixed-size Basic Header Segment (BHS) and a variable-length payload that may
54/// contain Additional Header Segments, data, and digests.
55#[derive(Debug, Clone)]
56pub struct RawPdu {
57    /// Basic Header Segment - exactly 48 bytes according to iSCSI specification
58    ///
59    /// Contains the fundamental PDU information including opcode, flags,
60    /// lengths, sequence numbers, and other protocol-specific fields.
61    pub header: [u8; HEADER_LEN],
62    /// Variable-length payload section
63    ///
64    /// May contain Additional Header Segments (AHS), padding, Header Digest
65    /// (HD), data payload, padding, and Data Digest (DD) depending on PDU
66    /// type and configuration.
67    pub payload: Bytes,
68}