DTLS handshake doesn't complete in Chrome but does in Firefox

1,020 views
Skip to first unread message

roxlu

unread,
Aug 5, 2014, 3:32:44 PM8/5/14
to discuss...@googlegroups.com
Hi,

I'm creating an experimental C/C++ library that implements the server side of WebRTC and I'm stuck on the DTLS
handshake part which doesn't want to complete when I try to setup a connection with Chrome 36.0.1985.125. When 
I use Firefox 32 the handshake successfully completes and I start receiving video packets.  I'm trying to find out
where what goes wrong and I have some clues but these may be totally wrong. 

First, when I run a peer connection demo and inspect the flow with Wireshark, I see a stun Binding-Request, 
Binding-Success-Response and then the DTLS ClientHello, ServerHello, Encrypted handshake, Change cipher
spec and then the video/audio packets start flowing. 

Though when I try my end point, I get a Binding-Request, Binding-Success-Message, DTLS ClientHello, ServerHello,
but then it stops and I get another ClientHello, ServerHello. This continues a couple of times. I'm wondering what 
might cause this behavior.  Differently from Firefox, I'm also receiving a lot more Binding-Requests (see attached
Wireshark file)

I've attached a Wireshark dump which shows the flow when the DTLS handshake never completes. 
Could it be caused by the ports to which I send the DTLS data? (which port should it be according to the 
Wireshark dump). 

I've also been thinking that my ICE implementation is not correct. I'm testing on a local network where my 
server is the controlled party. I'm only attaching one candidate to the server SDP. I'm handling the Binding-Request
with a Binding-Success-Response (with xor-mapped-address), that's all. Once I receive the Binding-Request and
sent the Binding-Success-Response, I stop the ICE part and assume the connections are setup correctly. Though, maybe 
I need to send a Binding-Request back to Chrome as well as it seems that the RFC example does this. But could 
this cause the handshake from not being completed? 

I've attached a Wireshark dump of the failing connection and the log of Chrome. 

Thanks
roxlu
chrome_debug.log
chrome_webrtc_dtls_doesnt_completes.pcapng

Iñaki Baz Castillo

unread,
Aug 5, 2014, 6:40:23 PM8/5/14
to discuss...@googlegroups.com
2014-08-05 21:32 GMT+02:00 roxlu <diede...@gmail.com>:
> Once I receive the Binding-Request and
> sent the Binding-Success-Response, I stop the ICE part and assume the
> connections are setup correctly.

Please don't do that. The ICE agent must be running all the time. You
may find the following issue report (which finally is not a bug)
interesting:

https://code.google.com/p/webrtc/issues/detail?id=3661


> Though, maybe I need to send a Binding-Request back to Chrome as well as it seems that the
> RFC example does this.

Not needed at all. Just the ICE Controlling agent is mandated to send
Binding-Requests.


> I've also been thinking that my ICE implementation is not correct. [...] I'm handling the Binding-Request with a Binding-Success-Response (with xor-mapped-address), that's all.

That is not enough, you MUST add the MessageIntegrity and FingerPrint
STUN attributes into the STUN success response. Otherwise the client
will ignore them and thus, will not continue sending media ("media" in
this case is the DTLS pending packets). That probably explains your
problem.

--
Iñaki Baz Castillo
<i...@aliax.net>

roxlu

unread,
Aug 6, 2014, 4:22:13 AM8/6/14
to discuss...@googlegroups.com
Hi Iñaki, thanks for your reply!

Op woensdag 6 augustus 2014 00:40:23 UTC+2 schreef Iñaki Baz Castillo:
2014-08-05 21:32 GMT+02:00 roxlu <diede...@gmail.com>:
>  Once I receive the Binding-Request and
> sent the Binding-Success-Response, I stop the ICE part and assume the
> connections are setup correctly.

Please don't do that. The ICE agent must be running all the time. You
may find the following issue report (which finally is not a bug)
interesting:

https://code.google.com/p/webrtc/issues/detail?id=3661
 
Thanks for clearing that up. I've tested both flows: one where I keep parsing
the incoming stun messages and another one where I stop when I received the 
Binding-Request and answered with a Binding-Success-Response. I'll continue
parsing messages, thanks.

I'm going to look into that bug report. 



> Though, maybe I need to send a Binding-Request back to Chrome as well as it seems that the
> RFC example does this.

Not needed at all. Just the ICE Controlling agent is mandated to send
Binding-Requests.
 
Ah, thanks!  


> I've also been thinking that my ICE implementation is not correct. [...] I'm handling the Binding-Request with a Binding-Success-Response (with xor-mapped-address), that's all.

That is not enough, you MUST add the MessageIntegrity and FingerPrint
STUN attributes into the STUN success response. Otherwise the client
will ignore them and thus, will not continue sending media ("media" in
this case is the DTLS pending packets). That probably explains your
problem.

Sorry, I should have mentioned that more explicitly, but I am adding the MessageIntegrity and Fingerprint
values which are valid as far as I can see. Or I would expect the logs of Chrome to show an error when the
MessageIntegrity is wrong. I've validated my implementation of the MessageIntegrity and Fingerprint using the 

Below I've pasted the messages from my application and Chrome. I've only added one candidate in the server's SDP (192.168.0.194:59976)
to handle only one stream (video only).  After I send the Binding-Success-Response (line 104) I receive the Client Hello and response with a 
Server Hello. Though right after that I receive another multiple Binding-Requests.  Why isn't Chrome replying to my Server Hello?

No.     Time           Source                Destination           Protocol Length Info
    103 11.840171000   192.168.0.194         192.168.0.194         STUN     140    Binding Request user: 5PN2qmWqBl:QhvTdFxcmmHzkzq1
    104 11.879924000   192.168.0.194         192.168.0.194         STUN     96     Binding Success Response XOR-MAPPED-ADDRESS: 192.168.0.194:59976
    105 11.880698000   192.168.0.194         192.168.0.194         DTLSv1.0 151    Client Hello
    106 11.889024000   192.168.0.193         192.168.0.194         STUN     140    Binding Request user: 5PN2qmWqBl:QhvTdFxcmmHzkzq1
    107 11.893398000   192.168.0.194         192.168.0.194         DTLSv1.0 1151   Server Hello, Certificate, Certificate Request, Server Hello Done
    115 12.369285000   192.168.0.194         192.168.0.194         STUN     140    Binding Request user: 5PN2qmWqBl:QhvTdFxcmmHzkzq1
    122 12.849502000   192.168.0.193         192.168.0.194         STUN     140    Binding Request user: 5PN2qmWqBl:QhvTdFxcmmHzkzq1
    123 12.881314000   192.168.0.194         192.168.0.194         DTLSv1.0 151    Client Hello
    124 12.972398000   192.168.0.194         192.168.0.194         DTLSv1.0 1151   Server Hello, Certificate, Certificate Request, Server Hello Done
    127 13.330504000   192.168.0.194         192.168.0.194         STUN     140    Binding Request user: 5PN2qmWqBl:QhvTdFxcmmHzkzq1
    131 13.810993000   192.168.0.193         192.168.0.194         STUN     140    Binding Request user: 5PN2qmWqBl:QhvTdFxcmmHzkzq1
    133 14.291746000   192.168.0.194         192.168.0.194         STUN     140    Binding Request user: 5PN2qmWqBl:QhvTdFxcmmHzkzq1
    140 14.773401000   192.168.0.193         192.168.0.194         STUN     140    Binding Request user: 5PN2qmWqBl:QhvTdFxcmmHzkzq1
    143 14.882329000   192.168.0.194         192.168.0.194         DTLSv1.0 151    Client Hello
    146 15.255111000   192.168.0.194         192.168.0.194         STUN     140    Binding Request user: 5PN2qmWqBl:QhvTdFxcmmHzkzq1
    183 15.738816000   192.168.0.193         192.168.0.194         STUN     140    Binding Request user: 5PN2qmWqBl:QhvTdFxcmmHzkzq1
    220 16.218648000   192.168.0.194         192.168.0.194         STUN     140    Binding Request user: 5PN2qmWqBl:QhvTdFxcmmHzkzq1
    240 16.699564000   192.168.0.193         192.168.0.194         STUN     140    Binding Request user: 5PN2qmWqBl:QhvTdFxcmmHzkzq1
    255 17.183782000   192.168.0.194         192.168.0.194         STUN     140    Binding Request user: 5PN2qmWqBl:QhvTdFxcmmHzkzq1
    260 17.664089000   192.168.0.193         192.168.0.194         STUN     140    Binding Request user: 5PN2qmWqBl:QhvTdFxcmmHzkzq1
    265 18.294117000   192.168.0.194         192.168.0.194         STUN     140    Binding Request user: 5PN2qmWqBl:QhvTdFxcmmHzkzq1
    274 18.625845000   192.168.0.193         192.168.0.194         STUN     140    Binding Request user: 5PN2qmWqBl:QhvTdFxcmmHzkzq1
    275 18.883438000   192.168.0.194         192.168.0.194         DTLSv1.0 151    Client Hello
    276 18.911041000   192.168.0.194         192.168.0.194         DTLSv1.0 1151   Server Hello, Certificate, Certificate Request, Server Hello Done
    277 19.108078000   192.168.0.194         192.168.0.194         STUN     140    Binding Request user: 5PN2qmWqBl:QhvTdFxcmmHzkzq1
    280 19.588449000   192.168.0.193         192.168.0.194         STUN     140    Binding Request user: 5PN2qmWqBl:QhvTdFxcmmHzk


