Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DTLSListener gets stuck in accept when DTLS Handshake fails #614

Open
feschber opened this issue Sep 17, 2024 · 2 comments
Open

DTLSListener gets stuck in accept when DTLS Handshake fails #614

feschber opened this issue Sep 17, 2024 · 2 comments
Assignees
Labels
bug Something isn't working enhancement New feature or request

Comments

@feschber
Copy link
Contributor

I'm not sure if this is intentional or not but the problem is in essence that DTLSConn::new() has no timeout within the accept() function.
So whenever a handshake fails for various reasons, accept will not be able to return any new connection.

    async fn accept(&self) -> UtilResult<(Arc<dyn Conn + Send + Sync>, SocketAddr)> {
        let (conn, raddr) = self.parent.accept().await?;
        let dtls_conn = DTLSConn::new(conn, self.config.clone(), false, None)
            .await
            .map_err(util::Error::from_std)?;
        Ok((Arc::new(dtls_conn), raddr))
    }

This happens for example with my laptop, which has wifi and ethernet ports.
Opening a DTLSListener on this device on 0.0.0.0:4242 accepts connections via WIFI and Ethernet (two separate ips), however
the Ethernet port is preferred leading to response messages being sent only via the Ethernet port.

Connecting to the WIFI IP leads to self.parent.accept().await? returning successfully, however the DTLSConn::new() call blocks indefinitely since the Handshake fails. Therefore accept never returns, which leaves the DTLSListener in a broken state.

image

the attached image illustrates the problem: 192.168.178.189 is the wifi port on the laptop and 192.168.178.172 is the ethernet port.
The Client Hello is sent to the WIFI port but the Helly Verify Request is received from the ethernet port. The last five lines show the (unsuccessful) attempt of connecting to the Ethernet IP.

Server log with log messages for the self.parent.accept() and DTLSCon::new()` calls:


listening 0.0.0.0:4242...
type 'exit' to shutdown gracefully
parent.accept() ...
DTLSConn::new() ...
dtls/src/handshaker.rs:223 [TRACE] 13:00:54.689740 - [handshake:server] Flight 0: Preparing
dtls/src/handshaker.rs:223 [TRACE] 13:00:54.689962 - [handshake:server] Flight 0: Sending
dtls/src/handshaker.rs:223 [TRACE] 13:00:54.690035 - [handshake:server] Flight 0: Waiting
dtls/src/conn/mod.rs:1034 [TRACE] 13:00:54.690300 - Recv [handshake:server] -> ClientHello (epoch: 0, seq: 0)
dtls/src/flight/flight0.rs:84 [DEBUG] 13:00:54.690673 - [handshake:server] use cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
dtls/src/handshaker.rs:364 [TRACE] 13:00:54.693901 - [handshake:server] Flight 0 -> Flight 2
dtls/src/handshaker.rs:223 [TRACE] 13:00:54.693935 - [handshake:server] Flight 2: Preparing
dtls/src/handshaker.rs:223 [TRACE] 13:00:54.693950 - [handshake:server] Flight 2: Sending
dtls/src/conn/mod.rs:568 [TRACE] 13:00:54.694004 - Send [handshake:server] -> HelloVerifyRequest (epoch: 0, seq: 0)
dtls/src/handshaker.rs:223 [TRACE] 13:00:54.694091 - [handshake:server] Flight 2: Waiting
dtls/src/flight/flight0.rs:84 [DEBUG] 13:00:55.690131 - [handshake:server] use cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
dtls/src/handshaker.rs:364 [TRACE] 13:00:55.690358 - [handshake:server] Flight 2 -> Flight 2
dtls/src/handshaker.rs:223 [TRACE] 13:00:55.690378 - [handshake:server] Flight 2: Preparing
dtls/src/handshaker.rs:223 [TRACE] 13:00:55.690394 - [handshake:server] Flight 2: Sending
dtls/src/conn/mod.rs:568 [TRACE] 13:00:55.690501 - Send [handshake:server] -> HelloVerifyRequest (epoch: 0, seq: 0)
dtls/src/handshaker.rs:223 [TRACE] 13:00:55.690669 - [handshake:server] Flight 2: Waiting
dtls/src/flight/flight0.rs:84 [DEBUG] 13:00:56.691253 - [handshake:server] use cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
dtls/src/handshaker.rs:364 [TRACE] 13:00:56.691384 - [handshake:server] Flight 2 -> Flight 2
dtls/src/handshaker.rs:223 [TRACE] 13:00:56.691423 - [handshake:server] Flight 2: Preparing
dtls/src/handshaker.rs:223 [TRACE] 13:00:56.691453 - [handshake:server] Flight 2: Sending
dtls/src/conn/mod.rs:568 [TRACE] 13:00:56.691561 - Send [handshake:server] -> HelloVerifyRequest (epoch: 0, seq: 0)
dtls/src/handshaker.rs:223 [TRACE] 13:00:56.691733 - [handshake:server] Flight 2: Waiting
dtls/src/flight/flight0.rs:84 [DEBUG] 13:00:57.692747 - [handshake:server] use cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
dtls/src/handshaker.rs:364 [TRACE] 13:00:57.692881 - [handshake:server] Flight 2 -> Flight 2
dtls/src/handshaker.rs:223 [TRACE] 13:00:57.692909 - [handshake:server] Flight 2: Preparing
dtls/src/handshaker.rs:223 [TRACE] 13:00:57.692931 - [handshake:server] Flight 2: Sending
dtls/src/conn/mod.rs:568 [TRACE] 13:00:57.693015 - Send [handshake:server] -> HelloVerifyRequest (epoch: 0, seq: 0)
dtls/src/handshaker.rs:223 [TRACE] 13:00:57.693131 - [handshake:server] Flight 2: Waiting
dtls/src/handshaker.rs:375 [TRACE] 13:00:58.694346 - [handshake:server] Flight 2 retransmit_timer
dtls/src/handshaker.rs:223 [TRACE] 13:00:58.694577 - [handshake:server] Flight 2: Waiting
dtls/src/handshaker.rs:375 [TRACE] 13:00:59.697032 - [handshake:server] Flight 2 retransmit_timer

^C
feschber added a commit to feschber/lan-mouse that referenced this issue Sep 20, 2024
feschber added a commit to feschber/lan-mouse that referenced this issue Sep 20, 2024
feschber added a commit to feschber/lan-mouse that referenced this issue Oct 7, 2024
@jofleck
Copy link

jofleck commented Oct 9, 2024

Unfortunately we are facing the same problem. Sometimes connecting our NB-IoT devices via a CoAP Library fails due to packet loss. Afterwards no new handshakes are possible and we are forced to restart the server.

The mentioned library uses webrtc-rs for DTLS handshakes too

@feschber
Copy link
Contributor Author

feschber commented Oct 9, 2024

The DTLSListener itself is not used anywhere in the project besides the DTLS example apparently.

@rainliu could you comment on this line? What was the plan here?
The difference to the pion implementation seems to be that here the handshake is done in DTLSConn::new() whereas pion defers it until the first read / write request on the connection.

feschber added a commit to feschber/lan-mouse that referenced this issue Oct 25, 2024
feschber added a commit to feschber/lan-mouse that referenced this issue Oct 28, 2024
feschber added a commit to feschber/lan-mouse that referenced this issue Nov 5, 2024
feschber added a commit to feschber/lan-mouse that referenced this issue Nov 5, 2024
feschber added a commit to feschber/lan-mouse that referenced this issue Nov 6, 2024
feschber added a commit to feschber/lan-mouse that referenced this issue Nov 6, 2024
feschber added a commit to feschber/lan-mouse that referenced this issue Nov 7, 2024
@rainliu rainliu added bug Something isn't working enhancement New feature or request labels Dec 10, 2024
@rainliu rainliu self-assigned this Dec 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants