New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.
Starred by 21 users

Issue metadata

Status: Available
Owner: ----
Cc:
Components:
NextAction: ----
OS: ----
Pri: 3
Type: Bug



Sign in to add a comment

Support STUN/TURN over DTLS for WebRTC standalone

Reported by manish.j...@gmail.com, Jul 31 2014

Issue description

What steps will reproduce the problem?
1.  Create an ICE candidate with a "stuns:" or "turns:" URL with "?transport=udp"
2.  Create a PeerConnection and send SDPs as normal to begin ICE negotiation.

What is the expected result?
Each client should connect to the stun or turn server via DTLS.

What do you see instead?
No DTLS connection is made.

What version of the product are you using? On what operating system?
libjingle r6540 on Android

Please provide any additional information below.
Even though DTLS is not part of the standard (yet), it would be nice to have support for it for the native client. rfc5766-turn-server already supports DTLS. UDP is generally more suitable for VoIP.

 
Project Member

Comment 1 by juberti@webrtc.org, Aug 1 2014

Cc: jiayl@webrtc.org juberti@webrtc.org
Status: Available
I think you need 2 things:
1) Change BasicPacketSocketFactory::CreateUdpSocket to take opts, and process OPT_TLS to create a SslAdapter similar to what you are doing for TCP. You'll also need to expand CreateUdpSocket to allow the remote hostname to be passed, for TLS hostname validation.
2) Change TurnPort::PrepareAddress to pass the secure flag as a OPT_TLS option for both UDP and TCP sockets.
First I need to get DTLS working in OpenSSLAdapter.

I couldn't get it working on a non-blocking socket, because recvfrom() will return immediately with EWOULDBLOCK, and that just causes SSL_connect() to fail with SSL_ERROR_WANT_READ.

So far I've got it working by setting the socket to blocking mode just for the DTLS handshake.

Roughly:

  fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK);
  SSL_connect(ssl);
  fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK);

This blocks the thread for the duration of the DTLS handshake, which is up to 10 seconds on my setup here.

I also had to take the DTLS timeout into account. socket_ctrl() gets called with BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT and ptr as the timeout value. I set that as the receive timeout on the socket.

Roughly:

  setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(struct timeval));

This way recvfrom() doesn't return immediately but waits only long enough based on the value given by OpenSSL.

Does this seem like a reasonable approach?

There are a couple of other issues too, but first I'd like to know if this is OK.
It's not clear why DTLS would be any different than TLS in this regard, or why openssladapter would have to work differently than opensslstreamadapter (which doesn't seem to disable nonblocking).

I haven't looked at this in depth, but I think if you are messing with fds you are probably headed down the wrong path.
DTLS is different because it uses retransmission timers.

http://tools.ietf.org/html/rfc4347#section-4.2

OpenSSLStreamAdapter appears to deal with this, but I'm not sure how it works. I tried doing the same in OpenSSLAdapter, and it keeps returning SSL_ERROR_WANT_READ and OpenSSL's internal timeout keeps increasing. I'll try once more.

Meanwhile, I put log statements in OpenSSLStreamAdapter, but I don't see anything.

How can I get OpenSSLStreamAdapter to run?
I must have been doing something wrong, because it's working now.
I'd like to describe my changes so you can tell me if you see any red flags:

 1)  Added CreateClientUdpSocket() to PacketSocketFactory and BasicPacketSocketFactory

 This is similar to CreateClientTcpSocket(): it takes a remote_address, calls Connect() on the underlying socket, wraps it into an SSLAdapter instance, and calls StartSSL() on the SSLAdapter instance.

 2)  TurnPort treats UDP with server_address_.secure set (meaning DTLS) in a similar manner to TCP and TLS

 Normally TurnPort will start sending ALLOCATE immediately on a UDP socket. Unfortunately this just leads to Send() failing as the DTLS handshake is still in progress. After enough retries, ALLOCATE times out.

 The proper way to do this is to wait for the socket to "connect," just like TCP and TLS.

 3)  AsyncUdpSocket, similar to AsyncTcpSocket, now bounces the connect and close events from the underlying socket

 OpenSSLAdapter will emit a connect event on successful DTLS, but as it is wrapped in an AsyncUdpSocket object, TurnPort will never see the event and will not know when to start sending ALLOCATE.

So I think the important thing here is the introduction of a "connected" state in AsyncUdpSocket.

I also had to override SendTo() and RecvFrom() in OpenSSLAdapter.

The rest of the changes are implementation details.

I'm going to do a little more testing and then I'll submit a CL.
Thanks for the description and explanation of the issues. Let me think about this a bit to see if perhaps we want a different type of socket than AsyncUdpSocket to have this notion of connected.
I've submitted a CL now.

Comment 9 by vrk@webrtc.org, Oct 14 2014

Labels: Area-Network

Comment 10 by vrk@webrtc.org, Nov 3 2014

Labels: Mstone-41 EngTriaged
CLs still need review:
https://review.webrtc.org/21179004/
https://review.webrtc.org/19059004/

Justin to try to review this week.
Project Member

Comment 11 by pthatcher@webrtc.org, Dec 22 2014

Labels: -Mstone-41 Mstone-42
Project Member

Comment 12 by pthatcher@webrtc.org, Feb 19 2015

Labels: -Mstone-42 Mstone-44
This looks like it's not hitting m42.  Update it if I'm wrong.
Any update on when/if this will be available in Chrome (as opposed to standalone)

Chrome 45 still has same reported behaviour of using TURNS TCP mode even if transport=udp is specified.  


Project Member

Comment 14 by bemasc@webrtc.org, Dec 29 2015

Cc: bemasc@webrtc.org
Project Member

Comment 15 by tnakamura@webrtc.org, Jan 29 2016

Labels: -Mstone-44
Following up on the two CLs linked in #10:
https://review.webrtc.org/21179004/ - not submitted
https://review.webrtc.org/19059004/ - submitted as r7981

Because the first CL hasn't been submitted, I'm leaving this bug open. However, I'm also clearing the milestone label because it's been more than a year since the last meaningful update.
Project Member

Comment 16 by braveyao@webrtc.org, Apr 7 2016

Cc: braveyao@webrtc.org
 Issue 5744  has been merged into this issue.

Comment 17 Deleted

Hi , Could you please let us know when we are going to get this fix?
Project Member

Comment 19 by pthatcher@webrtc.org, Nov 8 2016

Labels: Pri-3
Any updates please?
The sample still doesn't like "stuns"
https://github.com/webrtc/samples/blob/gh-pages/src/content/peerconnection/trickle-ice/js/main.js#L40
Thanks.

Sign in to add a comment