Skip to content

Potential PDU length negotiation issue: SCU sends larger PDUs than its declared maximum #712

@qarmin

Description

@qarmin

While developing custom SCP and SCU clients using dicom-rs, everything worked fine until the SCP increased its max_pdu_length from the default 16 KB to 32 KB.

After that, I started receiving warnings like this:

11:36:25.161 [WARN] [dicom_ul::pdu::reader] reader.rs:72 - Incoming pdu was too large: length 32000, maximum is 16384

When strict PDU length validation was enabled, file transfers started failing.

At first, I assumed the problem was on the SCP side, but after verifying the negotiation, it turned out the SCP correctly reported and used its PDU size.
The issue was actually in my SCU: even though its own max_pdu_length was 16 KB, it sent PDUs up to 32 KB (matching the SCP’s declared size).

Looking into the code, I found this function:

    pub fn send_pdata(
        &mut self,
        presentation_context_id: u8,
    ) -> PDataWriter<&mut std::net::TcpStream> {
        PDataWriter::new(
            &mut self.socket,
            presentation_context_id,
            self.acceptor_max_pdu_length,
        )
    }

It seems that the function uses only the SCP’s (acceptor) maximum PDU length, and ignores the SCU’s (requestor) declared limit.

Changing it to use the smaller of the two values fixed the issue in my case:

    pub fn send_pdata2(
        &mut self,
        presentation_context_id: u8,
    ) -> PDataWriter<&mut std::net::TcpStream> {
        PDataWriter::new(
            &mut self.socket,
            presentation_context_id,
            std::cmp::min(self.acceptor_max_pdu_length, self.requestor_max_pdu_length),
        )
    }

After this change, all transfers work as expected and the warnings disappeared.

Is this behavior a bug in dicom-rs, where only the acceptor’s maximum PDU length is considered?
Or is it an issue in my implementation — e.g. I might be losing some negotiation parameters or not setting them correctly during association setup?

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-toolArea: toolingC-storescuCrate: dicom-storescu

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions