diff --git a/talk/p2p/base/dtlstransportchannel.cc b/talk/p2p/base/dtlstransportchannel.cc index 1b3a779b1..416e6e932 100644 --- a/talk/p2p/base/dtlstransportchannel.cc +++ b/talk/p2p/base/dtlstransportchannel.cc @@ -211,8 +211,11 @@ bool DtlsTransportChannelWrapper::SetRemoteFingerprint( talk_base::Buffer remote_fingerprint_value(digest, digest_len); - if ((dtls_state_ == STATE_OPEN) && - (remote_fingerprint_value_ == remote_fingerprint_value)) { + if (dtls_state_ != STATE_NONE && + remote_fingerprint_value_ == remote_fingerprint_value && + !digest_alg.empty()) { + // This may happen during renegotiation. + LOG_J(LS_INFO, this) << "Ignoring identical remote DTLS fingerprint"; return true; } diff --git a/talk/p2p/base/dtlstransportchannel_unittest.cc b/talk/p2p/base/dtlstransportchannel_unittest.cc index 88f143937..5727ac4cf 100644 --- a/talk/p2p/base/dtlstransportchannel_unittest.cc +++ b/talk/p2p/base/dtlstransportchannel_unittest.cc @@ -776,6 +776,25 @@ TEST_F(DtlsTransportChannelTest, TestDtlsReOfferWithDifferentSetupAttr) { TestTransfer(1, 1000, 100, true); } +// Test that re-negotiation can be started before the clients become connected +// in the first negotiation. +TEST_F(DtlsTransportChannelTest, TestRenegotiateBeforeConnect) { + MAYBE_SKIP_TEST(HaveDtlsSrtp); + SetChannelCount(2); + PrepareDtls(true, true); + PrepareDtlsSrtp(true, true); + Negotiate(); + + Renegotiate(&client1_, cricket::CONNECTIONROLE_ACTPASS, + cricket::CONNECTIONROLE_ACTIVE, NF_REOFFER); + bool rv = client1_.Connect(&client2_); + EXPECT_TRUE(rv); + EXPECT_TRUE_WAIT(client1_.writable() && client2_.writable(), 10000); + + TestTransfer(0, 1000, 100, true); + TestTransfer(1, 1000, 100, true); +} + // Test Certificates state after negotiation but before connection. TEST_F(DtlsTransportChannelTest, TestCertificatesBeforeConnect) { MAYBE_SKIP_TEST(HaveDtls);