@@ -131,14 +131,14 @@ fn test_so_listen_q_limit() {
131
131
#[ test]
132
132
fn test_so_tcp_maxseg ( ) {
133
133
use nix:: sys:: socket:: {
134
- accept, bind, connect, listen, Backlog , SockaddrIn ,
134
+ accept, bind, connect, getsockname , listen, Backlog , SockaddrIn ,
135
135
} ;
136
136
use nix:: unistd:: write;
137
137
use std:: net:: SocketAddrV4 ;
138
138
use std:: str:: FromStr ;
139
139
140
- let std_sa = SocketAddrV4 :: from_str ( "127.0.0.1:4003 " ) . unwrap ( ) ;
141
- let sock_addr = SockaddrIn :: from ( std_sa) ;
140
+ let std_sa = SocketAddrV4 :: from_str ( "127.0.0.1:0 " ) . unwrap ( ) ;
141
+ let mut sock_addr = SockaddrIn :: from ( std_sa) ;
142
142
143
143
let rsock = socket (
144
144
AddressFamily :: Inet ,
@@ -148,6 +148,7 @@ fn test_so_tcp_maxseg() {
148
148
)
149
149
. unwrap ( ) ;
150
150
bind ( rsock. as_raw_fd ( ) , & sock_addr) . unwrap ( ) ;
151
+ sock_addr = getsockname ( rsock. as_raw_fd ( ) ) . unwrap ( ) ;
151
152
listen ( & rsock, Backlog :: new ( 10 ) . unwrap ( ) ) . unwrap ( ) ;
152
153
let initial = getsockopt ( & rsock, sockopt:: TcpMaxSeg ) . unwrap ( ) ;
153
154
// Initial MSS is expected to be 536 (https://tools.ietf.org/html/rfc879#section-1) but some
@@ -305,7 +306,7 @@ fn test_get_mtu() {
305
306
use std:: net:: SocketAddrV4 ;
306
307
use std:: str:: FromStr ;
307
308
308
- let std_sa = SocketAddrV4 :: from_str ( "127.0.0.1:4001 " ) . unwrap ( ) ;
309
+ let std_sa = SocketAddrV4 :: from_str ( "127.0.0.1:0 " ) . unwrap ( ) ;
309
310
let std_sb = SocketAddrV4 :: from_str ( "127.0.0.1:4002" ) . unwrap ( ) ;
310
311
311
312
let usock = socket (
@@ -615,7 +616,7 @@ fn test_ts_clock_monotonic() {
615
616
616
617
#[ test]
617
618
#[ cfg( linux_android) ]
618
- // Disable the test under emulation because it failsi with ENOPROTOOPT in CI
619
+ // Disable the test under emulation because it fails with ENOPROTOOPT in CI
619
620
// on cross target. Lack of QEMU support is suspected.
620
621
#[ cfg_attr( qemu, ignore) ]
621
622
fn test_ip_bind_address_no_port ( ) {
@@ -735,3 +736,95 @@ fn can_get_listen_on_tcp_socket() {
735
736
let s_listening2 = getsockopt ( & s, sockopt:: AcceptConn ) . unwrap ( ) ;
736
737
assert ! ( s_listening2) ;
737
738
}
739
+
740
+ #[ cfg( target_os = "linux" ) ]
741
+ // Some architectures running under cross don't support `setsockopt(SOL_TCP, TCP_ULP)`
742
+ // because the cross image is based on Ubuntu 16.04 which predates TCP ULP support
743
+ // (it was added in kernel v4.13 released in 2017). For these architectures,
744
+ // the `setsockopt(SOL_TCP, TCP_ULP, "tls", sizeof("tls"))` call succeeds
745
+ // but the subsequent `setsockopt(SOL_TLS, TLS_TX, ...)` call fails with `ENOPROTOOPT`.
746
+ // It's as if the first `setsockopt` call enabled some other option, not `TCP_ULP`.
747
+ // For example, `strace` says:
748
+ //
749
+ // [pid 813] setsockopt(4, SOL_TCP, 0x1f /* TCP_??? */, [7564404], 4) = 0
750
+ //
751
+ // It's not clear why `setsockopt(SOL_TCP, TCP_ULP)` succeeds if the container image libc doesn't support it,
752
+ // but in any case we can't run the test on such an architecture, so skip it.
753
+ #[ cfg_attr( qemu, ignore) ]
754
+ #[ test]
755
+ fn test_ktls ( ) {
756
+ use nix:: sys:: socket:: {
757
+ accept, bind, connect, getsockname, listen, Backlog , SockaddrIn ,
758
+ } ;
759
+ use std:: net:: SocketAddrV4 ;
760
+ use std:: str:: FromStr ;
761
+
762
+ let std_sa = SocketAddrV4 :: from_str ( "127.0.0.1:0" ) . unwrap ( ) ;
763
+ let mut sock_addr = SockaddrIn :: from ( std_sa) ;
764
+
765
+ let rsock = socket (
766
+ AddressFamily :: Inet ,
767
+ SockType :: Stream ,
768
+ SockFlag :: empty ( ) ,
769
+ SockProtocol :: Tcp ,
770
+ )
771
+ . unwrap ( ) ;
772
+ bind ( rsock. as_raw_fd ( ) , & sock_addr) . unwrap ( ) ;
773
+ sock_addr = getsockname ( rsock. as_raw_fd ( ) ) . unwrap ( ) ;
774
+ listen ( & rsock, Backlog :: new ( 10 ) . unwrap ( ) ) . unwrap ( ) ;
775
+
776
+ let ssock = socket (
777
+ AddressFamily :: Inet ,
778
+ SockType :: Stream ,
779
+ SockFlag :: empty ( ) ,
780
+ SockProtocol :: Tcp ,
781
+ )
782
+ . unwrap ( ) ;
783
+ connect ( ssock. as_raw_fd ( ) , & sock_addr) . unwrap ( ) ;
784
+
785
+ let _rsess = accept ( rsock. as_raw_fd ( ) ) . unwrap ( ) ;
786
+
787
+ match setsockopt ( & ssock, sockopt:: TcpUlp :: default ( ) , b"tls" ) {
788
+ Ok ( ( ) ) => ( ) ,
789
+
790
+ // TLS ULP is not enabled, so we can't test kTLS.
791
+ Err ( nix:: Error :: ENOENT ) => skip ! ( "TLS ULP is not enabled" ) ,
792
+
793
+ Err ( err) => panic ! ( "{err:?}" ) ,
794
+ }
795
+
796
+ // In real life we would do a TLS handshake and extract the protocol version and secrets.
797
+ // For this test we just make some up.
798
+
799
+ let tx = sockopt:: TlsCryptoInfo :: Aes128Gcm ( libc:: tls12_crypto_info_aes_gcm_128 {
800
+ info : libc:: tls_crypto_info {
801
+ version : libc:: TLS_1_2_VERSION ,
802
+ cipher_type : libc:: TLS_CIPHER_AES_GCM_128 ,
803
+ } ,
804
+ iv : * b"\x04 \x05 \x06 \x07 \x08 \x09 \x0a \x0b " ,
805
+ key : * b"\x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19 \x1a \x1b \x1c \x1d \x1e \x1f " ,
806
+ salt : * b"\x00 \x01 \x02 \x03 " ,
807
+ rec_seq : * b"\x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 " ,
808
+ } ) ;
809
+ setsockopt ( & ssock, sockopt:: TcpTlsTx , & tx)
810
+ . expect ( "setting TLS_TX after enabling TLS ULP should succeed" ) ;
811
+
812
+ let rx = sockopt:: TlsCryptoInfo :: Aes128Gcm ( libc:: tls12_crypto_info_aes_gcm_128 {
813
+ info : libc:: tls_crypto_info {
814
+ version : libc:: TLS_1_2_VERSION ,
815
+ cipher_type : libc:: TLS_CIPHER_AES_GCM_128 ,
816
+ } ,
817
+ iv : * b"\xf4 \xf5 \xf6 \xf7 \xf8 \xf9 \xfa \xfb " ,
818
+ key : * b"\xe0 \xe1 \xe2 \xe3 \xe4 \xe5 \xe6 \xe7 \xe8 \xe9 \xea \xeb \xec \xed \xee \xef " ,
819
+ salt : * b"\xf0 \xf1 \xf2 \xf3 " ,
820
+ rec_seq : * b"\x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 " ,
821
+ } ) ;
822
+ match setsockopt ( & ssock, sockopt:: TcpTlsRx , & rx) {
823
+ Ok ( ( ) ) => ( ) ,
824
+ Err ( nix:: Error :: ENOPROTOOPT ) => {
825
+ // TLS_TX was added in v4.13 and TLS_RX in v4.17, so we appear to be between that range.
826
+ // It's good enough that TLS_TX worked, so let the test succeed.
827
+ }
828
+ Err ( err) => panic ! ( "{err:?}" ) ,
829
+ }
830
+ }
0 commit comments