Thanks
roxlu

Iñaki Baz Castillo

unread,
Aug 6, 2014, 7:43:13 AM8/6/14
to discuss...@googlegroups.com
2014-08-06 10:22 GMT+02:00 roxlu <diede...@gmail.com>:
> Below I've pasted the messages from my application and Chrome. I've only
> added one candidate in the server's SDP (192.168.0.194:59976)
> to handle only one stream (video only). After I send the
> Binding-Success-Response (line 104) I receive the Client Hello and response
> with a
> Server Hello. Though right after that I receive another multiple
> Binding-Requests. Why isn't Chrome replying to my Server Hello?

OK, from my experiments I'm sure that Chrome would not send the DTLS
HelloClient if the STUN response is not valid, so I'm sure that the
problem is in your DTLS response.

To test your DTLS server side implementation, use this code (I use it
and it works in the same scenario in which Chrome and Firefox work):

https://gist.github.com/ibc/8b9627f3c76dfb8d5446 (read also the
comment after the code).

Of course, you need to "hack" your server to allow processing DTLS
even without a previous ICE request/response.

roxlu

unread,
Aug 6, 2014, 4:38:09 PM8/6/14
to discuss...@googlegroups.com
Just found the issue. It seems it wasn't in my STUN/ICE/DTLS code after all, but in 
the SDP and not sure if this is a bug in Chrome.  Whenever I do not add the a=ice-lite
session attribute Chrome does not complete the DTLS handshake. It sends the ClientHello,
but doesn't seem to handle the ServerHello (only using video as media). 

When my server users this SDP, it works in Chrome:

v=0
o=- 5372151867866539221 2 IN IP4 127.0.0.1
s=-
c=IN IP4 192.168.0.193
t=0 0
a=ice-lite
m=video 1 RTP/SAVPF 100
a=rtpmap:100 VP8/90000
a=mid:video
a=recvonly
a=rtcp-mux
a=ice-ufrag:5PN2qmWqBl
a=ice-pwd:Q9wQj99nsQzldVI5ZuGXbEWRK5RhRXdC
a=candidate:4252876256 1 udp 2122260223 192.168.0.193 59976 typ host
a=candidate:4252876256 2 udp 2122260223 192.168.0.193 59976 typ host
a=fingerprint:sha-256 3C:A8:D2:9B:34:9C:F1:94:F5:FD:AD:61:1D:79:21:4D:75:32:23:BB:ED:2E:85:02:79:C9:80:1D:A8:BB:A9:8A
a=setup:passive

And when I remove the a=ice-lite, like below it doesn't work anymore.

v=0
o=- 5372151867866539221 2 IN IP4 127.0.0.1
s=-
c=IN IP4 192.168.0.193
t=0 0
m=video 1 RTP/SAVPF 100
a=rtpmap:100 VP8/90000
a=mid:video
a=recvonly
a=rtcp-mux
a=ice-ufrag:5PN2qmWqBl
a=ice-pwd:Q9wQj99nsQzldVI5ZuGXbEWRK5RhRXdC
a=candidate:4252876256 1 udp 2122260223 192.168.0.193 59976 typ host
a=candidate:4252876256 2 udp 2122260223 192.168.0.193 59976 typ host
a=fingerprint:sha-256 3C:A8:D2:9B:34:9C:F1:94:F5:FD:AD:61:1D:79:21:4D:75:32:23:BB:ED:2E:85:02:79:C9:80:1D:A8:BB:A9:8A
a=setup:passive

In both cases I'm responding with the same Binding-Success-Response after receiving a Binding-Request.

Anyone who knows why?

roxlu

Justin Uberti

unread,
Aug 6, 2014, 5:08:25 PM8/6/14
to discuss-webrtc
If you are not doing ICE Lite, you must do a connectivity check (STUN exchange) before sending media.



--

---
You received this message because you are subscribed to the Google Groups "discuss-webrtc" group.
To unsubscribe from this group and stop receiving emails from it, send an email to discuss-webrt...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

roxlu

unread,
Aug 6, 2014, 5:12:38 PM8/6/14
to discuss...@googlegroups.com
Hi Justin, thanks for your reply. I had a similar thought (as posted earlier) I was wondering I had to send a 
Binding-Request back to chrome. Is this part 14 in the flow (and the rest) from the example in RFC 5245, here

And is this also necessary for recvonly (as what my server SDP is using).

Thanks
roxlu

Op woensdag 6 augustus 2014 23:08:25 UTC+2 schreef Justin Uberti:

Justin Uberti

unread,
Aug 6, 2014, 5:44:44 PM8/6/14
to discuss-webrtc
yes, exactly - part 14.

recvonly has no effect on the ICE processing.


--
Reply all
Reply to author
Forward
0 new messages