When an SCU tries to connect to a server that uses the library, and the SCU includes an Extended Negotiation sub-item in the association request, the library completely fails to respond, and the SCU eventually times out.
It can be tested like this:
- Install
pynetdicom (it can be done in a virtual environment if you don't want to pollute your Python installation)
- Open the
dicom-storescp utility included in dicom-rs, with suitable parameters.
- Use
pynetdicom's findscu --relational-query -k "0010,0010=" <host> <port> to target the above storescp. --relational-query is an example; any extended negotiation option will do.
This is the result with Wireshark, taken before the client times out:
No. Time Source Destination Protocol Length Info
6 10.798361668 10.0.0.11 10.0.128.11 DICOM 2771 A-ASSOCIATE request FINDSCU --> SERVER
Frame 6: 2771 bytes on wire (22168 bits), 2771 bytes captured (22168 bits) on interface any, id 0
Linux cooked capture v1
Internet Protocol Version 4, Src: 10.0.0.11, Dst: 10.0.128.11
Transmission Control Protocol, Src Port: 45971, Dst Port: 11111, Seq: 1, Ack: 1, Len: 2703
DICOM, A-ASSOCIATE request FINDSCU --> SERVER
PDU Type: ASSOC Request (0x01)
PDU Length: 2697
A-ASSOCIATE request FINDSCU --> SERVER
Protocol Version: 1
Called AE Title: SERVER
Calling AE Title: FINDSCU
Application Context: DICOM Application Context Name (1.2.840.10008.3.1.1.1)
Presentation Context: 1.2.840.10008.5.1.4.1.1.201.6
Item Type: Presentation Context (0x20)
Item Length: 130
Context ID: 0x01
Abstract Syntax: 1.2.840.10008.5.1.4.1.1.201.6
Transfer Syntax: Implicit VR Little Endian: Default Transfer Syntax for DICOM (1.2.840.10008.1.2)
Transfer Syntax: Explicit VR Little Endian (1.2.840.10008.1.2.1)
Transfer Syntax: Deflated Explicit VR Little Endian (1.2.840.10008.1.2.1.99)
Transfer Syntax: Explicit VR Big Endian (Retired) (1.2.840.10008.1.2.2)
<snipped the other presentation contexts for brevity>
User Info: Max PDU Length 16382, Implementation UID 1.2.826.0.1.3680043.9.3811.3.0.4, Version PYNETDICOM_304
Item Type: User Info (0x50)
Item Length: 100
Max PDU Length: 16382
Item Type: Max Length (0x51)
Item Length: 4
Max PDU Length: 16382
Implementation UID: 1.2.826.0.1.3680043.9.3811.3.0.4
Item Type: Implementation Class UID (0x52)
Item Length: 32
Implementation Class UID: 1.2.826.0.1.3680043.9.3811.3.0.4
Implementation Version: PYNETDICOM_304
Item Type: Implementation Version (0x55)
Item Length: 14
Implementation Version: PYNETDICOM_304
Ext. Neg.: Patient Root Query/Retrieve Information Model - FIND (1.2.840.10008.5.1.4.1.2.1.1)
Item Type: SOP Class Extended Negotiation (0x56)
Item Length: 34
SOP Class UID Length: 27
SOP Class UID: Patient Root Query/Retrieve Information Model - FIND (1.2.840.10008.5.1.4.1.2.1.1)
Relational-queries: 0x01
Combined Date-Time matching: 0x00
Fuzzy semantic matching: 0x00
Timezone query adjustment: 0x00
The capture ends there; there's no A-ASSOCIATE-AC or anything else. Note that at this point, there hasn't even been a chance for the server to know what kind of SCU the SCU is, so it doesn't really matter that it's a C-STORE-only SCP driven by a C-FIND-only SCU: the association never reaches the established state.
The cause is that the Service-class-application-information field in the Extended Negotiation Sub-item (see Table D.3-11 in PS3.7) is not prefixed by a length, but the library expects one in reader.rs. This causes the stream reader to de-synchronize, interpreting the Relational-queries boolean as if it was the high byte of the length field, and the Combined Date-Time matching boolean as if it was the low byte, resulting in a length of 0x0100 (256 bytes). That's more data than remains in the buffer, causing the reader to return Ok(None), which somehow causes the whole association request to be ignored.
Similarly, writer.rs writes a length field that should not be there.
I also wonder if returning Ok(None) is the right thing to do in some circumstances where something like that fails, as that would apparently cause the above behaviour in situations where the failure is serious enough to grant an abort.
When an SCU tries to connect to a server that uses the library, and the SCU includes an Extended Negotiation sub-item in the association request, the library completely fails to respond, and the SCU eventually times out.
It can be tested like this:
pynetdicom(it can be done in a virtual environment if you don't want to pollute your Python installation)dicom-storescputility included in dicom-rs, with suitable parameters.pynetdicom'sfindscu --relational-query -k "0010,0010=" <host> <port>to target the abovestorescp.--relational-queryis an example; any extended negotiation option will do.This is the result with Wireshark, taken before the client times out:
The capture ends there; there's no A-ASSOCIATE-AC or anything else. Note that at this point, there hasn't even been a chance for the server to know what kind of SCU the SCU is, so it doesn't really matter that it's a C-STORE-only SCP driven by a C-FIND-only SCU: the association never reaches the established state.
The cause is that the Service-class-application-information field in the Extended Negotiation Sub-item (see Table D.3-11 in PS3.7) is not prefixed by a length, but the library expects one in
reader.rs. This causes the stream reader to de-synchronize, interpreting the Relational-queries boolean as if it was the high byte of the length field, and the Combined Date-Time matching boolean as if it was the low byte, resulting in a length of 0x0100 (256 bytes). That's more data than remains in the buffer, causing the reader to returnOk(None), which somehow causes the whole association request to be ignored.Similarly,
writer.rswrites a length field that should not be there.I also wonder if returning Ok(None) is the right thing to do in some circumstances where something like that fails, as that would apparently cause the above behaviour in situations where the failure is serious enough to grant an abort.