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

Udp connection not close when using TURN (reopen #195) #232

Closed
shiqifeng2000 opened this issue Aug 8, 2022 · 2 comments · Fixed by #330
Closed

Udp connection not close when using TURN (reopen #195) #232

shiqifeng2000 opened this issue Aug 8, 2022 · 2 comments · Fixed by #330
Labels
bug Something isn't working subcrate:turn For issues specific to the TURN crate

Comments

@shiqifeng2000
Copy link
Contributor

shiqifeng2000 commented Aug 8, 2022

hi

This is a bug similar to bug 195, the out come is udp port not closing.

It seems when I try to deploy a TURN server, the candidate would use the related_address to communicate with the TURN server. But when the peer connection is dropping and all candidate are dropped, it seems the related_address is still trying to listen to the opened port.

Everytime I opened a new peerconnection, a new port shall be unreleased. It is a sure to come issue, could you please take a look into it?

Screen Shot 2022-08-08 at 10 37 09 AM

[Rolling] 2022-08-08T10:36:37.769958+08:00 - INFO - 1339329739 - Ice candidate Some(
    RTCIceCandidate {
        stats_id: "candidate:7nc6VphUbPm3n0qLtV5oRUfCXOr/auPt",
        foundation: "2842371988",
        priority: 16777215,
        address: "0.0.0.0",
        protocol: Udp,
        port: 55933,
        typ: Relay,
        component: 1,
        related_address: "0.0.0.0",
        related_port: 54677,
        tcp_type: "unspecified",
    },
)
@shiqifeng2000
Copy link
Contributor Author

shiqifeng2000 commented Aug 8, 2022

UPDATE:
It seems I have target the problem, you see, in the submodule TURN crate,
when agent_gather is starting to gather relay candidate by invoking gather_candidates_relay
a TURN client is created to listen to the remote turn socket.

In the listen method of the TURN client, I found a tokio task spawn to listen to that socket, without safe guarding

tokio::spawn(async move {
            let mut buf = vec![0u8; MAX_DATA_BUFFER_SIZE];
            loop {
                //TODO: gracefully exit loop
                let (n, from) = match conn.recv_from(&mut buf).await {
                    Ok((n, from)) => (n, from),
                    Err(err) => {
                        log::debug!("exiting read loop: {}", err);
                        break;
                    }
                };

                log::debug!("received {} bytes of udp from {}", n, from);

                if let Err(err) = ClientInternal::handle_inbound(
                    &read_ch_tx,
                    &buf[..n],
                    from,
                    &stun_serv_str,
                    &tr_map,
                    &binding_mgr,
                )
                .await
                {
                    log::debug!("exiting read loop: {}", err);
                    break;
                }
            }
        });

So, similarly, I play the timeout strategy,

tokio::spawn(async move {
            let mut buf = vec![0u8; MAX_DATA_BUFFER_SIZE];
            loop {
                //TODO: gracefully exit loop
                let timeout = tokio::time::sleep(std::time::Duration::from_secs(10));
                tokio::pin!(timeout);
                let (n, from) = tokio::select! {
                    _ = timeout.as_mut() =>{
                        log::debug!("timeout reading, exiting read loop");
                        break;
                    }
                    result = conn.recv_from(&mut buf)=> {
                        match result {
                            Ok((n, from)) => (n, from),
                            Err(err) => {
                                log::debug!("exiting read loop: {}", err);
                                break;
                            }
                        }
                    }
                };

and it seems the conn got dropped and port released, I am not sure if a Strong/Weak Atomic count could work this time

@k0nserv k0nserv added subcrate:turn For issues specific to the TURN crate bug Something isn't working labels Aug 23, 2022
@clia
Copy link
Contributor

clia commented Oct 15, 2022

Is this issue webrtc-rs/turn#13 the same cause of this one?

melekes pushed a commit that referenced this issue Nov 22, 2022
On our servers, we found that after the TURN service runs for a long time, there will be a large number of UDP ports that are not released.

We found that the reason is that after the `packet_handler` task is started, if the client no longer uses the UDP connection, `relay_socket.recv_from` will never return. So we add a 10-second timeout here to check whether the allocation has been dropped every 10 seconds.

Fixes #232
Refs webrtc-rs/turn#13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working subcrate:turn For issues specific to the TURN crate
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants