Update libjingle 62472237->62550414

git-svn-id: http://webrtc.googlecode.com/svn/trunk@5640 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
henrike@webrtc.org 2014-03-04 19:54:57 +00:00
parent 7bd4a27502
commit b90991dade
19 changed files with 344 additions and 174 deletions

View File

@ -49,7 +49,8 @@ class AudioTrack : public MediaStreamTrack<AudioTrackInterface> {
virtual void AddSink(AudioTrackSinkInterface* sink) OVERRIDE {}
virtual void RemoveSink(AudioTrackSinkInterface* sink) OVERRIDE {}
virtual bool GetSignalLevel(int* level) OVERRIDE { return false; }
virtual AudioProcessorInterface* GetAudioProcessor() OVERRIDE { return NULL; }
virtual talk_base::scoped_refptr<AudioProcessorInterface> GetAudioProcessor()
OVERRIDE { return NULL; }
virtual cricket::AudioRenderer* GetRenderer() OVERRIDE {
return NULL;
}

View File

@ -220,7 +220,8 @@ class AudioTrackInterface : public MediaStreamTrackInterface {
// Get the audio processor used by the audio track. Return NULL if the track
// does not have any processor.
// TODO(xians): Make the interface pure virtual.
virtual AudioProcessorInterface* GetAudioProcessor() { return NULL; }
virtual talk_base::scoped_refptr<AudioProcessorInterface>
GetAudioProcessor() { return NULL; }
// Get a pointer to the audio renderer of this AudioTrack.
// The pointer is valid for the lifetime of this AudioTrack.

View File

@ -45,7 +45,8 @@ BEGIN_PROXY_MAP(AudioTrack)
PROXY_METHOD1(void, AddSink, AudioTrackSinkInterface*)
PROXY_METHOD1(void, RemoveSink, AudioTrackSinkInterface*)
PROXY_METHOD1(bool, GetSignalLevel, int*)
PROXY_METHOD0(AudioProcessorInterface*, GetAudioProcessor)
PROXY_METHOD0(talk_base::scoped_refptr<AudioProcessorInterface>,
GetAudioProcessor)
PROXY_METHOD0(cricket::AudioRenderer*, GetRenderer)
PROXY_METHOD1(bool, set_enabled, bool)

View File

@ -1095,32 +1095,6 @@ TEST_F(JsepPeerConnectionP2PTestClient, LocalP2PTestDtlsRenegotiate) {
receiving_client()->Negotiate();
}
// This test sets up a call between an endpoint configured to use either SDES or
// DTLS (the offerer) and just SDES (the answerer). As a result, SDES is used
// instead of DTLS.
TEST_F(JsepPeerConnectionP2PTestClient, LocalP2PTestOfferDtlsToSdes) {
MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
FakeConstraints setup_constraints;
setup_constraints.AddMandatory(MediaConstraintsInterface::kEnableDtlsSrtp,
true);
ASSERT_TRUE(CreateTestClients(&setup_constraints, NULL));
LocalP2PTest();
VerifyRenderedSize(640, 480);
}
// This test sets up a call between an endpoint configured to use SDES
// (the offerer) and either SDES or DTLS (the answerer). As a result, SDES is
// used instead of DTLS.
TEST_F(JsepPeerConnectionP2PTestClient, LocalP2PTestOfferSdesToDtls) {
MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
FakeConstraints setup_constraints;
setup_constraints.AddMandatory(MediaConstraintsInterface::kEnableDtlsSrtp,
true);
ASSERT_TRUE(CreateTestClients(NULL, &setup_constraints));
LocalP2PTest();
VerifyRenderedSize(640, 480);
}
// This test sets up a call between two endpoints that are configured to use
// DTLS key agreement. The offerer don't support SDES. As a result, DTLS is
// negotiated and used for transport.

View File

@ -134,8 +134,9 @@ class FakeLocalAudioTrack
*level = 1;
return true;
}
virtual webrtc::AudioProcessorInterface* GetAudioProcessor() OVERRIDE {
return processor_.get();
virtual talk_base::scoped_refptr<webrtc::AudioProcessorInterface>
GetAudioProcessor() OVERRIDE {
return processor_;
}
private:

View File

@ -64,11 +64,12 @@ const char kMlineMismatch[] =
"Offer and answer descriptions m-lines are not matching. Rejecting answer.";
const char kPushDownTDFailed[] =
"Failed to push down transport description:";
const char kSdpWithoutCrypto[] = "Called with a SDP without crypto enabled.";
const char kSdpWithoutDtlsFingerprint[] =
"Called with SDP without DTLS fingerprint.";
const char kSdpWithoutSdesCrypto[] =
"Called with SDP without SDES crypto.";
const char kSdpWithoutIceUfragPwd[] =
"Called with a SDP without ice-ufrag and ice-pwd.";
const char kSdpWithoutSdesAndDtlsDisabled[] =
"Called with a SDP without SDES crypto and DTLS disabled locally.";
"Called with SDP without ice-ufrag and ice-pwd.";
const char kSessionError[] = "Session error code: ";
const char kSessionErrorDesc[] = "Session error description: ";
@ -112,17 +113,18 @@ static bool VerifyCrypto(const SessionDescription* desc,
*error = kInvalidSdp;
return false;
}
if (media->cryptos().empty()) {
if (dtls_enabled) {
if (!tinfo->description.identity_fingerprint) {
// Crypto must be supplied.
LOG(LS_WARNING) << "Session description must have SDES or DTLS-SRTP.";
*error = kSdpWithoutCrypto;
LOG(LS_WARNING) <<
"Session description must have DTLS fingerprint if DTLS enabled.";
*error = kSdpWithoutDtlsFingerprint;
return false;
}
if (!dtls_enabled) {
} else {
if (media->cryptos().empty()) {
LOG(LS_WARNING) <<
"Session description must have SDES when DTLS disabled.";
*error = kSdpWithoutSdesAndDtlsDisabled;
*error = kSdpWithoutSdesCrypto;
return false;
}
}
@ -160,9 +162,8 @@ static bool VerifyIceUfragPwdPresent(const SessionDescription* desc) {
// current security policy, to ensure a failure occurs if there is an error
// in crypto negotiation.
// Called when processing the local session description.
static void UpdateSessionDescriptionSecurePolicy(
cricket::SecureMediaPolicy secure_policy,
SessionDescription* sdesc) {
static void UpdateSessionDescriptionSecurePolicy(cricket::CryptoType type,
SessionDescription* sdesc) {
if (!sdesc) {
return;
}
@ -175,7 +176,7 @@ static void UpdateSessionDescriptionSecurePolicy(
MediaContentDescription* mdesc =
static_cast<MediaContentDescription*> (iter->description);
if (mdesc) {
mdesc->set_crypto_required(secure_policy == cricket::SEC_REQUIRED);
mdesc->set_crypto_required(type);
}
}
}
@ -465,14 +466,18 @@ bool WebRtcSession::Initialize(
// can be null.
bool value;
// Enable DTLS by default if |dtls_identity_service| is valid.
dtls_enabled_ = (dtls_identity_service != NULL);
// |constraints| can override the default |dtls_enabled_| value.
if (FindConstraint(
constraints,
MediaConstraintsInterface::kEnableDtlsSrtp,
&value, NULL)) {
dtls_enabled_ = value;
if (options.disable_encryption) {
dtls_enabled_ = false;
} else {
// Enable DTLS by default if |dtls_identity_service| is valid.
dtls_enabled_ = (dtls_identity_service != NULL);
// |constraints| can override the default |dtls_enabled_| value.
if (FindConstraint(
constraints,
MediaConstraintsInterface::kEnableDtlsSrtp,
&value, NULL)) {
dtls_enabled_ = value;
}
}
// Enable creation of RTP data channels if the kEnableRtpDataChannels is set.
@ -526,7 +531,7 @@ bool WebRtcSession::Initialize(
this, &WebRtcSession::OnIdentityReady);
if (options.disable_encryption) {
webrtc_session_desc_factory_->SetSecure(cricket::SEC_DISABLED);
webrtc_session_desc_factory_->SetSdesPolicy(cricket::SEC_DISABLED);
}
return true;
@ -554,13 +559,12 @@ bool WebRtcSession::StartCandidatesAllocation() {
return true;
}
void WebRtcSession::SetSecurePolicy(
cricket::SecureMediaPolicy secure_policy) {
webrtc_session_desc_factory_->SetSecure(secure_policy);
void WebRtcSession::SetSdesPolicy(cricket::SecurePolicy secure_policy) {
webrtc_session_desc_factory_->SetSdesPolicy(secure_policy);
}
cricket::SecureMediaPolicy WebRtcSession::SecurePolicy() const {
return webrtc_session_desc_factory_->Secure();
cricket::SecurePolicy WebRtcSession::SdesPolicy() const {
return webrtc_session_desc_factory_->SdesPolicy();
}
bool WebRtcSession::GetSslRole(talk_base::SSLRole* role) {
@ -609,10 +613,13 @@ bool WebRtcSession::SetLocalDescription(SessionDescriptionInterface* desc,
set_initiator(true);
}
cricket::SecureMediaPolicy secure_policy =
webrtc_session_desc_factory_->Secure();
cricket::SecurePolicy sdes_policy =
webrtc_session_desc_factory_->SdesPolicy();
cricket::CryptoType crypto_required = dtls_enabled_ ?
cricket::CT_DTLS : (sdes_policy == cricket::SEC_REQUIRED ?
cricket::CT_SDES : cricket::CT_NONE);
// Update the MediaContentDescription crypto settings as per the policy set.
UpdateSessionDescriptionSecurePolicy(secure_policy, desc->description());
UpdateSessionDescriptionSecurePolicy(crypto_required, desc->description());
set_local_description(desc->description()->Copy());
local_desc_.reset(desc_temp.release());
@ -1512,7 +1519,8 @@ bool WebRtcSession::ValidateSessionDescription(
// Verify crypto settings.
std::string crypto_error;
if (webrtc_session_desc_factory_->Secure() == cricket::SEC_REQUIRED &&
if ((webrtc_session_desc_factory_->SdesPolicy() == cricket::SEC_REQUIRED ||
dtls_enabled_) &&
!VerifyCrypto(sdesc->description(), dtls_enabled_, &crypto_error)) {
return BadSdp(source, type, crypto_error, err_desc);
}

View File

@ -63,7 +63,8 @@ extern const char kInvalidCandidates[];
extern const char kInvalidSdp[];
extern const char kMlineMismatch[];
extern const char kPushDownTDFailed[];
extern const char kSdpWithoutCrypto[];
extern const char kSdpWithoutDtlsFingerprint[];
extern const char kSdpWithoutSdesCrypto[];
extern const char kSdpWithoutIceUfragPwd[];
extern const char kSdpWithoutSdesAndDtlsDisabled[];
extern const char kSessionError[];
@ -128,8 +129,8 @@ class WebRtcSession : public cricket::BaseSession,
return data_channel_.get();
}
void SetSecurePolicy(cricket::SecureMediaPolicy secure_policy);
cricket::SecureMediaPolicy SecurePolicy() const;
void SetSdesPolicy(cricket::SecurePolicy secure_policy);
cricket::SecurePolicy SdesPolicy() const;
// Get current ssl role from transport.
bool GetSslRole(talk_base::SSLRole* role);

View File

@ -91,9 +91,9 @@ using webrtc::kCreateChannelFailed;
using webrtc::kInvalidSdp;
using webrtc::kMlineMismatch;
using webrtc::kPushDownTDFailed;
using webrtc::kSdpWithoutCrypto;
using webrtc::kSdpWithoutIceUfragPwd;
using webrtc::kSdpWithoutSdesAndDtlsDisabled;
using webrtc::kSdpWithoutDtlsFingerprint;
using webrtc::kSdpWithoutSdesCrypto;
using webrtc::kSessionError;
using webrtc::kSessionErrorDesc;
@ -458,7 +458,7 @@ class WebRtcSessionTest : public testing::Test {
// Set the internal fake description factories to do DTLS-SRTP.
void SetFactoryDtlsSrtp() {
desc_factory_->set_secure(cricket::SEC_ENABLED);
desc_factory_->set_secure(cricket::SEC_DISABLED);
std::string identity_name = "WebRTC" +
talk_base::ToString(talk_base::CreateRandomId());
identity_.reset(talk_base::SSLIdentity::Generate(identity_name));
@ -484,8 +484,8 @@ class WebRtcSessionTest : public testing::Test {
CreateRemoteOffer(options, cricket::SEC_DISABLED));
ASSERT_TRUE(offer != NULL);
VerifyNoCryptoParams(offer->description(), false);
SetRemoteDescriptionOfferExpectError(
"Called with a SDP without crypto enabled", offer);
SetRemoteDescriptionOfferExpectError(kSdpWithoutSdesCrypto,
offer);
const webrtc::SessionDescriptionInterface* answer = CreateAnswer(NULL);
// Answer should be NULL as no crypto params in offer.
ASSERT_TRUE(answer == NULL);
@ -645,6 +645,28 @@ class WebRtcSessionTest : public testing::Test {
EXPECT_TRUE(*nocrypto_answer != NULL);
}
void CreateDtlsOfferAndNonDtlsAnswer(SessionDescriptionInterface** offer,
SessionDescriptionInterface** nodtls_answer) {
cricket::MediaSessionOptions options;
options.has_video = true;
options.bundle_enabled = true;
talk_base::scoped_ptr<SessionDescriptionInterface> temp_offer(
CreateRemoteOffer(options, cricket::SEC_ENABLED));
*nodtls_answer =
CreateRemoteAnswer(temp_offer.get(), options, cricket::SEC_ENABLED);
EXPECT_TRUE(*nodtls_answer != NULL);
VerifyFingerprintStatus((*nodtls_answer)->description(), false);
VerifyCryptoParams((*nodtls_answer)->description());
SetFactoryDtlsSrtp();
*offer = CreateRemoteOffer(options, cricket::SEC_ENABLED);
ASSERT_TRUE(*offer != NULL);
VerifyFingerprintStatus((*offer)->description(), true);
VerifyCryptoParams((*offer)->description());
}
JsepSessionDescription* CreateRemoteOfferWithVersion(
cricket::MediaSessionOptions options,
cricket::SecurePolicy secure_policy,
@ -673,8 +695,9 @@ class WebRtcSessionTest : public testing::Test {
kSessionVersion, NULL);
}
JsepSessionDescription* CreateRemoteOffer(
cricket::MediaSessionOptions options, cricket::SecurePolicy policy) {
return CreateRemoteOfferWithVersion(options, policy, kSessionVersion, NULL);
cricket::MediaSessionOptions options, cricket::SecurePolicy sdes_policy) {
return CreateRemoteOfferWithVersion(
options, sdes_policy, kSessionVersion, NULL);
}
JsepSessionDescription* CreateRemoteOffer(
cricket::MediaSessionOptions options,
@ -938,11 +961,11 @@ class WebRtcSessionTest : public testing::Test {
void VerifyMultipleAsyncCreateDescription(
bool success, CreateSessionDescriptionRequest::Type type) {
InitWithDtls(!success);
SetFactoryDtlsSrtp();
if (type == CreateSessionDescriptionRequest::kAnswer) {
cricket::MediaSessionOptions options;
scoped_ptr<JsepSessionDescription> offer(
CreateRemoteOffer(options, cricket::SEC_REQUIRED));
CreateRemoteOffer(options, cricket::SEC_DISABLED));
ASSERT_TRUE(offer.get() != NULL);
SetRemoteDescriptionWithoutError(offer.release());
}
@ -997,18 +1020,16 @@ class WebRtcSessionTest : public testing::Test {
cricket::FakeVoiceMediaChannel* voice_channel_;
};
TEST_F(WebRtcSessionTest, TestInitialize) {
Init(NULL);
}
TEST_F(WebRtcSessionTest, TestInitializeWithDtls) {
InitWithDtls();
// SDES is disabled when DTLS is on.
EXPECT_EQ(cricket::SEC_DISABLED, session_->SdesPolicy());
}
// Verifies that WebRtcSession uses SEC_REQUIRED by default.
TEST_F(WebRtcSessionTest, TestDefaultSetSecurePolicy) {
TEST_F(WebRtcSessionTest, TestInitializeWithoutDtls) {
Init(NULL);
EXPECT_EQ(cricket::SEC_REQUIRED, session_->SecurePolicy());
// SDES is required if DTLS is off.
EXPECT_EQ(cricket::SEC_REQUIRED, session_->SdesPolicy());
}
TEST_F(WebRtcSessionTest, TestSessionCandidates) {
@ -1063,7 +1084,7 @@ TEST_F(WebRtcSessionTest, SetSdpFailedOnInvalidSdp) {
// Test creating offers and receive answers and make sure the
// media engine creates the expected send and receive streams.
TEST_F(WebRtcSessionTest, TestCreateOfferReceiveAnswer) {
TEST_F(WebRtcSessionTest, TestCreateSdesOfferReceiveSdesAnswer) {
Init(NULL);
mediastream_signaling_.SendAudioVideoStream1();
SessionDescriptionInterface* offer = CreateOffer(NULL);
@ -1118,14 +1139,16 @@ TEST_F(WebRtcSessionTest, TestCreateOfferReceiveAnswer) {
// Test receiving offers and creating answers and make sure the
// media engine creates the expected send and receive streams.
TEST_F(WebRtcSessionTest, TestReceiveOfferCreateAnswer) {
TEST_F(WebRtcSessionTest, TestReceiveSdesOfferCreateSdesAnswer) {
Init(NULL);
mediastream_signaling_.SendAudioVideoStream2();
SessionDescriptionInterface* offer = CreateOffer(NULL);
VerifyCryptoParams(offer->description());
SetRemoteDescriptionWithoutError(offer);
mediastream_signaling_.SendAudioVideoStream1();
SessionDescriptionInterface* answer = CreateAnswer(NULL);
VerifyCryptoParams(answer->description());
SetLocalDescriptionWithoutError(answer);
const std::string session_id_orig = answer->session_id();
@ -1186,9 +1209,39 @@ TEST_F(WebRtcSessionTest, SetLocalSdpFailedOnCreateChannel) {
SetLocalDescriptionOfferExpectError(kCreateChannelFailed, offer);
}
// Test we will return fail when apply an offer that doesn't have
// crypto enabled.
TEST_F(WebRtcSessionTest, SetNonCryptoOffer) {
//
// Tests for creating/setting SDP under different SDES/DTLS polices:
//
// --DTLS off and SDES on
// TestCreateSdesOfferReceiveSdesAnswer/TestReceiveSdesOfferCreateSdesAnswer:
// set local/remote offer/answer with crypto --> success
// TestSetNonSdesOfferWhenSdesOn: set local/remote offer without crypto --->
// failure
// TestSetLocalNonSdesAnswerWhenSdesOn: set local answer without crypto -->
// failure
// TestSetRemoteNonSdesAnswerWhenSdesOn: set remote answer without crypto -->
// failure
//
// --DTLS on and SDES off
// TestCreateDtlsOfferReceiveDtlsAnswer/TestReceiveDtlsOfferCreateDtlsAnswer:
// set local/remote offer/answer with DTLS fingerprint --> success
// TestReceiveNonDtlsOfferWhenDtlsOn: set local/remote offer without DTLS
// fingerprint --> failure
// TestSetLocalNonDtlsAnswerWhenDtlsOn: set local answer without fingerprint
// --> failure
// TestSetRemoteNonDtlsAnswerWhenDtlsOn: set remote answer without fingerprint
// --> failure
//
// --Encryption disabled: DTLS off and SDES off
// TestCreateOfferReceiveAnswerWithoutEncryption: set local offer and remote
// answer without SDES or DTLS --> success
// TestCreateAnswerReceiveOfferWithoutEncryption: set remote offer and local
// answer without SDES or DTLS --> success
//
// Test that we return a failure when applying a remote/local offer that doesn't
// have cryptos enabled when DTLS is off.
TEST_F(WebRtcSessionTest, TestSetNonSdesOfferWhenSdesOn) {
Init(NULL);
cricket::MediaSessionOptions options;
options.has_video = true;
@ -1198,15 +1251,15 @@ TEST_F(WebRtcSessionTest, SetNonCryptoOffer) {
VerifyNoCryptoParams(offer->description(), false);
// SetRemoteDescription and SetLocalDescription will take the ownership of
// the offer.
SetRemoteDescriptionOfferExpectError(kSdpWithoutCrypto, offer);
SetRemoteDescriptionOfferExpectError(kSdpWithoutSdesCrypto, offer);
offer = CreateRemoteOffer(options, cricket::SEC_DISABLED);
ASSERT_TRUE(offer != NULL);
SetLocalDescriptionOfferExpectError(kSdpWithoutCrypto, offer);
SetLocalDescriptionOfferExpectError(kSdpWithoutSdesCrypto, offer);
}
// Test we will return fail when apply an answer that doesn't have
// crypto enabled.
TEST_F(WebRtcSessionTest, SetLocalNonCryptoAnswer) {
// Test that we return a failure when applying a local answer that doesn't have
// cryptos enabled when DTLS is off.
TEST_F(WebRtcSessionTest, TestSetLocalNonSdesAnswerWhenSdesOn) {
Init(NULL);
SessionDescriptionInterface* offer = NULL;
SessionDescriptionInterface* answer = NULL;
@ -1214,12 +1267,12 @@ TEST_F(WebRtcSessionTest, SetLocalNonCryptoAnswer) {
// SetRemoteDescription and SetLocalDescription will take the ownership of
// the offer.
SetRemoteDescriptionWithoutError(offer);
SetLocalDescriptionAnswerExpectError(kSdpWithoutCrypto, answer);
SetLocalDescriptionAnswerExpectError(kSdpWithoutSdesCrypto, answer);
}
// Test we will return fail when apply an answer that doesn't have
// crypto enabled.
TEST_F(WebRtcSessionTest, SetRemoteNonCryptoAnswer) {
// Test we will return fail when apply an remote answer that doesn't have
// crypto enabled when DTLS is off.
TEST_F(WebRtcSessionTest, TestSetRemoteNonSdesAnswerWhenSdesOn) {
Init(NULL);
SessionDescriptionInterface* offer = NULL;
SessionDescriptionInterface* answer = NULL;
@ -1227,32 +1280,23 @@ TEST_F(WebRtcSessionTest, SetRemoteNonCryptoAnswer) {
// SetRemoteDescription and SetLocalDescription will take the ownership of
// the offer.
SetLocalDescriptionWithoutError(offer);
SetRemoteDescriptionAnswerExpectError(kSdpWithoutCrypto, answer);
SetRemoteDescriptionAnswerExpectError(kSdpWithoutSdesCrypto, answer);
}
// Test that we can create and set an offer with a DTLS fingerprint.
TEST_F(WebRtcSessionTest, CreateSetDtlsOffer) {
// Test that we accept an offer with a DTLS fingerprint when DTLS is on
// and that we return an answer with a DTLS fingerprint.
TEST_F(WebRtcSessionTest, TestReceiveDtlsOfferCreateDtlsAnswer) {
MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
InitWithDtls();
mediastream_signaling_.SendAudioVideoStream1();
SessionDescriptionInterface* offer = CreateOffer(NULL);
ASSERT_TRUE(offer != NULL);
VerifyFingerprintStatus(offer->description(), true);
// SetLocalDescription will take the ownership of the offer.
SetLocalDescriptionWithoutError(offer);
}
// Test that we can process an offer with a DTLS fingerprint
// and that we return an answer with a fingerprint.
TEST_F(WebRtcSessionTest, ReceiveDtlsOfferCreateAnswer) {
MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
InitWithDtls();
SetFactoryDtlsSrtp();
cricket::MediaSessionOptions options;
options.has_video = true;
JsepSessionDescription* offer = CreateRemoteOffer(options);
JsepSessionDescription* offer =
CreateRemoteOffer(options, cricket::SEC_DISABLED);
ASSERT_TRUE(offer != NULL);
VerifyFingerprintStatus(offer->description(), true);
VerifyNoCryptoParams(offer->description(), true);
// SetRemoteDescription will take the ownership of the offer.
SetRemoteDescriptionWithoutError(offer);
@ -1268,28 +1312,148 @@ TEST_F(WebRtcSessionTest, ReceiveDtlsOfferCreateAnswer) {
SetLocalDescriptionWithoutError(answer);
}
// Test that even if we support DTLS, if the other side didn't offer a
// fingerprint, we don't either.
TEST_F(WebRtcSessionTest, ReceiveNoDtlsOfferCreateAnswer) {
// Test that we set a local offer with a DTLS fingerprint when DTLS is on
// and then we accept a remote answer with a DTLS fingerprint successfully.
TEST_F(WebRtcSessionTest, TestCreateDtlsOfferReceiveDtlsAnswer) {
MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
mediastream_signaling_.SendAudioVideoStream1();
InitWithDtls();
SetFactoryDtlsSrtp();
// Verify that we get a crypto fingerprint in the answer.
SessionDescriptionInterface* offer = CreateOffer(NULL);
ASSERT_TRUE(offer != NULL);
VerifyFingerprintStatus(offer->description(), true);
// Check that we don't have an a=crypto line in the offer.
VerifyNoCryptoParams(offer->description(), true);
// Now set the local description, which should work, even without a=crypto.
SetLocalDescriptionWithoutError(offer);
cricket::MediaSessionOptions options;
options.has_video = true;
JsepSessionDescription* answer =
CreateRemoteAnswer(offer, options, cricket::SEC_DISABLED);
ASSERT_TRUE(answer != NULL);
VerifyFingerprintStatus(answer->description(), true);
VerifyNoCryptoParams(answer->description(), true);
// SetRemoteDescription will take the ownership of the answer.
SetRemoteDescriptionWithoutError(answer);
}
// Test that if we support DTLS and the other side didn't offer a fingerprint,
// we will fail to set the remote description.
TEST_F(WebRtcSessionTest, TestReceiveNonDtlsOfferWhenDtlsOn) {
MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
InitWithDtls();
cricket::MediaSessionOptions options;
options.has_video = true;
options.bundle_enabled = true;
JsepSessionDescription* offer = CreateRemoteOffer(
options, cricket::SEC_REQUIRED);
ASSERT_TRUE(offer != NULL);
VerifyFingerprintStatus(offer->description(), false);
VerifyCryptoParams(offer->description());
// SetRemoteDescription will take the ownership of
// the offer.
// SetRemoteDescription will take the ownership of the offer.
SetRemoteDescriptionOfferExpectError(
kSdpWithoutDtlsFingerprint, offer);
offer = CreateRemoteOffer(options, cricket::SEC_REQUIRED);
// SetLocalDescription will take the ownership of the offer.
SetLocalDescriptionOfferExpectError(
kSdpWithoutDtlsFingerprint, offer);
}
// Test that we return a failure when applying a local answer that doesn't have
// a DTLS fingerprint when DTLS is required.
TEST_F(WebRtcSessionTest, TestSetLocalNonDtlsAnswerWhenDtlsOn) {
MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
InitWithDtls();
SessionDescriptionInterface* offer = NULL;
SessionDescriptionInterface* answer = NULL;
CreateDtlsOfferAndNonDtlsAnswer(&offer, &answer);
// SetRemoteDescription and SetLocalDescription will take the ownership of
// the offer and answer.
SetRemoteDescriptionWithoutError(offer);
SetLocalDescriptionAnswerExpectError(
kSdpWithoutDtlsFingerprint, answer);
}
// Test that we return a failure when applying a remote answer that doesn't have
// a DTLS fingerprint when DTLS is required.
TEST_F(WebRtcSessionTest, TestSetRemoteNonDtlsAnswerWhenDtlsOn) {
MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
InitWithDtls();
SessionDescriptionInterface* offer = CreateOffer(NULL);
cricket::MediaSessionOptions options;
options.has_video = true;
JsepSessionDescription* answer =
CreateRemoteAnswer(offer, options, cricket::SEC_ENABLED);
// SetRemoteDescription and SetLocalDescription will take the ownership of
// the offer and answer.
SetLocalDescriptionWithoutError(offer);
SetRemoteDescriptionAnswerExpectError(
kSdpWithoutDtlsFingerprint, answer);
}
// Test that we create a local offer without SDES or DTLS and accept a remote
// answer without SDES or DTLS when encryption is disabled.
TEST_F(WebRtcSessionTest, TestCreateOfferReceiveAnswerWithoutEncryption) {
mediastream_signaling_.SendAudioVideoStream1();
options_.disable_encryption = true;
InitWithDtls();
// Verify that we get a crypto fingerprint in the answer.
SessionDescriptionInterface* offer = CreateOffer(NULL);
ASSERT_TRUE(offer != NULL);
VerifyFingerprintStatus(offer->description(), false);
// Check that we don't have an a=crypto line in the offer.
VerifyNoCryptoParams(offer->description(), false);
// Now set the local description, which should work, even without a=crypto.
SetLocalDescriptionWithoutError(offer);
cricket::MediaSessionOptions options;
options.has_video = true;
JsepSessionDescription* answer =
CreateRemoteAnswer(offer, options, cricket::SEC_DISABLED);
ASSERT_TRUE(answer != NULL);
VerifyFingerprintStatus(answer->description(), false);
VerifyNoCryptoParams(answer->description(), false);
// SetRemoteDescription will take the ownership of the answer.
SetRemoteDescriptionWithoutError(answer);
}
// Test that we create a local answer without SDES or DTLS and accept a remote
// offer without SDES or DTLS when encryption is disabled.
TEST_F(WebRtcSessionTest, TestCreateAnswerReceiveOfferWithoutEncryption) {
options_.disable_encryption = true;
InitWithDtls();
cricket::MediaSessionOptions options;
options.has_video = true;
JsepSessionDescription* offer =
CreateRemoteOffer(options, cricket::SEC_DISABLED);
ASSERT_TRUE(offer != NULL);
VerifyFingerprintStatus(offer->description(), false);
VerifyNoCryptoParams(offer->description(), false);
// SetRemoteDescription will take the ownership of the offer.
SetRemoteDescriptionWithoutError(offer);
// Verify that we don't get a crypto fingerprint in the answer.
// Verify that we get a crypto fingerprint in the answer.
SessionDescriptionInterface* answer = CreateAnswer(NULL);
ASSERT_TRUE(answer != NULL);
VerifyFingerprintStatus(answer->description(), false);
// Check that we don't have an a=crypto line in the answer.
VerifyNoCryptoParams(answer->description(), false);
// Now set the local description.
// Now set the local description, which should work, even without a=crypto.
SetLocalDescriptionWithoutError(answer);
}
@ -2700,7 +2864,7 @@ TEST_F(WebRtcSessionTest, TestRtpDataChannelConstraintTakesPrecedence) {
webrtc::MediaConstraintsInterface::kEnableRtpDataChannels, true);
options_.disable_sctp_data_channels = false;
InitWithDtls(false);
InitWithDtls();
SetLocalDescriptionWithDataChannel();
EXPECT_EQ(cricket::DCT_RTP, data_engine_->last_channel_type());
@ -2709,7 +2873,7 @@ TEST_F(WebRtcSessionTest, TestRtpDataChannelConstraintTakesPrecedence) {
TEST_F(WebRtcSessionTest, TestCreateOfferWithSctpEnabledWithoutStreams) {
MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
InitWithDtls(false);
InitWithDtls();
talk_base::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer(NULL));
EXPECT_TRUE(offer->description()->GetContentByName("data") == NULL);
@ -2719,13 +2883,13 @@ TEST_F(WebRtcSessionTest, TestCreateOfferWithSctpEnabledWithoutStreams) {
TEST_F(WebRtcSessionTest, TestCreateAnswerWithSctpInOfferAndNoStreams) {
MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
SetFactoryDtlsSrtp();
InitWithDtls(false);
InitWithDtls();
// Create remote offer with SCTP.
cricket::MediaSessionOptions options;
options.data_channel_type = cricket::DCT_SCTP;
JsepSessionDescription* offer =
CreateRemoteOffer(options, cricket::SEC_ENABLED);
CreateRemoteOffer(options, cricket::SEC_DISABLED);
SetRemoteDescriptionWithoutError(offer);
// Verifies the answer contains SCTP.
@ -2739,7 +2903,7 @@ TEST_F(WebRtcSessionTest, TestSctpDataChannelWithoutDtls) {
constraints_.reset(new FakeConstraints());
constraints_->AddOptional(
webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, false);
InitWithDtls(false);
InitWithDtls();
SetLocalDescriptionWithDataChannel();
EXPECT_EQ(cricket::DCT_NONE, data_engine_->last_channel_type());
@ -2748,7 +2912,7 @@ TEST_F(WebRtcSessionTest, TestSctpDataChannelWithoutDtls) {
TEST_F(WebRtcSessionTest, TestSctpDataChannelWithDtls) {
MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
InitWithDtls(false);
InitWithDtls();
SetLocalDescriptionWithDataChannel();
EXPECT_EQ(cricket::DCT_SCTP, data_engine_->last_channel_type());
@ -2757,7 +2921,7 @@ TEST_F(WebRtcSessionTest, TestSctpDataChannelWithDtls) {
TEST_F(WebRtcSessionTest, TestDisableSctpDataChannels) {
MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
options_.disable_sctp_data_channels = true;
InitWithDtls(false);
InitWithDtls();
SetLocalDescriptionWithDataChannel();
EXPECT_EQ(cricket::DCT_NONE, data_engine_->last_channel_type());
@ -2768,7 +2932,7 @@ TEST_F(WebRtcSessionTest, TestSctpDataChannelSendPortParsing) {
const int new_send_port = 9998;
const int new_recv_port = 7775;
InitWithDtls(false);
InitWithDtls();
SetFactoryDtlsSrtp();
// By default, don't actually add the codecs to desc_factory_; they don't
@ -2821,34 +2985,41 @@ TEST_F(WebRtcSessionTest, TestSctpDataChannelSendPortParsing) {
// identity generation is finished.
TEST_F(WebRtcSessionTest, TestCreateOfferBeforeIdentityRequestReturnSuccess) {
MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
InitWithDtls(false);
InitWithDtls();
EXPECT_TRUE(session_->waiting_for_identity());
mediastream_signaling_.SendAudioVideoStream1();
talk_base::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer(NULL));
EXPECT_TRUE(offer != NULL);
VerifyNoCryptoParams(offer->description(), true);
VerifyFingerprintStatus(offer->description(), true);
}
// Verifies that CreateAnswer succeeds when CreateOffer is called before async
// identity generation is finished.
TEST_F(WebRtcSessionTest, TestCreateAnswerBeforeIdentityRequestReturnSuccess) {
MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
InitWithDtls(false);
InitWithDtls();
SetFactoryDtlsSrtp();
cricket::MediaSessionOptions options;
options.has_video = true;
scoped_ptr<JsepSessionDescription> offer(
CreateRemoteOffer(options, cricket::SEC_REQUIRED));
CreateRemoteOffer(options, cricket::SEC_DISABLED));
ASSERT_TRUE(offer.get() != NULL);
SetRemoteDescriptionWithoutError(offer.release());
talk_base::scoped_ptr<SessionDescriptionInterface> answer(CreateAnswer(NULL));
EXPECT_TRUE(answer != NULL);
VerifyNoCryptoParams(answer->description(), true);
VerifyFingerprintStatus(answer->description(), true);
}
// Verifies that CreateOffer succeeds when CreateOffer is called after async
// identity generation is finished.
TEST_F(WebRtcSessionTest, TestCreateOfferAfterIdentityRequestReturnSuccess) {
MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
InitWithDtls(false);
InitWithDtls();
EXPECT_TRUE_WAIT(!session_->waiting_for_identity(), 1000);
talk_base::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer(NULL));
@ -2919,7 +3090,7 @@ TEST_F(WebRtcSessionTest, TestSetRemoteOfferFailIfDtlsDisabledAndNoCrypto) {
audio->description.identity_fingerprint.reset(
talk_base::SSLFingerprint::CreateFromRfc4572(
talk_base::DIGEST_SHA_256, kFakeDtlsFingerprint));
SetRemoteDescriptionOfferExpectError(kSdpWithoutSdesAndDtlsDisabled,
SetRemoteDescriptionOfferExpectError(kSdpWithoutSdesCrypto,
offer);
}

View File

@ -127,8 +127,8 @@ WebRtcSessionDescriptionFactory::WebRtcSessionDescriptionFactory(
identity_request_state_(IDENTITY_NOT_NEEDED) {
transport_desc_factory_.set_protocol(cricket::ICEPROTO_HYBRID);
session_desc_factory_.set_add_legacy_streams(false);
// By default SRTP-SDES is enabled in WebRtc.
SetSecure(cricket::SEC_REQUIRED);
// SRTP-SDES is disabled if DTLS is on.
SetSdesPolicy(dtls_enabled ? cricket::SEC_DISABLED : cricket::SEC_REQUIRED);
if (!dtls_enabled) {
return;
@ -261,12 +261,12 @@ void WebRtcSessionDescriptionFactory::CreateAnswer(
}
}
void WebRtcSessionDescriptionFactory::SetSecure(
cricket::SecureMediaPolicy secure_policy) {
void WebRtcSessionDescriptionFactory::SetSdesPolicy(
cricket::SecurePolicy secure_policy) {
session_desc_factory_.set_secure(secure_policy);
}
cricket::SecureMediaPolicy WebRtcSessionDescriptionFactory::Secure() const {
cricket::SecurePolicy WebRtcSessionDescriptionFactory::SdesPolicy() const {
return session_desc_factory_.secure();
}
@ -318,7 +318,8 @@ void WebRtcSessionDescriptionFactory::InternalCreateOffer(
if (!offer->Initialize(desc, session_id_,
talk_base::ToString(session_version_++))) {
delete offer;
PostCreateSessionDescriptionFailed(request.observer, "CreateOffer failed.");
PostCreateSessionDescriptionFailed(request.observer,
"Failed to initialize the offer.");
return;
}
if (session_->local_description() &&
@ -362,7 +363,7 @@ void WebRtcSessionDescriptionFactory::InternalCreateAnswer(
talk_base::ToString(session_version_++))) {
delete answer;
PostCreateSessionDescriptionFailed(request.observer,
"CreateAnswer failed.");
"Failed to initialize the answer.");
return;
}
if (session_->local_description() &&
@ -380,6 +381,7 @@ void WebRtcSessionDescriptionFactory::PostCreateSessionDescriptionFailed(
CreateSessionDescriptionMsg* msg = new CreateSessionDescriptionMsg(observer);
msg->error = error;
signaling_thread_->Post(this, MSG_CREATE_SESSIONDESCRIPTION_FAILED, msg);
LOG(LS_ERROR) << "Create SDP failed: " << error;
}
void WebRtcSessionDescriptionFactory::PostCreateSessionDescriptionSucceeded(

View File

@ -112,8 +112,8 @@ class WebRtcSessionDescriptionFactory : public talk_base::MessageHandler,
CreateSessionDescriptionObserver* observer,
const MediaConstraintsInterface* constraints);
void SetSecure(cricket::SecureMediaPolicy secure_policy);
cricket::SecureMediaPolicy Secure() const;
void SetSdesPolicy(cricket::SecurePolicy secure_policy);
cricket::SecurePolicy SdesPolicy() const;
sigslot::signal1<talk_base::SSLIdentity*> SignalIdentityReady;

View File

@ -704,8 +704,9 @@ class WebRtcVideoChannelSendInfo : public sigslot::has_slots<> {
// TODO(thorcarpenter): Have VideoAdapter be responsible for setting
// all these video options.
CoordinatedVideoAdapter* video_adapter = video_capturer_->video_adapter();
if (video_options_.adapt_input_to_cpu_usage.Get(&cpu_adapt)) {
video_adapter->set_cpu_adaptation(cpu_adapt);
if (video_options_.adapt_input_to_cpu_usage.Get(&cpu_adapt) ||
overuse_observer_enabled_) {
video_adapter->set_cpu_adaptation(cpu_adapt || overuse_observer_enabled_);
}
if (video_options_.adapt_cpu_with_smoothing.Get(&cpu_smoothing)) {
video_adapter->set_cpu_smoothing(cpu_smoothing);
@ -727,19 +728,18 @@ class WebRtcVideoChannelSendInfo : public sigslot::has_slots<> {
void SetCpuOveruseDetection(bool enable) {
overuse_observer_enabled_ = enable;
if (!overuse_observer_) {
// Cannot actually use the overuse detector until it is initialized
// with a video adapter.
return;
if (overuse_observer_) {
overuse_observer_->Enable(enable);
}
overuse_observer_->Enable(enable);
// If overuse detection is enabled, it will signal the video adapter
// instead of the cpu monitor. If disabled, connect the adapter to the
// cpu monitor.
// The video adapter is signaled by overuse detection if enabled; otherwise
// it will be signaled by cpu monitor.
CoordinatedVideoAdapter* adapter = video_adapter();
if (adapter) {
adapter->set_cpu_adaptation(enable);
bool cpu_adapt = false;
video_options_.adapt_input_to_cpu_usage.Get(&cpu_adapt);
adapter->set_cpu_adaptation(
adapter->cpu_adaptation() || cpu_adapt || enable);
if (cpu_monitor_) {
if (enable) {
cpu_monitor_->SignalUpdate.disconnect(adapter);

View File

@ -1159,7 +1159,7 @@ bool BaseChannel::SetBaseLocalContent_w(const MediaContentDescription* content,
ContentAction action,
std::string* error_desc) {
// Cache secure_required_ for belt and suspenders check on SendPacket
secure_required_ = content->crypto_required();
secure_required_ = content->crypto_required() != CT_NONE;
bool ret = UpdateLocalStreams_w(content->streams(), action, error_desc);
// Set local SRTP parameters (what we will encrypt with).
ret &= SetSrtp_w(content->cryptos(), action, CS_LOCAL, error_desc);

View File

@ -691,7 +691,7 @@ template <class C>
static bool CreateMediaContentOffer(
const MediaSessionOptions& options,
const std::vector<C>& codecs,
const SecureMediaPolicy& secure_policy,
const SecurePolicy& secure_policy,
const CryptoParamsVec* current_cryptos,
const std::vector<std::string>& crypto_suites,
const RtpHeaderExtensions& rtp_extensions,
@ -701,7 +701,9 @@ static bool CreateMediaContentOffer(
offer->AddCodecs(codecs);
offer->SortCodecs();
offer->set_crypto_required(secure_policy == SEC_REQUIRED);
if (secure_policy == SEC_REQUIRED) {
offer->set_crypto_required(CT_SDES);
}
offer->set_rtcp_mux(options.rtcp_mux_enabled);
offer->set_multistream(options.is_muc);
offer->set_rtp_header_extensions(rtp_extensions);
@ -725,7 +727,7 @@ static bool CreateMediaContentOffer(
}
#endif
if (offer->crypto_required() && offer->cryptos().empty()) {
if (offer->crypto_required() == CT_SDES && offer->cryptos().empty()) {
return false;
}
return true;
@ -903,7 +905,7 @@ static bool CreateMediaContentAnswer(
const MediaContentDescriptionImpl<C>* offer,
const MediaSessionOptions& options,
const std::vector<C>& local_codecs,
const SecureMediaPolicy& sdes_policy,
const SecurePolicy& sdes_policy,
const CryptoParamsVec* current_cryptos,
const RtpHeaderExtensions& local_rtp_extenstions,
StreamParamsVec* current_streams,
@ -934,7 +936,7 @@ static bool CreateMediaContentAnswer(
}
if (answer->cryptos().empty() &&
(offer->crypto_required() || sdes_policy == SEC_REQUIRED)) {
(offer->crypto_required() == CT_SDES || sdes_policy == SEC_REQUIRED)) {
return false;
}

View File

@ -54,9 +54,6 @@ typedef std::vector<DataCodec> DataCodecs;
typedef std::vector<CryptoParams> CryptoParamsVec;
typedef std::vector<RtpHeaderExtension> RtpHeaderExtensions;
// TODO(juberti): Replace SecureMediaPolicy with SecurePolicy everywhere.
typedef SecurePolicy SecureMediaPolicy;
enum MediaType {
MEDIA_TYPE_AUDIO,
MEDIA_TYPE_VIDEO,
@ -72,6 +69,12 @@ enum MediaContentDirection {
MD_SENDRECV
};
enum CryptoType {
CT_NONE,
CT_SDES,
CT_DTLS
};
// RTC4585 RTP/AVPF
extern const char kMediaProtocolAvpf[];
// RFC5124 RTP/SAVPF
@ -155,7 +158,7 @@ class MediaContentDescription : public ContentDescription {
MediaContentDescription()
: rtcp_mux_(false),
bandwidth_(kAutoBandwidth),
crypto_required_(false),
crypto_required_(CT_NONE),
rtp_header_extensions_set_(false),
multistream_(false),
conference_mode_(false),
@ -190,9 +193,10 @@ class MediaContentDescription : public ContentDescription {
void set_cryptos(const std::vector<CryptoParams>& cryptos) {
cryptos_ = cryptos;
}
bool crypto_required() const { return crypto_required_; }
void set_crypto_required(bool crypto) {
crypto_required_ = crypto;
CryptoType crypto_required() const { return crypto_required_; }
void set_crypto_required(CryptoType type) {
crypto_required_ = type;
}
const RtpHeaderExtensions& rtp_header_extensions() const {
@ -279,7 +283,7 @@ class MediaContentDescription : public ContentDescription {
int bandwidth_;
std::string protocol_;
std::vector<CryptoParams> cryptos_;
bool crypto_required_;
CryptoType crypto_required_;
std::vector<RtpHeaderExtension> rtp_header_extensions_;
bool rtp_header_extensions_set_;
bool multistream_;

View File

@ -41,12 +41,12 @@
#ifdef HAVE_SRTP
#define ASSERT_CRYPTO(cd, s, cs) \
ASSERT_FALSE(cd->crypto_required()); \
ASSERT_EQ(cricket::CT_NONE, cd->crypto_required()); \
ASSERT_EQ(s, cd->cryptos().size()); \
ASSERT_EQ(std::string(cs), cd->cryptos()[0].cipher_suite)
#else
#define ASSERT_CRYPTO(cd, s, cs) \
ASSERT_FALSE(cd->crypto_required()); \
ASSERT_EQ(cricket::CT_NONE, cd->crypto_required()); \
ASSERT_EQ(0U, cd->cryptos().size());
#endif

View File

@ -339,8 +339,9 @@ bool ParseGingleEncryption(const buzz::XmlElement* desc,
encryption != NULL;
encryption = encryption->NextNamed(QN_ENCRYPTION)) {
if (encryption->FirstNamed(usage) != NULL) {
media->set_crypto_required(
GetXmlAttr(encryption, QN_ENCRYPTION_REQUIRED, false));
if (GetXmlAttr(encryption, QN_ENCRYPTION_REQUIRED, false)) {
media->set_crypto_required(CT_SDES);
}
for (const buzz::XmlElement* crypto = encryption->FirstNamed(QN_CRYPTO);
crypto != NULL;
crypto = crypto->NextNamed(QN_CRYPTO)) {
@ -479,8 +480,9 @@ bool ParseJingleEncryption(const buzz::XmlElement* content_elem,
return true;
}
media->set_crypto_required(
GetXmlAttr(encryption, QN_ENCRYPTION_REQUIRED, false));
if (GetXmlAttr(encryption, QN_ENCRYPTION_REQUIRED, false)) {
media->set_crypto_required(CT_SDES);
}
for (const buzz::XmlElement* crypto = encryption->FirstNamed(QN_CRYPTO);
crypto != NULL;

View File

@ -2751,11 +2751,11 @@ class MediaSessionClientTest : public sigslot::has_slots<> {
ClearStanzas();
}
void MakeSignalingSecure(cricket::SecureMediaPolicy secure) {
void MakeSignalingSecure(cricket::SecurePolicy secure) {
client_->set_secure(secure);
}
void ExpectCrypto(cricket::SecureMediaPolicy secure) {
void ExpectCrypto(cricket::SecurePolicy secure) {
MakeSignalingSecure(secure);
expect_incoming_crypto_ = true;
#ifdef HAVE_SRTP

View File

@ -119,6 +119,7 @@ const char STR_MUC_ROOM_FEATURE_HANGOUT_LITE[] = "muc_lite";
const char STR_MUC_ROOM_FEATURE_BROADCAST[] = "broadcast";
const char STR_MUC_ROOM_FEATURE_MULTI_USER_VC[] = "muc_muvc";
const char STR_MUC_ROOM_FEATURE_RECORDABLE[] = "recordable";
const char STR_MUC_ROOM_FEATURE_CUSTOM_RECORDING[] = "custom_recording";
const char STR_MUC_ROOM_OWNER_PROFILE_ID[] = "muc#roominfo_owner_profile_id";
const char STR_ID_TYPE_CONVERSATION[] = "conversation";

View File

@ -112,6 +112,7 @@ extern const char STR_MUC_ROOM_FEATURE_HANGOUT_LITE[];
extern const char STR_MUC_ROOM_FEATURE_BROADCAST[];
extern const char STR_MUC_ROOM_FEATURE_MULTI_USER_VC[];
extern const char STR_MUC_ROOM_FEATURE_RECORDABLE[];
extern const char STR_MUC_ROOM_FEATURE_CUSTOM_RECORDING[];
extern const char STR_MUC_ROOM_OWNER_PROFILE_ID[];
extern const char STR_ID_TYPE_CONVERSATION[];