paullouisageneau / libdatachannel

C/C++ WebRTC network library featuring Data Channels, Media Transport, and WebSockets
https://libdatachannel.org/
Mozilla Public License 2.0
1.82k stars 365 forks source link

Datachannel with RelayType::TurnTcp #304

Closed kkxyxy closed 3 years ago

kkxyxy commented 3 years ago

I want to use RelayType::TurnTcp to connect, but the connection fails. libnice uses the one provided by gstreamer. The connection failed on the windows system, and the connection on linux seems to be ok. I think the codes on both sides are the same, but the version of libnice may be different. I want to know whether the connection failure is caused by the system or the plug-in. Help me, thanks,

murat-dogan commented 3 years ago

In the past I used libnice version 0.1.16 & 0.1.17 in windows. Which version are you using? Is there any error message?

kkxyxy commented 3 years ago

Using 0.1.18. I found that the connection failed because the Candidate provided by the turn server was not obtained. I found that when the Log level is adjusted to LogLevel::Verbose, the Candidate provided by the turn server can be obtained, otherwise the Candidate cannot be obtained. I wonder why adjusting the log level will affect this.

paullouisageneau commented 3 years ago

Interesting! There is indeed a difference when the log level is set to verbose as libnice debug output is enabled:

IF_PLOG(plog::verbose) {
    nice_debug_enable(false); // do not output STUN debug messages
}

However, if calling this function changes the behavior, it is a bug in libnice. Could you please check this call is indeed causing the problem by setting the log level to something else, for instance warning, and removing the test around nice_debug_enabled() here:

https://github.com/paullouisageneau/libdatachannel/blob/3745ff5f7a0970131b418eaeb9d70247bbf36eda/src/icetransport.cpp#L363

kkxyxy commented 3 years ago

After removing the test around nice_debug_enabled(). The log levels are: LogLevel::Info and RTC_LOG_INFO. But I still can't get the relay address of the coturn server.

paullouisageneau commented 3 years ago

That's weird because it seems to be the only logic difference between log levels.

The log levels are: LogLevel::Info and RTC_LOG_INFO.

What do you mean? LogLevel::Info is the constant for C++ and RTC_LOG_INFO is the constant for C, you shouldn't have both.

kkxyxy commented 3 years ago

I have tried both c and c++. Will not work. Does this problem need to be changed to resolve libnice? For example, before compiling libnice, I reduced the speed of processing candidates in libnice. Is there any way to solve this problem on libdatachannel?

kkxyxy commented 3 years ago

After changing the processing of Allocate request in libnice and recompiling it, the candidate provided by the coturn server can be obtained. Now I want to use tls/dtls to communicate, but I cannot find the relevant configuration. Are there relevant configuration documents?

paullouisageneau commented 3 years ago

After changing the processing of Allocate request in libnice and recompiling it, the candidate provided by the coturn server can be obtained.

Oh great, so if I understand correctly, you solved the issue by patching libnice? If so, you should definitely report the fix upstream at https://gitlab.freedesktop.org/libnice/libnice/

Now I want to use tls/dtls to communicate, but I cannot find the relevant configuration. Are there relevant configuration documents?

It depends on what you mean by TLS/DTLS.

To open the control connection to the TURN server over TLS/TCP, you just have to specify the TURN server URL in libdatachannel as IceServer(HOSTNAME, PORT, USERNAME, PASSWORD, IceServer::RelayType::TurnTls) or IceServer("turns:USER:PASSWORD@HOST?transport=tcp") (use the second in the C API).

DTLS/UDP is not available for TURN control connection as it is out of the WebRTC standard.

The traffic between peers (relayed or not) is always over DTLS.

kkxyxy commented 3 years ago

Thanks you. I will try it.

kkxyxy commented 3 years ago

I have created and configured the certificate on the coturn server. I want to add a Self-signed SSL certificate to the client. Is it necessary? If so, how do I set it up. Just import the certificate into the system and then configure it?

paullouisageneau commented 3 years ago

I want to add a Self-signed SSL certificate to the client. Is it necessary? If so, how do I set it up. Just import the certificate into the system and then configure it?

I don't think this is necessary. TURN over TLS does not really add security (actual traffic between peers is always over DTLS), it's mostly here to make it easier to get around corporate firewalls in some scenarios. I think libnice accepts any certificate. However, you need a libnice version recent enough, until a few years ago it supported only a fake unencrypted TLS connection.

kkxyxy commented 3 years ago

I use the latest version of libnice. I have created and configured the certificate on the coturn server. I use turnutils_uclient -T -S -v -p 5349 -u u -w p -i /etc/turn_server_cert.pem -k /etc/turn_server_pkey.pem HOST to test and capture packets to confirm that it is tls communication. I want to use libdatachannel to configure the same certificate file. How do I set the path, or can it be read automatically after the certificate is installed on my system? What can I set? Thank you for your reply!

paullouisageneau commented 3 years ago

My point is that you can't verify a particular certificate, as I think libnice will accept any certificate because TURN control over TLS is not for security but for compatibility with some corporate firewalls. To get more info on what the last version of libnice supports you should reach the authors directly.

The security of the actual connection is guaranteed by the DTLS layer between peers, which use automatically generated certificates verified by the fingerprint in the signaling messages. The TURN server does not need to be trusted by peers.

kkxyxy commented 3 years ago

I've reinterpreted the webrtc Datachannel My point is that when using a Turn server, data is transmitted from the Peer to the Turn server, and then from the Turn server to another Peer. When data is transmitted from the Peer to the Turn server, I still want to use tls for transmission. I want to ask whether I need to rewrite the relevant code.

paullouisageneau commented 3 years ago

Sure, but TLS will be in addition to DTLS between the peer and the TURN server, so the data will be encrypted twice.

I think you indeed need to modify libnice to validate your certificate, I don't see functions for it in the existing API. You might also want to reach out to libnice authors about it.