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

Accepting non-TLS WebSocket makes TspListener hang? #237

Open
tkntkn opened this issue Oct 7, 2022 · 1 comment
Open

Accepting non-TLS WebSocket makes TspListener hang? #237

tkntkn opened this issue Oct 7, 2022 · 1 comment

Comments

@tkntkn
Copy link

tkntkn commented Oct 7, 2022

Description

While trying to write a secured WebSocket server using tungstenite-rs, I found this strange behavior of native-tls (it does not require tungstenite to reproduce). When a client incorrectly requests a non-TLS WebSocket handshake to the server, TlsAcceptor::accept(&self, stream) goes into an infinite loop and never returns unless the client explicitly closes the connection. Even worse, it makes the server (= TcpListener) stop handling other (TLS secured) WebSocket requests. I'm new to Rust so I couldn't determine why accepting one wrong request in the separated thread makes TcpListener in the main thread stop working.

Environment

  • native-tls = "0.2.10"
  • rustc 1.63.0 (4b91a6ea7 2022-08-08)
  • cargo 1.63.0 (fd9c4297c 2022-07-01)
  • Windows 11
  • Microsoft Edge

How to reproduce

  1. Run the below program

    use std::sync::Arc;
    use std::thread;
    use std::{fs::File, net::TcpListener};
    use std::io::{Read};
    
    use native_tls::{TlsAcceptor, Identity};
    
    fn main() {
        let mut file = File::open("./cert/server.pfx").unwrap();
        let mut identity = vec![];
        file.read_to_end(&mut identity).unwrap();
        let identity = Identity::from_pkcs12(&identity, "").unwrap();
        let acceptor = TlsAcceptor::new(identity).unwrap();
        let acceptor = Arc::new(acceptor);
    
        let server = TcpListener::bind("127.0.0.1:8080").unwrap();
        let t = thread::spawn(move || {
            for stream in server.incoming() {
                println!("incoming!");
                let acceptor = acceptor.clone();
                thread::spawn(move || {
                    acceptor.accept(stream.unwrap()).unwrap();
                    println!("accepted!");
                });
            }
        });
    
        t.join().unwrap();
    }
  2. Send a non-TLS WebSocket request from a browser

    > var ws = new WebSocket('ws://127.0.0.1:8080');
    
  3. The server prints "incoming!" but not "accepted!"

  4. Send another (but this time using TLS) WebSocketSecure request from a browser

    > var ws = new WebSocket('wss://127.0.0.1:8080');
    
  5. The server prints neither "incoming!" nor "accepted!", which means TcpListener itself is hanging?

@mybreeze2018
Copy link

yes . me to

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants