1- use dicom_dictionary_std:: uids:: VERIFICATION ;
2- use dicom_ul:: ClientAssociationOptions ;
1+ use dicom_dictionary_std:: uids:: { self , VERIFICATION } ;
2+ use dicom_ul:: { ClientAssociationOptions , Pdu , ServerAssociationOptions , association :: SyncAssociation } ;
33use rstest:: rstest;
44use std:: time:: Instant ;
55#[ cfg( feature = "sync-tls" ) ]
66use dicom_ul:: association:: Association ;
77#[ cfg( feature = "sync-tls" ) ]
88use std:: sync:: Arc ;
99
10+ type Result < T , E = Box < dyn std:: error:: Error + Send + Sync + ' static > > = std:: result:: Result < T , E > ;
11+
1012#[ cfg( feature = "sync-tls" ) ]
11- fn ensure_test_certs ( ) -> Result < ( ) , Box < dyn std :: error :: Error > > {
13+ fn ensure_test_certs ( ) -> Result < ( ) > {
1214 use rustls_cert_gen:: CertificateBuilder ;
1315 use rcgen:: SanType ;
1416 use std:: { convert:: TryInto , net:: IpAddr , str:: FromStr , path:: PathBuf } ;
@@ -68,7 +70,7 @@ const TIMEOUT_TOLERANCE: u64 = 25;
6870
6971#[ cfg( feature = "sync-tls" ) ]
7072/// Create a test TLS server configuration
71- fn create_test_config ( ) -> Result < ( Arc < rustls:: ServerConfig > , Arc < rustls:: ClientConfig > ) , Box < dyn std :: error :: Error > > {
73+ fn create_test_config ( ) -> Result < ( Arc < rustls:: ServerConfig > , Arc < rustls:: ClientConfig > ) > {
7274 use rustls:: { ClientConfig , RootCertStore , ServerConfig , pki_types:: { CertificateDer , PrivateKeyDer , pem:: PemObject } , server:: WebPkiClientVerifier } ;
7375 use std:: path:: PathBuf ;
7476 ensure_test_certs ( ) ?;
@@ -188,7 +190,7 @@ fn test_tls_connection_sync() {
188190
189191#[ cfg( feature = "async-tls" ) ]
190192#[ tokio:: test( flavor = "multi_thread" ) ]
191- async fn test_tls_connection_async ( ) -> Result < ( ) , Box < dyn std :: error :: Error + Send + Sync + ' static > > {
193+ async fn test_tls_connection_async ( ) -> Result < ( ) > {
192194 use dicom_ul:: { ServerAssociationOptions , association:: AsyncAssociation } ;
193195 // set up crypto provider -- Just use the default provider which is aws_lc_rs
194196 let _ = rustls:: crypto:: aws_lc_rs:: default_provider ( ) . install_default ( ) ;
@@ -205,7 +207,7 @@ async fn test_tls_connection_async() -> Result<(), Box<dyn std::error::Error + S
205207 . tls_config ( ( * server_tls_config) . clone ( ) ) ;
206208
207209 // Spawn server task
208- let server_handle = tokio:: spawn ( async move {
210+ let server_handle: tokio :: task :: JoinHandle < Result < _ > > = tokio:: spawn ( async move {
209211 let ( stream, _) = listener. accept ( ) . await . map_err ( |e| Box :: new ( e) as Box < dyn std:: error:: Error + Send + Sync + ' static > ) ?;
210212 let mut association = server_options. establish_tls_async ( stream) . await . map_err ( |e| Box :: new ( e) as Box < dyn std:: error:: Error + Send + Sync + ' static > ) ?;
211213
@@ -219,7 +221,7 @@ async fn test_tls_connection_async() -> Result<(), Box<dyn std::error::Error + S
219221 association. send ( & dicom_ul:: Pdu :: ReleaseRP ) . await . map_err ( |e| Box :: new ( e) as Box < dyn std:: error:: Error + Send + Sync + ' static > ) ?;
220222 }
221223
222- Ok :: < ( ) , Box < dyn std :: error :: Error + Send + Sync + ' static > > ( ( ) )
224+ Result :: Ok ( ( ) )
223225 } ) ;
224226
225227 // Give server time to start
@@ -297,3 +299,44 @@ async fn test_slow_association_async(#[case] timeout: u64) {
297299 timeout
298300 ) ;
299301}
302+
303+ /// Associations can be established
304+ /// when identifying remote nodes by their application entity address.
305+ #[ test]
306+ fn test_establish_via_ae_address ( ) -> Result < ( ) > {
307+ let listener = std:: net:: TcpListener :: bind ( "localhost:0" ) ?;
308+ let addr = listener. local_addr ( ) ?;
309+ let scp = ServerAssociationOptions :: new ( )
310+ . accept_called_ae_title ( )
311+ . ae_title ( "THIS-SCP" )
312+ . with_abstract_syntax ( VERIFICATION ) ;
313+
314+ // Spawn server thread
315+ let h = std:: thread:: spawn ( move || -> Result < _ > {
316+ let ( stream, _addr) = listener. accept ( ) ?;
317+ let mut association = scp. establish ( stream) ?;
318+
319+ // handle one release request
320+ let pdu = association. receive ( ) ?;
321+ assert_eq ! ( pdu, Pdu :: ReleaseRQ ) ;
322+ association. send ( & Pdu :: ReleaseRP ) ?;
323+
324+ Ok ( association)
325+ } ) ;
326+
327+ // use bound socket address to create AE address
328+ let ae_address = format ! ( "THIS-SCP@{addr}" ) ;
329+
330+ // create SCU and establish association
331+ let association = ClientAssociationOptions :: new ( )
332+ . calling_ae_title ( "THIS-SCU" )
333+ . with_presentation_context ( uids:: VERIFICATION , vec ! [ uids:: IMPLICIT_VR_LITTLE_ENDIAN , uids:: EXPLICIT_VR_LITTLE_ENDIAN ] )
334+ . establish_with ( & ae_address) ?;
335+
336+ // just release and finish
337+ association. release ( ) ?;
338+
339+ let _ = h. join ( ) ;
340+
341+ Ok ( ( ) )
342+ }
0 commit comments