Update libjingle to 61514460
TBR=tommi@webrtc.org Review URL: https://webrtc-codereview.appspot.com/8649004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@5545 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
8f690bc222
commit
e749c9ebdb
@ -106,6 +106,8 @@ void LocalAudioTrackHandler::Stop() {
|
|||||||
void LocalAudioTrackHandler::OnEnabledChanged() {
|
void LocalAudioTrackHandler::OnEnabledChanged() {
|
||||||
cricket::AudioOptions options;
|
cricket::AudioOptions options;
|
||||||
if (audio_track_->enabled() && audio_track_->GetSource()) {
|
if (audio_track_->enabled() && audio_track_->GetSource()) {
|
||||||
|
// TODO(xians): Remove this static_cast since we should be able to connect
|
||||||
|
// a remote audio track to peer connection.
|
||||||
options = static_cast<LocalAudioSource*>(
|
options = static_cast<LocalAudioSource*>(
|
||||||
audio_track_->GetSource())->options();
|
audio_track_->GetSource())->options();
|
||||||
}
|
}
|
||||||
@ -125,10 +127,12 @@ RemoteAudioTrackHandler::RemoteAudioTrackHandler(
|
|||||||
: TrackHandler(track, ssrc),
|
: TrackHandler(track, ssrc),
|
||||||
audio_track_(track),
|
audio_track_(track),
|
||||||
provider_(provider) {
|
provider_(provider) {
|
||||||
|
track->GetSource()->RegisterAudioObserver(this);
|
||||||
OnEnabledChanged();
|
OnEnabledChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
RemoteAudioTrackHandler::~RemoteAudioTrackHandler() {
|
RemoteAudioTrackHandler::~RemoteAudioTrackHandler() {
|
||||||
|
audio_track_->GetSource()->UnregisterAudioObserver(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteAudioTrackHandler::Stop() {
|
void RemoteAudioTrackHandler::Stop() {
|
||||||
@ -143,6 +147,14 @@ void RemoteAudioTrackHandler::OnEnabledChanged() {
|
|||||||
audio_track_->GetRenderer());
|
audio_track_->GetRenderer());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RemoteAudioTrackHandler::OnSetVolume(double volume) {
|
||||||
|
// When the track is disabled, the volume of the source, which is the
|
||||||
|
// corresponding WebRtc Voice Engine channel will be 0. So we do not allow
|
||||||
|
// setting the volume to the source when the track is disabled.
|
||||||
|
if (audio_track_->enabled())
|
||||||
|
provider_->SetAudioPlayoutVolume(ssrc(), volume);
|
||||||
|
}
|
||||||
|
|
||||||
LocalVideoTrackHandler::LocalVideoTrackHandler(
|
LocalVideoTrackHandler::LocalVideoTrackHandler(
|
||||||
VideoTrackInterface* track,
|
VideoTrackInterface* track,
|
||||||
uint32 ssrc,
|
uint32 ssrc,
|
||||||
|
@ -118,7 +118,8 @@ class LocalAudioTrackHandler : public TrackHandler {
|
|||||||
// RemoteAudioTrackHandler listen to events on a remote AudioTrack instance
|
// RemoteAudioTrackHandler listen to events on a remote AudioTrack instance
|
||||||
// connected to a PeerConnection and orders the |provider| to executes the
|
// connected to a PeerConnection and orders the |provider| to executes the
|
||||||
// requested change.
|
// requested change.
|
||||||
class RemoteAudioTrackHandler : public TrackHandler {
|
class RemoteAudioTrackHandler : public AudioSourceInterface::AudioObserver,
|
||||||
|
public TrackHandler {
|
||||||
public:
|
public:
|
||||||
RemoteAudioTrackHandler(AudioTrackInterface* track,
|
RemoteAudioTrackHandler(AudioTrackInterface* track,
|
||||||
uint32 ssrc,
|
uint32 ssrc,
|
||||||
@ -131,6 +132,9 @@ class RemoteAudioTrackHandler : public TrackHandler {
|
|||||||
virtual void OnEnabledChanged() OVERRIDE;
|
virtual void OnEnabledChanged() OVERRIDE;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// AudioSourceInterface::AudioObserver implementation.
|
||||||
|
virtual void OnSetVolume(double volume) OVERRIDE;
|
||||||
|
|
||||||
AudioTrackInterface* audio_track_;
|
AudioTrackInterface* audio_track_;
|
||||||
AudioProviderInterface* provider_;
|
AudioProviderInterface* provider_;
|
||||||
};
|
};
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
|
|
||||||
#include "talk/app/webrtc/audiotrack.h"
|
#include "talk/app/webrtc/audiotrack.h"
|
||||||
#include "talk/app/webrtc/mediastream.h"
|
#include "talk/app/webrtc/mediastream.h"
|
||||||
|
#include "talk/app/webrtc/remoteaudiosource.h"
|
||||||
#include "talk/app/webrtc/streamcollection.h"
|
#include "talk/app/webrtc/streamcollection.h"
|
||||||
#include "talk/app/webrtc/videosource.h"
|
#include "talk/app/webrtc/videosource.h"
|
||||||
#include "talk/app/webrtc/videotrack.h"
|
#include "talk/app/webrtc/videotrack.h"
|
||||||
@ -59,6 +60,7 @@ class MockAudioProvider : public AudioProviderInterface {
|
|||||||
MOCK_METHOD4(SetAudioSend, void(uint32 ssrc, bool enable,
|
MOCK_METHOD4(SetAudioSend, void(uint32 ssrc, bool enable,
|
||||||
const cricket::AudioOptions& options,
|
const cricket::AudioOptions& options,
|
||||||
cricket::AudioRenderer* renderer));
|
cricket::AudioRenderer* renderer));
|
||||||
|
MOCK_METHOD2(SetAudioPlayoutVolume, void(uint32 ssrc, double volume));
|
||||||
};
|
};
|
||||||
|
|
||||||
// Helper class to test MediaStreamHandler.
|
// Helper class to test MediaStreamHandler.
|
||||||
@ -110,12 +112,11 @@ class MediaStreamHandlerTest : public testing::Test {
|
|||||||
FakeVideoSource::Create());
|
FakeVideoSource::Create());
|
||||||
video_track_ = VideoTrack::Create(kVideoTrackId, source);
|
video_track_ = VideoTrack::Create(kVideoTrackId, source);
|
||||||
EXPECT_TRUE(stream_->AddTrack(video_track_));
|
EXPECT_TRUE(stream_->AddTrack(video_track_));
|
||||||
audio_track_ = AudioTrack::Create(kAudioTrackId,
|
|
||||||
NULL);
|
|
||||||
EXPECT_TRUE(stream_->AddTrack(audio_track_));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddLocalAudioTrack() {
|
void AddLocalAudioTrack() {
|
||||||
|
audio_track_ = AudioTrack::Create(kAudioTrackId, NULL);
|
||||||
|
EXPECT_TRUE(stream_->AddTrack(audio_track_));
|
||||||
EXPECT_CALL(audio_provider_, SetAudioSend(kAudioSsrc, true, _, _));
|
EXPECT_CALL(audio_provider_, SetAudioSend(kAudioSsrc, true, _, _));
|
||||||
handlers_.AddLocalAudioTrack(stream_, stream_->GetAudioTracks()[0],
|
handlers_.AddLocalAudioTrack(stream_, stream_->GetAudioTracks()[0],
|
||||||
kAudioSsrc);
|
kAudioSsrc);
|
||||||
@ -144,6 +145,9 @@ class MediaStreamHandlerTest : public testing::Test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AddRemoteAudioTrack() {
|
void AddRemoteAudioTrack() {
|
||||||
|
audio_track_ = AudioTrack::Create(kAudioTrackId,
|
||||||
|
RemoteAudioSource::Create().get());
|
||||||
|
EXPECT_TRUE(stream_->AddTrack(audio_track_));
|
||||||
EXPECT_CALL(audio_provider_, SetAudioPlayout(kAudioSsrc, true, _));
|
EXPECT_CALL(audio_provider_, SetAudioPlayout(kAudioSsrc, true, _));
|
||||||
handlers_.AddRemoteAudioTrack(stream_, stream_->GetAudioTracks()[0],
|
handlers_.AddRemoteAudioTrack(stream_, stream_->GetAudioTracks()[0],
|
||||||
kAudioSsrc);
|
kAudioSsrc);
|
||||||
@ -292,4 +296,27 @@ TEST_F(MediaStreamHandlerTest, RemoteVideoTrackDisable) {
|
|||||||
handlers_.TearDown();
|
handlers_.TearDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(MediaStreamHandlerTest, RemoteAudioTrackSetVolume) {
|
||||||
|
AddRemoteAudioTrack();
|
||||||
|
|
||||||
|
double volume = 0.5;
|
||||||
|
EXPECT_CALL(audio_provider_, SetAudioPlayoutVolume(kAudioSsrc, volume));
|
||||||
|
audio_track_->GetSource()->SetVolume(volume);
|
||||||
|
|
||||||
|
// Disable the audio track, this should prevent setting the volume.
|
||||||
|
EXPECT_CALL(audio_provider_, SetAudioPlayout(kAudioSsrc, false, _));
|
||||||
|
audio_track_->set_enabled(false);
|
||||||
|
audio_track_->GetSource()->SetVolume(1.0);
|
||||||
|
|
||||||
|
EXPECT_CALL(audio_provider_, SetAudioPlayout(kAudioSsrc, true, _));
|
||||||
|
audio_track_->set_enabled(true);
|
||||||
|
|
||||||
|
double new_volume = 0.8;
|
||||||
|
EXPECT_CALL(audio_provider_, SetAudioPlayoutVolume(kAudioSsrc, new_volume));
|
||||||
|
audio_track_->GetSource()->SetVolume(new_volume);
|
||||||
|
|
||||||
|
RemoveRemoteAudioTrack();
|
||||||
|
handlers_.TearDown();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
@ -142,9 +142,24 @@ class VideoTrackInterface : public MediaStreamTrackInterface {
|
|||||||
|
|
||||||
// AudioSourceInterface is a reference counted source used for AudioTracks.
|
// AudioSourceInterface is a reference counted source used for AudioTracks.
|
||||||
// The same source can be used in multiple AudioTracks.
|
// The same source can be used in multiple AudioTracks.
|
||||||
// TODO(perkj): Extend this class with necessary methods to allow separate
|
|
||||||
// sources for each audio track.
|
|
||||||
class AudioSourceInterface : public MediaSourceInterface {
|
class AudioSourceInterface : public MediaSourceInterface {
|
||||||
|
public:
|
||||||
|
class AudioObserver {
|
||||||
|
public:
|
||||||
|
virtual void OnSetVolume(double volume) = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual ~AudioObserver() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO(xians): Makes all the interface pure virtual after Chrome has their
|
||||||
|
// implementations.
|
||||||
|
// Sets the volume to the source. |volume| is in the range of [0, 10].
|
||||||
|
virtual void SetVolume(double volume) {}
|
||||||
|
|
||||||
|
// Registers/unregisters observer to the audio source.
|
||||||
|
virtual void RegisterAudioObserver(AudioObserver* observer) {}
|
||||||
|
virtual void UnregisterAudioObserver(AudioObserver* observer) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Interface for receiving audio data from a AudioTrack.
|
// Interface for receiving audio data from a AudioTrack.
|
||||||
|
@ -53,6 +53,10 @@ class AudioProviderInterface {
|
|||||||
const cricket::AudioOptions& options,
|
const cricket::AudioOptions& options,
|
||||||
cricket::AudioRenderer* renderer) = 0;
|
cricket::AudioRenderer* renderer) = 0;
|
||||||
|
|
||||||
|
// Sets the audio playout volume of a remote audio track with |ssrc|.
|
||||||
|
// |volume| is in the range of [0, 10].
|
||||||
|
virtual void SetAudioPlayoutVolume(uint32 ssrc, double volume) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual ~AudioProviderInterface() {}
|
virtual ~AudioProviderInterface() {}
|
||||||
};
|
};
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#include "talk/app/webrtc/mediastreamproxy.h"
|
#include "talk/app/webrtc/mediastreamproxy.h"
|
||||||
#include "talk/app/webrtc/mediaconstraintsinterface.h"
|
#include "talk/app/webrtc/mediaconstraintsinterface.h"
|
||||||
#include "talk/app/webrtc/mediastreamtrackproxy.h"
|
#include "talk/app/webrtc/mediastreamtrackproxy.h"
|
||||||
|
#include "talk/app/webrtc/remoteaudiosource.h"
|
||||||
#include "talk/app/webrtc/remotevideocapturer.h"
|
#include "talk/app/webrtc/remotevideocapturer.h"
|
||||||
#include "talk/app/webrtc/sctputils.h"
|
#include "talk/app/webrtc/sctputils.h"
|
||||||
#include "talk/app/webrtc/videosource.h"
|
#include "talk/app/webrtc/videosource.h"
|
||||||
@ -140,7 +141,7 @@ class RemoteMediaStreamFactory {
|
|||||||
AudioTrackInterface* AddAudioTrack(webrtc::MediaStreamInterface* stream,
|
AudioTrackInterface* AddAudioTrack(webrtc::MediaStreamInterface* stream,
|
||||||
const std::string& track_id) {
|
const std::string& track_id) {
|
||||||
return AddTrack<AudioTrackInterface, AudioTrack, AudioTrackProxy>(
|
return AddTrack<AudioTrackInterface, AudioTrack, AudioTrackProxy>(
|
||||||
stream, track_id, static_cast<AudioSourceInterface*>(NULL));
|
stream, track_id, RemoteAudioSource::Create().get());
|
||||||
}
|
}
|
||||||
|
|
||||||
VideoTrackInterface* AddVideoTrack(webrtc::MediaStreamInterface* stream,
|
VideoTrackInterface* AddVideoTrack(webrtc::MediaStreamInterface* stream,
|
||||||
|
72
talk/app/webrtc/remoteaudiosource.cc
Normal file
72
talk/app/webrtc/remoteaudiosource.cc
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* libjingle
|
||||||
|
* Copyright 2014, Google Inc.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||||
|
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||||
|
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||||
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "talk/app/webrtc/remoteaudiosource.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
#include "talk/base/logging.h"
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
|
||||||
|
talk_base::scoped_refptr<RemoteAudioSource> RemoteAudioSource::Create() {
|
||||||
|
return new talk_base::RefCountedObject<RemoteAudioSource>();
|
||||||
|
}
|
||||||
|
|
||||||
|
RemoteAudioSource::RemoteAudioSource() {
|
||||||
|
}
|
||||||
|
|
||||||
|
RemoteAudioSource::~RemoteAudioSource() {
|
||||||
|
ASSERT(audio_observers_.empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
MediaSourceInterface::SourceState RemoteAudioSource::state() const {
|
||||||
|
return MediaSourceInterface::kLive;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoteAudioSource::SetVolume(double volume) {
|
||||||
|
ASSERT(volume >= 0 && volume <= 10);
|
||||||
|
for (AudioObserverList::iterator it = audio_observers_.begin();
|
||||||
|
it != audio_observers_.end(); ++it) {
|
||||||
|
(*it)->OnSetVolume(volume);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoteAudioSource::RegisterAudioObserver(AudioObserver* observer) {
|
||||||
|
ASSERT(observer != NULL);
|
||||||
|
ASSERT(std::find(audio_observers_.begin(), audio_observers_.end(),
|
||||||
|
observer) == audio_observers_.end());
|
||||||
|
audio_observers_.push_back(observer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoteAudioSource::UnregisterAudioObserver(AudioObserver* observer) {
|
||||||
|
ASSERT(observer != NULL);
|
||||||
|
audio_observers_.remove(observer);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace webrtc
|
66
talk/app/webrtc/remoteaudiosource.h
Normal file
66
talk/app/webrtc/remoteaudiosource.h
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* libjingle
|
||||||
|
* Copyright 2014, Google Inc.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||||
|
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||||
|
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||||
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef TALK_APP_WEBRTC_REMOTEAUDIOSOURCE_H_
|
||||||
|
#define TALK_APP_WEBRTC_REMOTEAUDIOSOURCE_H_
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
|
||||||
|
#include "talk/app/webrtc/mediastreaminterface.h"
|
||||||
|
#include "talk/app/webrtc/notifier.h"
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
|
||||||
|
using webrtc::AudioSourceInterface;
|
||||||
|
|
||||||
|
// This class implements the audio source used by the remote audio track.
|
||||||
|
class RemoteAudioSource : public Notifier<AudioSourceInterface> {
|
||||||
|
public:
|
||||||
|
// Creates an instance of RemoteAudioSource.
|
||||||
|
static talk_base::scoped_refptr<RemoteAudioSource> Create();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
RemoteAudioSource();
|
||||||
|
virtual ~RemoteAudioSource();
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef std::list<AudioObserver*> AudioObserverList;
|
||||||
|
|
||||||
|
// MediaSourceInterface implementation.
|
||||||
|
virtual MediaSourceInterface::SourceState state() const OVERRIDE;
|
||||||
|
|
||||||
|
// AudioSourceInterface implementation.
|
||||||
|
virtual void SetVolume(double volume) OVERRIDE;
|
||||||
|
virtual void RegisterAudioObserver(AudioObserver* observer) OVERRIDE;
|
||||||
|
virtual void UnregisterAudioObserver(AudioObserver* observer) OVERRIDE;
|
||||||
|
|
||||||
|
AudioObserverList audio_observers_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace webrtc
|
||||||
|
|
||||||
|
#endif // TALK_APP_WEBRTC_REMOTEAUDIOSOURCE_H_
|
@ -78,6 +78,7 @@ const char StatsReport::kStatsValueNameEchoReturnLossEnhancement[] =
|
|||||||
|
|
||||||
const char StatsReport::kStatsValueNameEncodeUsagePercent[] =
|
const char StatsReport::kStatsValueNameEncodeUsagePercent[] =
|
||||||
"googEncodeUsagePercent";
|
"googEncodeUsagePercent";
|
||||||
|
const char StatsReport::kStatsValueNameExpandRate[] = "googExpandRate";
|
||||||
const char StatsReport::kStatsValueNameFingerprint[] = "googFingerprint";
|
const char StatsReport::kStatsValueNameFingerprint[] = "googFingerprint";
|
||||||
const char StatsReport::kStatsValueNameFingerprintAlgorithm[] =
|
const char StatsReport::kStatsValueNameFingerprintAlgorithm[] =
|
||||||
"googFingerprintAlgorithm";
|
"googFingerprintAlgorithm";
|
||||||
@ -221,7 +222,7 @@ void ExtractStats(const cricket::VoiceReceiverInfo& info, StatsReport* report) {
|
|||||||
info.bytes_rcvd);
|
info.bytes_rcvd);
|
||||||
report->AddValue(StatsReport::kStatsValueNameJitterReceived,
|
report->AddValue(StatsReport::kStatsValueNameJitterReceived,
|
||||||
info.jitter_ms);
|
info.jitter_ms);
|
||||||
report->AddValue(StatsReport::kStatsValueNameNetEqExpandRate,
|
report->AddValue(StatsReport::kStatsValueNameExpandRate,
|
||||||
talk_base::ToString<float>(info.expand_rate));
|
talk_base::ToString<float>(info.expand_rate));
|
||||||
report->AddValue(StatsReport::kStatsValueNamePacketsReceived,
|
report->AddValue(StatsReport::kStatsValueNamePacketsReceived,
|
||||||
info.packets_rcvd);
|
info.packets_rcvd);
|
||||||
@ -569,6 +570,14 @@ std::string StatsCollector::AddOneCertificateReport(
|
|||||||
|
|
||||||
talk_base::scoped_ptr<talk_base::SSLFingerprint> ssl_fingerprint(
|
talk_base::scoped_ptr<talk_base::SSLFingerprint> ssl_fingerprint(
|
||||||
talk_base::SSLFingerprint::Create(digest_algorithm, cert));
|
talk_base::SSLFingerprint::Create(digest_algorithm, cert));
|
||||||
|
|
||||||
|
// SSLFingerprint::Create can fail if the algorithm returned by
|
||||||
|
// SSLCertificate::GetSignatureDigestAlgorithm is not supported by the
|
||||||
|
// implementation of SSLCertificate::ComputeDigest. This currently happens
|
||||||
|
// with MD5- and SHA-224-signed certificates when linked to libNSS.
|
||||||
|
if (!ssl_fingerprint)
|
||||||
|
return std::string();
|
||||||
|
|
||||||
std::string fingerprint = ssl_fingerprint->GetRfc4572Fingerprint();
|
std::string fingerprint = ssl_fingerprint->GetRfc4572Fingerprint();
|
||||||
|
|
||||||
talk_base::Buffer der_buffer;
|
talk_base::Buffer der_buffer;
|
||||||
|
@ -302,16 +302,24 @@ class StatsCollectorTest : public testing::Test {
|
|||||||
webrtc::StatsReport::kStatsReportTypeComponent,
|
webrtc::StatsReport::kStatsReportTypeComponent,
|
||||||
reports,
|
reports,
|
||||||
webrtc::StatsReport::kStatsValueNameLocalCertificateId);
|
webrtc::StatsReport::kStatsValueNameLocalCertificateId);
|
||||||
EXPECT_NE(kNotFound, local_certificate_id);
|
if (local_ders.size() > 0) {
|
||||||
CheckCertChainReports(reports, local_ders, local_certificate_id);
|
EXPECT_NE(kNotFound, local_certificate_id);
|
||||||
|
CheckCertChainReports(reports, local_ders, local_certificate_id);
|
||||||
|
} else {
|
||||||
|
EXPECT_EQ(kNotFound, local_certificate_id);
|
||||||
|
}
|
||||||
|
|
||||||
// Check remote certificate chain.
|
// Check remote certificate chain.
|
||||||
std::string remote_certificate_id = ExtractStatsValue(
|
std::string remote_certificate_id = ExtractStatsValue(
|
||||||
webrtc::StatsReport::kStatsReportTypeComponent,
|
webrtc::StatsReport::kStatsReportTypeComponent,
|
||||||
reports,
|
reports,
|
||||||
webrtc::StatsReport::kStatsValueNameRemoteCertificateId);
|
webrtc::StatsReport::kStatsValueNameRemoteCertificateId);
|
||||||
EXPECT_NE(kNotFound, remote_certificate_id);
|
if (remote_ders.size() > 0) {
|
||||||
CheckCertChainReports(reports, remote_ders, remote_certificate_id);
|
EXPECT_NE(kNotFound, remote_certificate_id);
|
||||||
|
CheckCertChainReports(reports, remote_ders, remote_certificate_id);
|
||||||
|
} else {
|
||||||
|
EXPECT_EQ(kNotFound, remote_certificate_id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cricket::FakeMediaEngine* media_engine_;
|
cricket::FakeMediaEngine* media_engine_;
|
||||||
@ -774,4 +782,21 @@ TEST_F(StatsCollectorTest, NoCertificates) {
|
|||||||
ASSERT_EQ(kNotFound, remote_certificate_id);
|
ASSERT_EQ(kNotFound, remote_certificate_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This test verifies that a remote certificate with an unsupported digest
|
||||||
|
// algorithm is correctly ignored.
|
||||||
|
TEST_F(StatsCollectorTest, UnsupportedDigestIgnored) {
|
||||||
|
// Build a local certificate.
|
||||||
|
std::string local_der = "This is the local der.";
|
||||||
|
talk_base::FakeSSLCertificate local_cert(DerToPem(local_der));
|
||||||
|
|
||||||
|
// Build a remote certificate with an unsupported digest algorithm.
|
||||||
|
std::string remote_der = "This is somebody else's der.";
|
||||||
|
talk_base::FakeSSLCertificate remote_cert(DerToPem(remote_der));
|
||||||
|
remote_cert.set_digest_algorithm("foobar");
|
||||||
|
|
||||||
|
TestCertificateReports(local_cert, std::vector<std::string>(1, local_der),
|
||||||
|
remote_cert, std::vector<std::string>());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -141,6 +141,7 @@ class StatsReport {
|
|||||||
static const char kStatsValueNameEchoDelayStdDev[];
|
static const char kStatsValueNameEchoDelayStdDev[];
|
||||||
static const char kStatsValueNameEchoReturnLoss[];
|
static const char kStatsValueNameEchoReturnLoss[];
|
||||||
static const char kStatsValueNameEchoReturnLossEnhancement[];
|
static const char kStatsValueNameEchoReturnLossEnhancement[];
|
||||||
|
static const char kStatsValueNameExpandRate[];
|
||||||
static const char kStatsValueNameFirsReceived[];
|
static const char kStatsValueNameFirsReceived[];
|
||||||
static const char kStatsValueNameFirsSent[];
|
static const char kStatsValueNameFirsSent[];
|
||||||
static const char kStatsValueNameFrameHeightInput[];
|
static const char kStatsValueNameFrameHeightInput[];
|
||||||
|
@ -31,6 +31,7 @@ if env.Bit('have_webrtc_voice') and env.Bit('have_webrtc_video'):
|
|||||||
'peerconnectionfactory.cc',
|
'peerconnectionfactory.cc',
|
||||||
'peerconnection.cc',
|
'peerconnection.cc',
|
||||||
'portallocatorfactory.cc',
|
'portallocatorfactory.cc',
|
||||||
|
'remoteaudiosource.cc',
|
||||||
'roapmessages.cc',
|
'roapmessages.cc',
|
||||||
'roapsession.cc',
|
'roapsession.cc',
|
||||||
'roapsignaling.cc',
|
'roapsignaling.cc',
|
||||||
|
@ -866,6 +866,18 @@ void WebRtcSession::SetAudioSend(uint32 ssrc, bool enable,
|
|||||||
voice_channel_->SetChannelOptions(options);
|
voice_channel_->SetChannelOptions(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WebRtcSession::SetAudioPlayoutVolume(uint32 ssrc, double volume) {
|
||||||
|
ASSERT(signaling_thread()->IsCurrent());
|
||||||
|
ASSERT(volume >= 0 && volume <= 10);
|
||||||
|
if (!voice_channel_) {
|
||||||
|
LOG(LS_ERROR) << "SetAudioPlayoutVolume: No audio channel exists.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!voice_channel_->SetOutputScaling(ssrc, volume, volume))
|
||||||
|
ASSERT(false);
|
||||||
|
}
|
||||||
|
|
||||||
bool WebRtcSession::SetCaptureDevice(uint32 ssrc,
|
bool WebRtcSession::SetCaptureDevice(uint32 ssrc,
|
||||||
cricket::VideoCapturer* camera) {
|
cricket::VideoCapturer* camera) {
|
||||||
ASSERT(signaling_thread()->IsCurrent());
|
ASSERT(signaling_thread()->IsCurrent());
|
||||||
|
@ -165,6 +165,7 @@ class WebRtcSession : public cricket::BaseSession,
|
|||||||
virtual void SetAudioSend(uint32 ssrc, bool enable,
|
virtual void SetAudioSend(uint32 ssrc, bool enable,
|
||||||
const cricket::AudioOptions& options,
|
const cricket::AudioOptions& options,
|
||||||
cricket::AudioRenderer* renderer) OVERRIDE;
|
cricket::AudioRenderer* renderer) OVERRIDE;
|
||||||
|
virtual void SetAudioPlayoutVolume(uint32 ssrc, double volume) OVERRIDE;
|
||||||
|
|
||||||
// Implements VideoMediaProviderInterface.
|
// Implements VideoMediaProviderInterface.
|
||||||
virtual bool SetCaptureDevice(uint32 ssrc,
|
virtual bool SetCaptureDevice(uint32 ssrc,
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#ifndef TALK_BASE_ASYNCPACKETSOCKET_H_
|
#ifndef TALK_BASE_ASYNCPACKETSOCKET_H_
|
||||||
#define TALK_BASE_ASYNCPACKETSOCKET_H_
|
#define TALK_BASE_ASYNCPACKETSOCKET_H_
|
||||||
|
|
||||||
|
#include "talk/base/buffer.h"
|
||||||
#include "talk/base/dscp.h"
|
#include "talk/base/dscp.h"
|
||||||
#include "talk/base/sigslot.h"
|
#include "talk/base/sigslot.h"
|
||||||
#include "talk/base/socket.h"
|
#include "talk/base/socket.h"
|
||||||
@ -35,6 +36,29 @@
|
|||||||
|
|
||||||
namespace talk_base {
|
namespace talk_base {
|
||||||
|
|
||||||
|
// This structure holds the info needed to update the packet send time header
|
||||||
|
// extension, including the information needed to update the authentication tag
|
||||||
|
// after changing the value.
|
||||||
|
struct PacketTimeUpdateParams {
|
||||||
|
PacketTimeUpdateParams()
|
||||||
|
: rtp_sendtime_extension_id(-1), srtp_auth_tag_len(-1),
|
||||||
|
srtp_packet_index(-1) {
|
||||||
|
}
|
||||||
|
|
||||||
|
int rtp_sendtime_extension_id; // extension header id present in packet.
|
||||||
|
Buffer srtp_auth_key; // Authentication key.
|
||||||
|
int srtp_auth_tag_len; // Authentication tag length.
|
||||||
|
int64 srtp_packet_index; // Required for Rtp Packet authentication.
|
||||||
|
};
|
||||||
|
|
||||||
|
// This structure holds meta information for the packet which is about to send
|
||||||
|
// over network.
|
||||||
|
struct PacketOptions {
|
||||||
|
PacketOptions() : dscp(DSCP_NO_CHANGE) {}
|
||||||
|
DiffServCodePoint dscp;
|
||||||
|
PacketTimeUpdateParams packet_time_params;
|
||||||
|
};
|
||||||
|
|
||||||
// This structure will have the information about when packet is actually
|
// This structure will have the information about when packet is actually
|
||||||
// received by socket.
|
// received by socket.
|
||||||
struct PacketTime {
|
struct PacketTime {
|
||||||
|
@ -109,10 +109,12 @@ class FakeNetworkManager : public NetworkManagerBase,
|
|||||||
prefix_length = kFakeIPv6NetworkPrefixLength;
|
prefix_length = kFakeIPv6NetworkPrefixLength;
|
||||||
}
|
}
|
||||||
IPAddress prefix = TruncateIP(it->ipaddr(), prefix_length);
|
IPAddress prefix = TruncateIP(it->ipaddr(), prefix_length);
|
||||||
|
std::string key = MakeNetworkKey(it->hostname(), prefix, prefix_length);
|
||||||
scoped_ptr<Network> net(new Network(it->hostname(),
|
scoped_ptr<Network> net(new Network(it->hostname(),
|
||||||
it->hostname(),
|
it->hostname(),
|
||||||
prefix,
|
prefix,
|
||||||
prefix_length));
|
prefix_length,
|
||||||
|
key));
|
||||||
net->AddIP(it->ipaddr());
|
net->AddIP(it->ipaddr());
|
||||||
networks.push_back(net.release());
|
networks.push_back(net.release());
|
||||||
}
|
}
|
||||||
|
@ -38,9 +38,12 @@ namespace talk_base {
|
|||||||
|
|
||||||
class FakeSSLCertificate : public talk_base::SSLCertificate {
|
class FakeSSLCertificate : public talk_base::SSLCertificate {
|
||||||
public:
|
public:
|
||||||
explicit FakeSSLCertificate(const std::string& data) : data_(data) {}
|
// SHA-1 is the default digest algorithm because it is available in all build
|
||||||
|
// configurations used for unit testing.
|
||||||
|
explicit FakeSSLCertificate(const std::string& data)
|
||||||
|
: data_(data), digest_algorithm_(DIGEST_SHA_1) {}
|
||||||
explicit FakeSSLCertificate(const std::vector<std::string>& certs)
|
explicit FakeSSLCertificate(const std::vector<std::string>& certs)
|
||||||
: data_(certs.front()) {
|
: data_(certs.front()), digest_algorithm_(DIGEST_SHA_1) {
|
||||||
std::vector<std::string>::const_iterator it;
|
std::vector<std::string>::const_iterator it;
|
||||||
// Skip certs[0].
|
// Skip certs[0].
|
||||||
for (it = certs.begin() + 1; it != certs.end(); ++it) {
|
for (it = certs.begin() + 1; it != certs.end(); ++it) {
|
||||||
@ -58,10 +61,11 @@ class FakeSSLCertificate : public talk_base::SSLCertificate {
|
|||||||
VERIFY(SSLIdentity::PemToDer(kPemTypeCertificate, data_, &der_string));
|
VERIFY(SSLIdentity::PemToDer(kPemTypeCertificate, data_, &der_string));
|
||||||
der_buffer->SetData(der_string.c_str(), der_string.size());
|
der_buffer->SetData(der_string.c_str(), der_string.size());
|
||||||
}
|
}
|
||||||
|
void set_digest_algorithm(const std::string& algorithm) {
|
||||||
|
digest_algorithm_ = algorithm;
|
||||||
|
}
|
||||||
virtual bool GetSignatureDigestAlgorithm(std::string* algorithm) const {
|
virtual bool GetSignatureDigestAlgorithm(std::string* algorithm) const {
|
||||||
// SHA-1 is chosen because it is available in all build configurations
|
*algorithm = digest_algorithm_;
|
||||||
// used for unit testing.
|
|
||||||
*algorithm = DIGEST_SHA_1;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
virtual bool ComputeDigest(const std::string &algorithm,
|
virtual bool ComputeDigest(const std::string &algorithm,
|
||||||
@ -86,6 +90,7 @@ class FakeSSLCertificate : public talk_base::SSLCertificate {
|
|||||||
}
|
}
|
||||||
std::string data_;
|
std::string data_;
|
||||||
std::vector<FakeSSLCertificate> certs_;
|
std::vector<FakeSSLCertificate> certs_;
|
||||||
|
std::string digest_algorithm_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FakeSSLIdentity : public talk_base::SSLIdentity {
|
class FakeSSLIdentity : public talk_base::SSLIdentity {
|
||||||
|
@ -79,16 +79,7 @@ const uint32 kSignalNetworksMessage = 2;
|
|||||||
// Fetch list of networks every two seconds.
|
// Fetch list of networks every two seconds.
|
||||||
const int kNetworksUpdateIntervalMs = 2000;
|
const int kNetworksUpdateIntervalMs = 2000;
|
||||||
|
|
||||||
|
const int kHighestNetworkPreference = 127;
|
||||||
// Makes a string key for this network. Used in the network manager's maps.
|
|
||||||
// Network objects are keyed on interface name, network prefix and the
|
|
||||||
// length of that prefix.
|
|
||||||
std::string MakeNetworkKey(const std::string& name, const IPAddress& prefix,
|
|
||||||
int prefix_length) {
|
|
||||||
std::ostringstream ost;
|
|
||||||
ost << name << "%" << prefix.ToString() << "/" << prefix_length;
|
|
||||||
return ost.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CompareNetworks(const Network* a, const Network* b) {
|
bool CompareNetworks(const Network* a, const Network* b) {
|
||||||
if (a->prefix_length() == b->prefix_length()) {
|
if (a->prefix_length() == b->prefix_length()) {
|
||||||
@ -99,9 +90,36 @@ bool CompareNetworks(const Network* a, const Network* b) {
|
|||||||
return a->name() < b->name();
|
return a->name() < b->name();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SortNetworks(const Network* a, const Network* b) {
|
||||||
|
// Network types will be preferred above everything else while sorting
|
||||||
|
// Networks.
|
||||||
|
|
||||||
|
// Networks are sorted first by type.
|
||||||
|
if (a->type() != b->type()) {
|
||||||
|
return a->type() < b->type();
|
||||||
|
}
|
||||||
|
|
||||||
|
// After type, networks are sorted by IP address precedence values
|
||||||
|
// from RFC 3484-bis
|
||||||
|
if (IPAddressPrecedence(a->ip()) != IPAddressPrecedence(b->ip())) {
|
||||||
|
return IPAddressPrecedence(a->ip()) > IPAddressPrecedence(b->ip());
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(mallinath) - Add VPN and Link speed conditions while sorting.
|
||||||
|
|
||||||
|
// Networks are sorted last by key.
|
||||||
|
return a->key() > b->key();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
std::string MakeNetworkKey(const std::string& name, const IPAddress& prefix,
|
||||||
|
int prefix_length) {
|
||||||
|
std::ostringstream ost;
|
||||||
|
ost << name << "%" << prefix.ToString() << "/" << prefix_length;
|
||||||
|
return ost.str();
|
||||||
|
}
|
||||||
|
|
||||||
NetworkManager::NetworkManager() {
|
NetworkManager::NetworkManager() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,6 +198,29 @@ void NetworkManagerBase::MergeNetworkList(const NetworkList& new_networks,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
networks_ = merged_list;
|
networks_ = merged_list;
|
||||||
|
|
||||||
|
// If the network lists changes, we resort it.
|
||||||
|
if (changed) {
|
||||||
|
std::sort(networks_.begin(), networks_.end(), SortNetworks);
|
||||||
|
// Now network interfaces are sorted, we should set the preference value
|
||||||
|
// for each of the interfaces we are planning to use.
|
||||||
|
// Preference order of network interfaces might have changed from previous
|
||||||
|
// sorting due to addition of higher preference network interface.
|
||||||
|
// Since we have already sorted the network interfaces based on our
|
||||||
|
// requirements, we will just assign a preference value starting with 127,
|
||||||
|
// in decreasing order.
|
||||||
|
int pref = kHighestNetworkPreference;
|
||||||
|
for (NetworkList::const_iterator iter = networks_.begin();
|
||||||
|
iter != networks_.end(); ++iter) {
|
||||||
|
(*iter)->set_preference(pref);
|
||||||
|
if (pref > 0) {
|
||||||
|
--pref;
|
||||||
|
} else {
|
||||||
|
LOG(LS_ERROR) << "Too many network interfaces to handle!";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BasicNetworkManager::BasicNetworkManager()
|
BasicNetworkManager::BasicNetworkManager()
|
||||||
@ -240,6 +281,7 @@ void BasicNetworkManager::ConvertIfAddrs(struct ifaddrs* interfaces,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int prefix_length = CountIPMaskBits(mask);
|
int prefix_length = CountIPMaskBits(mask);
|
||||||
prefix = TruncateIP(ip, prefix_length);
|
prefix = TruncateIP(ip, prefix_length);
|
||||||
std::string key = MakeNetworkKey(std::string(cursor->ifa_name),
|
std::string key = MakeNetworkKey(std::string(cursor->ifa_name),
|
||||||
@ -249,7 +291,8 @@ void BasicNetworkManager::ConvertIfAddrs(struct ifaddrs* interfaces,
|
|||||||
scoped_ptr<Network> network(new Network(cursor->ifa_name,
|
scoped_ptr<Network> network(new Network(cursor->ifa_name,
|
||||||
cursor->ifa_name,
|
cursor->ifa_name,
|
||||||
prefix,
|
prefix,
|
||||||
prefix_length));
|
prefix_length,
|
||||||
|
key));
|
||||||
network->set_scope_id(scope_id);
|
network->set_scope_id(scope_id);
|
||||||
network->AddIP(ip);
|
network->AddIP(ip);
|
||||||
bool ignored = ((cursor->ifa_flags & IFF_LOOPBACK) ||
|
bool ignored = ((cursor->ifa_flags & IFF_LOOPBACK) ||
|
||||||
@ -386,6 +429,7 @@ bool BasicNetworkManager::CreateNetworks(bool include_ignored,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IPAddress prefix;
|
IPAddress prefix;
|
||||||
int prefix_length = GetPrefix(prefixlist, ip, &prefix);
|
int prefix_length = GetPrefix(prefixlist, ip, &prefix);
|
||||||
std::string key = MakeNetworkKey(name, prefix, prefix_length);
|
std::string key = MakeNetworkKey(name, prefix, prefix_length);
|
||||||
@ -394,7 +438,8 @@ bool BasicNetworkManager::CreateNetworks(bool include_ignored,
|
|||||||
scoped_ptr<Network> network(new Network(name,
|
scoped_ptr<Network> network(new Network(name,
|
||||||
description,
|
description,
|
||||||
prefix,
|
prefix,
|
||||||
prefix_length));
|
prefix_length,
|
||||||
|
key));
|
||||||
network->set_scope_id(scope_id);
|
network->set_scope_id(scope_id);
|
||||||
network->AddIP(ip);
|
network->AddIP(ip);
|
||||||
bool ignore = ((adapter_addrs->IfType == IF_TYPE_SOFTWARE_LOOPBACK) ||
|
bool ignore = ((adapter_addrs->IfType == IF_TYPE_SOFTWARE_LOOPBACK) ||
|
||||||
@ -561,12 +606,21 @@ void BasicNetworkManager::DumpNetworks(bool include_ignored) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Network::Network(const std::string& name, const std::string& desc,
|
||||||
|
const IPAddress& prefix, int prefix_length,
|
||||||
|
const std::string& key)
|
||||||
|
: name_(name), description_(desc), prefix_(prefix),
|
||||||
|
prefix_length_(prefix_length), key_(key), scope_id_(0), ignored_(false),
|
||||||
|
uniform_numerator_(0), uniform_denominator_(0), exponential_numerator_(0),
|
||||||
|
exponential_denominator_(0), type_(ADAPTER_TYPE_UNKNOWN), preference_(0) {
|
||||||
|
}
|
||||||
|
|
||||||
Network::Network(const std::string& name, const std::string& desc,
|
Network::Network(const std::string& name, const std::string& desc,
|
||||||
const IPAddress& prefix, int prefix_length)
|
const IPAddress& prefix, int prefix_length)
|
||||||
: name_(name), description_(desc), prefix_(prefix),
|
: name_(name), description_(desc), prefix_(prefix),
|
||||||
prefix_length_(prefix_length), scope_id_(0), ignored_(false),
|
prefix_length_(prefix_length), scope_id_(0), ignored_(false),
|
||||||
uniform_numerator_(0), uniform_denominator_(0), exponential_numerator_(0),
|
uniform_numerator_(0), uniform_denominator_(0), exponential_numerator_(0),
|
||||||
exponential_denominator_(0) {
|
exponential_denominator_(0), type_(ADAPTER_TYPE_UNKNOWN), preference_(0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Network::ToString() const {
|
std::string Network::ToString() const {
|
||||||
@ -600,4 +654,5 @@ bool Network::SetIPs(const std::vector<IPAddress>& ips, bool changed) {
|
|||||||
ips_ = ips;
|
ips_ = ips;
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace talk_base
|
} // namespace talk_base
|
||||||
|
@ -45,9 +45,23 @@ struct ifaddrs;
|
|||||||
namespace talk_base {
|
namespace talk_base {
|
||||||
|
|
||||||
class Network;
|
class Network;
|
||||||
class NetworkSession;
|
|
||||||
class Thread;
|
class Thread;
|
||||||
|
|
||||||
|
enum AdapterType {
|
||||||
|
// This enum resembles the one in Chromium net::ConnectionType.
|
||||||
|
ADAPTER_TYPE_UNKNOWN = 0,
|
||||||
|
ADAPTER_TYPE_ETHERNET = 1,
|
||||||
|
ADAPTER_TYPE_WIFI = 2,
|
||||||
|
ADAPTER_TYPE_CELLULAR = 3,
|
||||||
|
ADAPTER_TYPE_VPN = 4
|
||||||
|
};
|
||||||
|
|
||||||
|
// Makes a string key for this network. Used in the network manager's maps.
|
||||||
|
// Network objects are keyed on interface name, network prefix and the
|
||||||
|
// length of that prefix.
|
||||||
|
std::string MakeNetworkKey(const std::string& name, const IPAddress& prefix,
|
||||||
|
int prefix_length);
|
||||||
|
|
||||||
// Generic network manager interface. It provides list of local
|
// Generic network manager interface. It provides list of local
|
||||||
// networks.
|
// networks.
|
||||||
class NetworkManager {
|
class NetworkManager {
|
||||||
@ -168,7 +182,12 @@ class BasicNetworkManager : public NetworkManagerBase,
|
|||||||
// Represents a Unix-type network interface, with a name and single address.
|
// Represents a Unix-type network interface, with a name and single address.
|
||||||
class Network {
|
class Network {
|
||||||
public:
|
public:
|
||||||
Network() : prefix_(INADDR_ANY), scope_id_(0) {}
|
Network() : prefix_(INADDR_ANY), scope_id_(0),
|
||||||
|
type_(ADAPTER_TYPE_UNKNOWN) {}
|
||||||
|
Network(const std::string& name, const std::string& description,
|
||||||
|
const IPAddress& prefix, int prefix_length,
|
||||||
|
const std::string& key);
|
||||||
|
|
||||||
Network(const std::string& name, const std::string& description,
|
Network(const std::string& name, const std::string& description,
|
||||||
const IPAddress& prefix, int prefix_length);
|
const IPAddress& prefix, int prefix_length);
|
||||||
|
|
||||||
@ -184,6 +203,10 @@ class Network {
|
|||||||
// Returns the length, in bits, of this network's prefix.
|
// Returns the length, in bits, of this network's prefix.
|
||||||
int prefix_length() const { return prefix_length_; }
|
int prefix_length() const { return prefix_length_; }
|
||||||
|
|
||||||
|
// |key_| has unique value per network interface. Used in sorting network
|
||||||
|
// interfaces. Key is derived from interface name and it's prefix.
|
||||||
|
std::string key() const { return key_; }
|
||||||
|
|
||||||
// Returns the Network's current idea of the 'best' IP it has.
|
// Returns the Network's current idea of the 'best' IP it has.
|
||||||
// 'Best' currently means the first one added.
|
// 'Best' currently means the first one added.
|
||||||
// TODO: We should be preferring temporary addresses.
|
// TODO: We should be preferring temporary addresses.
|
||||||
@ -215,27 +238,32 @@ class Network {
|
|||||||
bool ignored() const { return ignored_; }
|
bool ignored() const { return ignored_; }
|
||||||
void set_ignored(bool ignored) { ignored_ = ignored; }
|
void set_ignored(bool ignored) { ignored_ = ignored; }
|
||||||
|
|
||||||
|
AdapterType type() const { return type_; }
|
||||||
|
int preference() const { return preference_; }
|
||||||
|
void set_preference(int preference) { preference_ = preference; }
|
||||||
|
|
||||||
// Debugging description of this network
|
// Debugging description of this network
|
||||||
std::string ToString() const;
|
std::string ToString() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef std::vector<NetworkSession*> SessionList;
|
|
||||||
|
|
||||||
std::string name_;
|
std::string name_;
|
||||||
std::string description_;
|
std::string description_;
|
||||||
IPAddress prefix_;
|
IPAddress prefix_;
|
||||||
int prefix_length_;
|
int prefix_length_;
|
||||||
|
std::string key_;
|
||||||
std::vector<IPAddress> ips_;
|
std::vector<IPAddress> ips_;
|
||||||
int scope_id_;
|
int scope_id_;
|
||||||
bool ignored_;
|
bool ignored_;
|
||||||
SessionList sessions_;
|
|
||||||
double uniform_numerator_;
|
double uniform_numerator_;
|
||||||
double uniform_denominator_;
|
double uniform_denominator_;
|
||||||
double exponential_numerator_;
|
double exponential_numerator_;
|
||||||
double exponential_denominator_;
|
double exponential_denominator_;
|
||||||
|
AdapterType type_;
|
||||||
|
int preference_;
|
||||||
|
|
||||||
friend class NetworkManager;
|
friend class NetworkManager;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace talk_base
|
} // namespace talk_base
|
||||||
|
|
||||||
#endif // TALK_BASE_NETWORK_H_
|
#endif // TALK_BASE_NETWORK_H_
|
||||||
|
@ -527,6 +527,33 @@ TEST_F(NetworkTest, TestIPv6Toggle) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(NetworkTest, TestNetworkListSorting) {
|
||||||
|
BasicNetworkManager manager;
|
||||||
|
Network ipv4_network1("test_eth0", "Test Network Adapter 1",
|
||||||
|
IPAddress(0x12345600U), 24);
|
||||||
|
ipv4_network1.AddIP(IPAddress(0x12345600U));
|
||||||
|
|
||||||
|
IPAddress ip;
|
||||||
|
IPAddress prefix;
|
||||||
|
EXPECT_TRUE(IPFromString("2400:4030:1:2c00:be30:abcd:efab:cdef", &ip));
|
||||||
|
prefix = TruncateIP(ip, 64);
|
||||||
|
Network ipv6_eth1_publicnetwork1_ip1("test_eth1", "Test NetworkAdapter 2",
|
||||||
|
prefix, 64);
|
||||||
|
ipv6_eth1_publicnetwork1_ip1.AddIP(ip);
|
||||||
|
|
||||||
|
NetworkManager::NetworkList list;
|
||||||
|
list.push_back(new Network(ipv4_network1));
|
||||||
|
list.push_back(new Network(ipv6_eth1_publicnetwork1_ip1));
|
||||||
|
Network* net1 = list[0];
|
||||||
|
Network* net2 = list[1];
|
||||||
|
|
||||||
|
bool changed = false;
|
||||||
|
MergeNetworkList(manager, list, &changed);
|
||||||
|
ASSERT_TRUE(changed);
|
||||||
|
// After sorting IPv6 network should be higher order than IPv4 networks.
|
||||||
|
EXPECT_TRUE(net1->preference() < net2->preference());
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(POSIX)
|
#if defined(POSIX)
|
||||||
// Verify that we correctly handle interfaces with no address.
|
// Verify that we correctly handle interfaces with no address.
|
||||||
TEST_F(NetworkTest, TestConvertIfAddrsNoAddress) {
|
TEST_F(NetworkTest, TestConvertIfAddrsNoAddress) {
|
||||||
|
37
talk/base/openssl.h
Normal file
37
talk/base/openssl.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* libjingle
|
||||||
|
* Copyright 2013, Google Inc.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||||
|
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||||
|
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||||
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef TALK_BASE_OPENSSL_H_
|
||||||
|
#define TALK_BASE_OPENSSL_H_
|
||||||
|
|
||||||
|
#include <openssl/ssl.h>
|
||||||
|
|
||||||
|
#if (OPENSSL_VERSION_NUMBER < 0x10001000L)
|
||||||
|
#error OpenSSL is older than 1.0.1, which is the minimum supported version.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // TALK_BASE_OPENSSL_H_
|
@ -41,7 +41,6 @@
|
|||||||
#include <openssl/err.h>
|
#include <openssl/err.h>
|
||||||
#include <openssl/opensslv.h>
|
#include <openssl/opensslv.h>
|
||||||
#include <openssl/rand.h>
|
#include <openssl/rand.h>
|
||||||
#include <openssl/ssl.h>
|
|
||||||
#include <openssl/x509v3.h>
|
#include <openssl/x509v3.h>
|
||||||
|
|
||||||
#if HAVE_CONFIG_H
|
#if HAVE_CONFIG_H
|
||||||
@ -50,6 +49,7 @@
|
|||||||
|
|
||||||
#include "talk/base/common.h"
|
#include "talk/base/common.h"
|
||||||
#include "talk/base/logging.h"
|
#include "talk/base/logging.h"
|
||||||
|
#include "talk/base/openssl.h"
|
||||||
#include "talk/base/sslroots.h"
|
#include "talk/base/sslroots.h"
|
||||||
#include "talk/base/stringutils.h"
|
#include "talk/base/stringutils.h"
|
||||||
|
|
||||||
@ -688,11 +688,7 @@ bool OpenSSLAdapter::VerifyServerName(SSL* ssl, const char* host,
|
|||||||
int extension_nid = OBJ_obj2nid(X509_EXTENSION_get_object(extension));
|
int extension_nid = OBJ_obj2nid(X509_EXTENSION_get_object(extension));
|
||||||
|
|
||||||
if (extension_nid == NID_subject_alt_name) {
|
if (extension_nid == NID_subject_alt_name) {
|
||||||
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
|
|
||||||
const X509V3_EXT_METHOD* meth = X509V3_EXT_get(extension);
|
const X509V3_EXT_METHOD* meth = X509V3_EXT_get(extension);
|
||||||
#else
|
|
||||||
X509V3_EXT_METHOD* meth = X509V3_EXT_get(extension);
|
|
||||||
#endif
|
|
||||||
if (!meth)
|
if (!meth)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -703,12 +699,8 @@ bool OpenSSLAdapter::VerifyServerName(SSL* ssl, const char* host,
|
|||||||
// See http://readlist.com/lists/openssl.org/openssl-users/0/4761.html.
|
// See http://readlist.com/lists/openssl.org/openssl-users/0/4761.html.
|
||||||
unsigned char* ext_value_data = extension->value->data;
|
unsigned char* ext_value_data = extension->value->data;
|
||||||
|
|
||||||
#if OPENSSL_VERSION_NUMBER >= 0x0090800fL
|
|
||||||
const unsigned char **ext_value_data_ptr =
|
const unsigned char **ext_value_data_ptr =
|
||||||
(const_cast<const unsigned char **>(&ext_value_data));
|
(const_cast<const unsigned char **>(&ext_value_data));
|
||||||
#else
|
|
||||||
unsigned char **ext_value_data_ptr = &ext_value_data;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (meth->it) {
|
if (meth->it) {
|
||||||
ext_str = ASN1_item_d2i(NULL, ext_value_data_ptr,
|
ext_str = ASN1_item_d2i(NULL, ext_value_data_ptr,
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#include "talk/base/openssldigest.h"
|
#include "talk/base/openssldigest.h"
|
||||||
|
|
||||||
#include "talk/base/common.h"
|
#include "talk/base/common.h"
|
||||||
|
#include "talk/base/openssl.h"
|
||||||
|
|
||||||
namespace talk_base {
|
namespace talk_base {
|
||||||
|
|
||||||
@ -78,7 +79,6 @@ bool OpenSSLDigest::GetDigestEVP(const std::string& algorithm,
|
|||||||
md = EVP_md5();
|
md = EVP_md5();
|
||||||
} else if (algorithm == DIGEST_SHA_1) {
|
} else if (algorithm == DIGEST_SHA_1) {
|
||||||
md = EVP_sha1();
|
md = EVP_sha1();
|
||||||
#if OPENSSL_VERSION_NUMBER >= 0x00908000L
|
|
||||||
} else if (algorithm == DIGEST_SHA_224) {
|
} else if (algorithm == DIGEST_SHA_224) {
|
||||||
md = EVP_sha224();
|
md = EVP_sha224();
|
||||||
} else if (algorithm == DIGEST_SHA_256) {
|
} else if (algorithm == DIGEST_SHA_256) {
|
||||||
@ -87,7 +87,6 @@ bool OpenSSLDigest::GetDigestEVP(const std::string& algorithm,
|
|||||||
md = EVP_sha384();
|
md = EVP_sha384();
|
||||||
} else if (algorithm == DIGEST_SHA_512) {
|
} else if (algorithm == DIGEST_SHA_512) {
|
||||||
md = EVP_sha512();
|
md = EVP_sha512();
|
||||||
#endif
|
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -108,7 +107,6 @@ bool OpenSSLDigest::GetDigestName(const EVP_MD* md,
|
|||||||
*algorithm = DIGEST_MD5;
|
*algorithm = DIGEST_MD5;
|
||||||
} else if (md_type == NID_sha1) {
|
} else if (md_type == NID_sha1) {
|
||||||
*algorithm = DIGEST_SHA_1;
|
*algorithm = DIGEST_SHA_1;
|
||||||
#if OPENSSL_VERSION_NUMBER >= 0x00908000L
|
|
||||||
} else if (md_type == NID_sha224) {
|
} else if (md_type == NID_sha224) {
|
||||||
*algorithm = DIGEST_SHA_224;
|
*algorithm = DIGEST_SHA_224;
|
||||||
} else if (md_type == NID_sha256) {
|
} else if (md_type == NID_sha256) {
|
||||||
@ -117,7 +115,6 @@ bool OpenSSLDigest::GetDigestName(const EVP_MD* md,
|
|||||||
*algorithm = DIGEST_SHA_384;
|
*algorithm = DIGEST_SHA_384;
|
||||||
} else if (md_type == NID_sha512) {
|
} else if (md_type == NID_sha512) {
|
||||||
*algorithm = DIGEST_SHA_512;
|
*algorithm = DIGEST_SHA_512;
|
||||||
#endif
|
|
||||||
} else {
|
} else {
|
||||||
algorithm->clear();
|
algorithm->clear();
|
||||||
return false;
|
return false;
|
||||||
|
@ -32,7 +32,6 @@
|
|||||||
// Must be included first before openssl headers.
|
// Must be included first before openssl headers.
|
||||||
#include "talk/base/win32.h" // NOLINT
|
#include "talk/base/win32.h" // NOLINT
|
||||||
|
|
||||||
#include <openssl/ssl.h>
|
|
||||||
#include <openssl/bio.h>
|
#include <openssl/bio.h>
|
||||||
#include <openssl/err.h>
|
#include <openssl/err.h>
|
||||||
#include <openssl/pem.h>
|
#include <openssl/pem.h>
|
||||||
@ -43,6 +42,7 @@
|
|||||||
#include "talk/base/checks.h"
|
#include "talk/base/checks.h"
|
||||||
#include "talk/base/helpers.h"
|
#include "talk/base/helpers.h"
|
||||||
#include "talk/base/logging.h"
|
#include "talk/base/logging.h"
|
||||||
|
#include "talk/base/openssl.h"
|
||||||
#include "talk/base/openssldigest.h"
|
#include "talk/base/openssldigest.h"
|
||||||
|
|
||||||
namespace talk_base {
|
namespace talk_base {
|
||||||
@ -66,15 +66,6 @@ static const int CERTIFICATE_WINDOW = -60*60*24;
|
|||||||
static EVP_PKEY* MakeKey() {
|
static EVP_PKEY* MakeKey() {
|
||||||
LOG(LS_INFO) << "Making key pair";
|
LOG(LS_INFO) << "Making key pair";
|
||||||
EVP_PKEY* pkey = EVP_PKEY_new();
|
EVP_PKEY* pkey = EVP_PKEY_new();
|
||||||
#if OPENSSL_VERSION_NUMBER < 0x00908000l
|
|
||||||
// Only RSA_generate_key is available. Use that.
|
|
||||||
RSA* rsa = RSA_generate_key(KEY_LENGTH, 0x10001, NULL, NULL);
|
|
||||||
if (!EVP_PKEY_assign_RSA(pkey, rsa)) {
|
|
||||||
EVP_PKEY_free(pkey);
|
|
||||||
RSA_free(rsa);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
// RSA_generate_key is deprecated. Use _ex version.
|
// RSA_generate_key is deprecated. Use _ex version.
|
||||||
BIGNUM* exponent = BN_new();
|
BIGNUM* exponent = BN_new();
|
||||||
RSA* rsa = RSA_new();
|
RSA* rsa = RSA_new();
|
||||||
@ -89,7 +80,6 @@ static EVP_PKEY* MakeKey() {
|
|||||||
}
|
}
|
||||||
// ownership of rsa struct was assigned, don't free it.
|
// ownership of rsa struct was assigned, don't free it.
|
||||||
BN_free(exponent);
|
BN_free(exponent);
|
||||||
#endif
|
|
||||||
LOG(LS_INFO) << "Returning key pair";
|
LOG(LS_INFO) << "Returning key pair";
|
||||||
return pkey;
|
return pkey;
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,6 @@
|
|||||||
#include <openssl/crypto.h>
|
#include <openssl/crypto.h>
|
||||||
#include <openssl/err.h>
|
#include <openssl/err.h>
|
||||||
#include <openssl/rand.h>
|
#include <openssl/rand.h>
|
||||||
#include <openssl/ssl.h>
|
|
||||||
#include <openssl/x509v3.h>
|
#include <openssl/x509v3.h>
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -45,6 +44,7 @@
|
|||||||
#include "talk/base/common.h"
|
#include "talk/base/common.h"
|
||||||
#include "talk/base/logging.h"
|
#include "talk/base/logging.h"
|
||||||
#include "talk/base/stream.h"
|
#include "talk/base/stream.h"
|
||||||
|
#include "talk/base/openssl.h"
|
||||||
#include "talk/base/openssladapter.h"
|
#include "talk/base/openssladapter.h"
|
||||||
#include "talk/base/openssldigest.h"
|
#include "talk/base/openssldigest.h"
|
||||||
#include "talk/base/opensslidentity.h"
|
#include "talk/base/opensslidentity.h"
|
||||||
@ -53,15 +53,6 @@
|
|||||||
|
|
||||||
namespace talk_base {
|
namespace talk_base {
|
||||||
|
|
||||||
#if (OPENSSL_VERSION_NUMBER >= 0x10001000L)
|
|
||||||
#define HAVE_DTLS_SRTP
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if (OPENSSL_VERSION_NUMBER >= 0x10000000L)
|
|
||||||
#define HAVE_DTLS
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_DTLS_SRTP
|
|
||||||
// SRTP cipher suite table
|
// SRTP cipher suite table
|
||||||
struct SrtpCipherMapEntry {
|
struct SrtpCipherMapEntry {
|
||||||
const char* external_name;
|
const char* external_name;
|
||||||
@ -74,7 +65,6 @@ static SrtpCipherMapEntry SrtpCipherMap[] = {
|
|||||||
{"AES_CM_128_HMAC_SHA1_32", "SRTP_AES128_CM_SHA1_32"},
|
{"AES_CM_128_HMAC_SHA1_32", "SRTP_AES128_CM_SHA1_32"},
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// StreamBIO
|
// StreamBIO
|
||||||
@ -248,7 +238,6 @@ bool OpenSSLStreamAdapter::ExportKeyingMaterial(const std::string& label,
|
|||||||
bool use_context,
|
bool use_context,
|
||||||
uint8* result,
|
uint8* result,
|
||||||
size_t result_len) {
|
size_t result_len) {
|
||||||
#ifdef HAVE_DTLS_SRTP
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
i = SSL_export_keying_material(ssl_, result, result_len,
|
i = SSL_export_keying_material(ssl_, result, result_len,
|
||||||
@ -260,9 +249,6 @@ bool OpenSSLStreamAdapter::ExportKeyingMaterial(const std::string& label,
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
#else
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OpenSSLStreamAdapter::SetDtlsSrtpCiphers(
|
bool OpenSSLStreamAdapter::SetDtlsSrtpCiphers(
|
||||||
@ -272,7 +258,6 @@ bool OpenSSLStreamAdapter::SetDtlsSrtpCiphers(
|
|||||||
if (state_ != SSL_NONE)
|
if (state_ != SSL_NONE)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
#ifdef HAVE_DTLS_SRTP
|
|
||||||
for (std::vector<std::string>::const_iterator cipher = ciphers.begin();
|
for (std::vector<std::string>::const_iterator cipher = ciphers.begin();
|
||||||
cipher != ciphers.end(); ++cipher) {
|
cipher != ciphers.end(); ++cipher) {
|
||||||
bool found = false;
|
bool found = false;
|
||||||
@ -298,13 +283,9 @@ bool OpenSSLStreamAdapter::SetDtlsSrtpCiphers(
|
|||||||
|
|
||||||
srtp_ciphers_ = internal_ciphers;
|
srtp_ciphers_ = internal_ciphers;
|
||||||
return true;
|
return true;
|
||||||
#else
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OpenSSLStreamAdapter::GetDtlsSrtpCipher(std::string* cipher) {
|
bool OpenSSLStreamAdapter::GetDtlsSrtpCipher(std::string* cipher) {
|
||||||
#ifdef HAVE_DTLS_SRTP
|
|
||||||
ASSERT(state_ == SSL_CONNECTED);
|
ASSERT(state_ == SSL_CONNECTED);
|
||||||
if (state_ != SSL_CONNECTED)
|
if (state_ != SSL_CONNECTED)
|
||||||
return false;
|
return false;
|
||||||
@ -326,9 +307,6 @@ bool OpenSSLStreamAdapter::GetDtlsSrtpCipher(std::string* cipher) {
|
|||||||
ASSERT(false); // This should never happen
|
ASSERT(false); // This should never happen
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
#else
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int OpenSSLStreamAdapter::StartSSLWithServer(const char* server_name) {
|
int OpenSSLStreamAdapter::StartSSLWithServer(const char* server_name) {
|
||||||
@ -665,14 +643,12 @@ int OpenSSLStreamAdapter::ContinueSSL() {
|
|||||||
|
|
||||||
case SSL_ERROR_WANT_READ: {
|
case SSL_ERROR_WANT_READ: {
|
||||||
LOG(LS_VERBOSE) << " -- error want read";
|
LOG(LS_VERBOSE) << " -- error want read";
|
||||||
#ifdef HAVE_DTLS
|
|
||||||
struct timeval timeout;
|
struct timeval timeout;
|
||||||
if (DTLSv1_get_timeout(ssl_, &timeout)) {
|
if (DTLSv1_get_timeout(ssl_, &timeout)) {
|
||||||
int delay = timeout.tv_sec * 1000 + timeout.tv_usec/1000;
|
int delay = timeout.tv_sec * 1000 + timeout.tv_usec/1000;
|
||||||
|
|
||||||
Thread::Current()->PostDelayed(delay, this, MSG_TIMEOUT, 0);
|
Thread::Current()->PostDelayed(delay, this, MSG_TIMEOUT, 0);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -727,9 +703,7 @@ void OpenSSLStreamAdapter::OnMessage(Message* msg) {
|
|||||||
// Process our own messages and then pass others to the superclass
|
// Process our own messages and then pass others to the superclass
|
||||||
if (MSG_TIMEOUT == msg->message_id) {
|
if (MSG_TIMEOUT == msg->message_id) {
|
||||||
LOG(LS_INFO) << "DTLS timeout expired";
|
LOG(LS_INFO) << "DTLS timeout expired";
|
||||||
#ifdef HAVE_DTLS
|
|
||||||
DTLSv1_handle_timeout(ssl_);
|
DTLSv1_handle_timeout(ssl_);
|
||||||
#endif
|
|
||||||
ContinueSSL();
|
ContinueSSL();
|
||||||
} else {
|
} else {
|
||||||
StreamInterface::OnMessage(msg);
|
StreamInterface::OnMessage(msg);
|
||||||
@ -740,19 +714,11 @@ SSL_CTX* OpenSSLStreamAdapter::SetupSSLContext() {
|
|||||||
SSL_CTX *ctx = NULL;
|
SSL_CTX *ctx = NULL;
|
||||||
|
|
||||||
if (role_ == SSL_CLIENT) {
|
if (role_ == SSL_CLIENT) {
|
||||||
#ifdef HAVE_DTLS
|
|
||||||
ctx = SSL_CTX_new(ssl_mode_ == SSL_MODE_DTLS ?
|
ctx = SSL_CTX_new(ssl_mode_ == SSL_MODE_DTLS ?
|
||||||
DTLSv1_client_method() : TLSv1_client_method());
|
DTLSv1_client_method() : TLSv1_client_method());
|
||||||
#else
|
|
||||||
ctx = SSL_CTX_new(TLSv1_client_method());
|
|
||||||
#endif
|
|
||||||
} else {
|
} else {
|
||||||
#ifdef HAVE_DTLS
|
|
||||||
ctx = SSL_CTX_new(ssl_mode_ == SSL_MODE_DTLS ?
|
ctx = SSL_CTX_new(ssl_mode_ == SSL_MODE_DTLS ?
|
||||||
DTLSv1_server_method() : TLSv1_server_method());
|
DTLSv1_server_method() : TLSv1_server_method());
|
||||||
#else
|
|
||||||
ctx = SSL_CTX_new(TLSv1_server_method());
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
if (ctx == NULL)
|
if (ctx == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -771,14 +737,12 @@ SSL_CTX* OpenSSLStreamAdapter::SetupSSLContext() {
|
|||||||
SSL_CTX_set_verify_depth(ctx, 4);
|
SSL_CTX_set_verify_depth(ctx, 4);
|
||||||
SSL_CTX_set_cipher_list(ctx, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
|
SSL_CTX_set_cipher_list(ctx, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
|
||||||
|
|
||||||
#ifdef HAVE_DTLS_SRTP
|
|
||||||
if (!srtp_ciphers_.empty()) {
|
if (!srtp_ciphers_.empty()) {
|
||||||
if (SSL_CTX_set_tlsext_use_srtp(ctx, srtp_ciphers_.c_str())) {
|
if (SSL_CTX_set_tlsext_use_srtp(ctx, srtp_ciphers_.c_str())) {
|
||||||
SSL_CTX_free(ctx);
|
SSL_CTX_free(ctx);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
@ -852,27 +816,15 @@ bool OpenSSLStreamAdapter::SSLPostConnectionCheck(SSL* ssl,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool OpenSSLStreamAdapter::HaveDtls() {
|
bool OpenSSLStreamAdapter::HaveDtls() {
|
||||||
#ifdef HAVE_DTLS
|
|
||||||
return true;
|
return true;
|
||||||
#else
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OpenSSLStreamAdapter::HaveDtlsSrtp() {
|
bool OpenSSLStreamAdapter::HaveDtlsSrtp() {
|
||||||
#ifdef HAVE_DTLS_SRTP
|
|
||||||
return true;
|
return true;
|
||||||
#else
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OpenSSLStreamAdapter::HaveExporter() {
|
bool OpenSSLStreamAdapter::HaveExporter() {
|
||||||
#ifdef HAVE_DTLS_SRTP
|
|
||||||
return true;
|
return true;
|
||||||
#else
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace talk_base
|
} // namespace talk_base
|
||||||
|
@ -541,6 +541,8 @@ class PhysicalSocket : public AsyncSocket, public sigslot::has_slots<> {
|
|||||||
case OPT_DSCP:
|
case OPT_DSCP:
|
||||||
LOG(LS_WARNING) << "Socket::OPT_DSCP not supported.";
|
LOG(LS_WARNING) << "Socket::OPT_DSCP not supported.";
|
||||||
return -1;
|
return -1;
|
||||||
|
case OPT_RTP_SENDTIME_EXTN_ID:
|
||||||
|
return -1; // No logging is necessary as this not a OS socket option.
|
||||||
default:
|
default:
|
||||||
ASSERT(false);
|
ASSERT(false);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -185,7 +185,10 @@ class Socket {
|
|||||||
OPT_SNDBUF, // send buffer size
|
OPT_SNDBUF, // send buffer size
|
||||||
OPT_NODELAY, // whether Nagle algorithm is enabled
|
OPT_NODELAY, // whether Nagle algorithm is enabled
|
||||||
OPT_IPV6_V6ONLY, // Whether the socket is IPv6 only.
|
OPT_IPV6_V6ONLY, // Whether the socket is IPv6 only.
|
||||||
OPT_DSCP // DSCP code
|
OPT_DSCP, // DSCP code
|
||||||
|
OPT_RTP_SENDTIME_EXTN_ID, // This is a non-traditional socket option param.
|
||||||
|
// This is specific to libjingle and will be used
|
||||||
|
// if SendTime option is needed at socket level.
|
||||||
};
|
};
|
||||||
virtual int GetOption(Option opt, int* value) = 0;
|
virtual int GetOption(Option opt, int* value) = 0;
|
||||||
virtual int SetOption(Option opt, int value) = 0;
|
virtual int SetOption(Option opt, int value) = 0;
|
||||||
|
@ -339,7 +339,7 @@ class AsyncInvokeTest : public testing::Test {
|
|||||||
Thread* expected_thread_;
|
Thread* expected_thread_;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(AsyncInvokeTest, FireAndForget) {
|
TEST_F(AsyncInvokeTest, DISABLED_FireAndForget) {
|
||||||
AsyncInvoker invoker;
|
AsyncInvoker invoker;
|
||||||
// Create and start the thread.
|
// Create and start the thread.
|
||||||
Thread thread;
|
Thread thread;
|
||||||
@ -350,7 +350,7 @@ TEST_F(AsyncInvokeTest, FireAndForget) {
|
|||||||
EXPECT_TRUE_WAIT(called, kWaitTimeout);
|
EXPECT_TRUE_WAIT(called, kWaitTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(AsyncInvokeTest, WithCallback) {
|
TEST_F(AsyncInvokeTest, DISABLED_WithCallback) {
|
||||||
AsyncInvoker invoker;
|
AsyncInvoker invoker;
|
||||||
// Create and start the thread.
|
// Create and start the thread.
|
||||||
Thread thread;
|
Thread thread;
|
||||||
@ -379,7 +379,7 @@ TEST_F(AsyncInvokeTest, DISABLED_CancelInvoker) {
|
|||||||
EXPECT_EQ(0, int_value_);
|
EXPECT_EQ(0, int_value_);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(AsyncInvokeTest, CancelCallingThread) {
|
TEST_F(AsyncInvokeTest, DISABLED_CancelCallingThread) {
|
||||||
AsyncInvoker invoker;
|
AsyncInvoker invoker;
|
||||||
{ // Create and start the thread.
|
{ // Create and start the thread.
|
||||||
Thread thread;
|
Thread thread;
|
||||||
@ -396,7 +396,7 @@ TEST_F(AsyncInvokeTest, CancelCallingThread) {
|
|||||||
EXPECT_EQ(0, int_value_);
|
EXPECT_EQ(0, int_value_);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(AsyncInvokeTest, KillInvokerBeforeExecute) {
|
TEST_F(AsyncInvokeTest, DISABLED_KillInvokerBeforeExecute) {
|
||||||
Thread thread;
|
Thread thread;
|
||||||
thread.Start();
|
thread.Start();
|
||||||
{
|
{
|
||||||
@ -413,7 +413,7 @@ TEST_F(AsyncInvokeTest, KillInvokerBeforeExecute) {
|
|||||||
EXPECT_EQ(0, int_value_);
|
EXPECT_EQ(0, int_value_);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(AsyncInvokeTest, Flush) {
|
TEST_F(AsyncInvokeTest, DISABLED_Flush) {
|
||||||
AsyncInvoker invoker;
|
AsyncInvoker invoker;
|
||||||
bool flag1 = false;
|
bool flag1 = false;
|
||||||
bool flag2 = false;
|
bool flag2 = false;
|
||||||
@ -431,7 +431,7 @@ TEST_F(AsyncInvokeTest, Flush) {
|
|||||||
EXPECT_TRUE(flag2);
|
EXPECT_TRUE(flag2);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(AsyncInvokeTest, FlushWithIds) {
|
TEST_F(AsyncInvokeTest, DISABLED_FlushWithIds) {
|
||||||
AsyncInvoker invoker;
|
AsyncInvoker invoker;
|
||||||
bool flag1 = false;
|
bool flag1 = false;
|
||||||
bool flag2 = false;
|
bool flag2 = false;
|
||||||
|
@ -715,6 +715,7 @@
|
|||||||
'conditions': [
|
'conditions': [
|
||||||
['OS!="ios"', {
|
['OS!="ios"', {
|
||||||
'sources': [
|
'sources': [
|
||||||
|
'base/openssl.h',
|
||||||
'base/openssladapter.cc',
|
'base/openssladapter.cc',
|
||||||
'base/openssladapter.h',
|
'base/openssladapter.h',
|
||||||
'base/openssldigest.cc',
|
'base/openssldigest.cc',
|
||||||
@ -1175,6 +1176,8 @@
|
|||||||
'app/webrtc/portallocatorfactory.cc',
|
'app/webrtc/portallocatorfactory.cc',
|
||||||
'app/webrtc/portallocatorfactory.h',
|
'app/webrtc/portallocatorfactory.h',
|
||||||
'app/webrtc/proxy.h',
|
'app/webrtc/proxy.h',
|
||||||
|
'app/webrtc/remoteaudiosource.cc',
|
||||||
|
'app/webrtc/remoteaudiosource.h',
|
||||||
'app/webrtc/remotevideocapturer.cc',
|
'app/webrtc/remotevideocapturer.cc',
|
||||||
'app/webrtc/remotevideocapturer.h',
|
'app/webrtc/remotevideocapturer.h',
|
||||||
'app/webrtc/sctputils.cc',
|
'app/webrtc/sctputils.cc',
|
||||||
|
@ -183,7 +183,8 @@ void VideoAdapter::SetInputFormat(const VideoFormat& format) {
|
|||||||
output_format_.interval = talk_base::_max(
|
output_format_.interval = talk_base::_max(
|
||||||
output_format_.interval, input_format_.interval);
|
output_format_.interval, input_format_.interval);
|
||||||
if (old_input_interval != input_format_.interval) {
|
if (old_input_interval != input_format_.interval) {
|
||||||
LOG(LS_INFO) << "VAdapt Input Interval: " << input_format_.interval;
|
LOG(LS_INFO) << "VAdapt input interval changed from "
|
||||||
|
<< old_input_interval << " to " << input_format_.interval;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -218,7 +219,8 @@ void VideoAdapter::SetOutputFormat(const VideoFormat& format) {
|
|||||||
output_format_.interval = talk_base::_max(
|
output_format_.interval = talk_base::_max(
|
||||||
output_format_.interval, input_format_.interval);
|
output_format_.interval, input_format_.interval);
|
||||||
if (old_output_interval != output_format_.interval) {
|
if (old_output_interval != output_format_.interval) {
|
||||||
LOG(LS_INFO) << "VAdapt Output Interval: " << output_format_.interval;
|
LOG(LS_INFO) << "VAdapt output interval changed from "
|
||||||
|
<< old_output_interval << " to " << output_format_.interval;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -283,16 +285,12 @@ bool VideoAdapter::AdaptFrame(const VideoFrame* in_frame,
|
|||||||
}
|
}
|
||||||
if (should_drop) {
|
if (should_drop) {
|
||||||
// Show VAdapt log every 90 frames dropped. (3 seconds)
|
// Show VAdapt log every 90 frames dropped. (3 seconds)
|
||||||
// TODO(fbarchard): Consider GetLogSeverity() to change interval to less
|
if ((frames_in_ - frames_out_) % 90 == 0) {
|
||||||
// for LS_VERBOSE and more for LS_INFO.
|
|
||||||
bool show = (frames_in_ - frames_out_) % 90 == 0;
|
|
||||||
|
|
||||||
if (show) {
|
|
||||||
// TODO(fbarchard): Reduce to LS_VERBOSE when adapter info is not needed
|
// TODO(fbarchard): Reduce to LS_VERBOSE when adapter info is not needed
|
||||||
// in default calls.
|
// in default calls.
|
||||||
LOG(LS_INFO) << "VAdapt Drop Frame: " << frames_scaled_
|
LOG(LS_INFO) << "VAdapt Drop Frame: scaled " << frames_scaled_
|
||||||
<< " / " << frames_out_
|
<< " / out " << frames_out_
|
||||||
<< " / " << frames_in_
|
<< " / in " << frames_in_
|
||||||
<< " Changes: " << adaption_changes_
|
<< " Changes: " << adaption_changes_
|
||||||
<< " Input: " << in_frame->GetWidth()
|
<< " Input: " << in_frame->GetWidth()
|
||||||
<< "x" << in_frame->GetHeight()
|
<< "x" << in_frame->GetHeight()
|
||||||
@ -344,9 +342,9 @@ bool VideoAdapter::AdaptFrame(const VideoFrame* in_frame,
|
|||||||
if (show) {
|
if (show) {
|
||||||
// TODO(fbarchard): Reduce to LS_VERBOSE when adapter info is not needed
|
// TODO(fbarchard): Reduce to LS_VERBOSE when adapter info is not needed
|
||||||
// in default calls.
|
// in default calls.
|
||||||
LOG(LS_INFO) << "VAdapt Frame: " << frames_scaled_
|
LOG(LS_INFO) << "VAdapt Frame: scaled " << frames_scaled_
|
||||||
<< " / " << frames_out_
|
<< " / out " << frames_out_
|
||||||
<< " / " << frames_in_
|
<< " / in " << frames_in_
|
||||||
<< " Changes: " << adaption_changes_
|
<< " Changes: " << adaption_changes_
|
||||||
<< " Input: " << in_frame->GetWidth()
|
<< " Input: " << in_frame->GetWidth()
|
||||||
<< "x" << in_frame->GetHeight()
|
<< "x" << in_frame->GetHeight()
|
||||||
|
@ -237,8 +237,10 @@ static int OnSctpInboundPacket(struct socket* sock, union sctp_sockstore addr,
|
|||||||
// Set the initial value of the static SCTP Data Engines reference count.
|
// Set the initial value of the static SCTP Data Engines reference count.
|
||||||
int SctpDataEngine::usrsctp_engines_count = 0;
|
int SctpDataEngine::usrsctp_engines_count = 0;
|
||||||
|
|
||||||
SctpDataEngine::SctpDataEngine() {
|
void SctpDataEngine::AddRefEngine() {
|
||||||
|
LOG(LS_VERBOSE) << "usrsctp_engines_count:" << usrsctp_engines_count;
|
||||||
if (usrsctp_engines_count == 0) {
|
if (usrsctp_engines_count == 0) {
|
||||||
|
LOG(LS_INFO) << "SctpDataEngine: Initializing usrsctp";
|
||||||
// First argument is udp_encapsulation_port, which is not releveant for our
|
// First argument is udp_encapsulation_port, which is not releveant for our
|
||||||
// AF_CONN use of sctp.
|
// AF_CONN use of sctp.
|
||||||
usrsctp_init(0, cricket::OnSctpOutboundPacket, debug_sctp_printf);
|
usrsctp_init(0, cricket::OnSctpOutboundPacket, debug_sctp_printf);
|
||||||
@ -276,26 +278,25 @@ SctpDataEngine::SctpDataEngine() {
|
|||||||
cricket::kMaxSctpSid);
|
cricket::kMaxSctpSid);
|
||||||
}
|
}
|
||||||
usrsctp_engines_count++;
|
usrsctp_engines_count++;
|
||||||
|
}
|
||||||
|
|
||||||
// We don't put in a codec because we don't want one offered when we
|
void SctpDataEngine::ReleaseEngine() {
|
||||||
// use the hybrid data engine.
|
usrsctp_engines_count--;
|
||||||
// codecs_.push_back(cricket::DataCodec( kGoogleSctpDataCodecId,
|
if (usrsctp_engines_count == 0) {
|
||||||
// kGoogleSctpDataCodecName, 0));
|
LOG(LS_INFO) << "SctpDataEngine: Shutting down";
|
||||||
|
if (usrsctp_finish() != 0) {
|
||||||
|
LOG_ERRNO(LS_ERROR) << "SctpDataEngine: usrsctp_finish failed: ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LOG(LS_VERBOSE) << "usrsctp_engines_count:" << usrsctp_engines_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
SctpDataEngine::SctpDataEngine() {
|
||||||
|
AddRefEngine();
|
||||||
}
|
}
|
||||||
|
|
||||||
SctpDataEngine::~SctpDataEngine() {
|
SctpDataEngine::~SctpDataEngine() {
|
||||||
// TODO(ldixon): There is currently a bug in teardown of usrsctp that blocks
|
ReleaseEngine();
|
||||||
// indefintely if a finish call made too soon after close calls. So teardown
|
|
||||||
// has been skipped. Once the bug is fixed, retest and enable teardown.
|
|
||||||
// Tracked in webrtc issue 2749.
|
|
||||||
//
|
|
||||||
// usrsctp_engines_count--;
|
|
||||||
// LOG(LS_VERBOSE) << "usrsctp_engines_count:" << usrsctp_engines_count;
|
|
||||||
// if (usrsctp_engines_count == 0) {
|
|
||||||
// if (usrsctp_finish() != 0) {
|
|
||||||
// LOG(LS_WARNING) << "usrsctp_finish.";
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DataMediaChannel* SctpDataEngine::CreateChannel(
|
DataMediaChannel* SctpDataEngine::CreateChannel(
|
||||||
@ -314,10 +315,12 @@ SctpDataMediaChannel::SctpDataMediaChannel(talk_base::Thread* thread)
|
|||||||
sending_(false),
|
sending_(false),
|
||||||
receiving_(false),
|
receiving_(false),
|
||||||
debug_name_("SctpDataMediaChannel") {
|
debug_name_("SctpDataMediaChannel") {
|
||||||
|
SctpDataEngine::AddRefEngine();
|
||||||
}
|
}
|
||||||
|
|
||||||
SctpDataMediaChannel::~SctpDataMediaChannel() {
|
SctpDataMediaChannel::~SctpDataMediaChannel() {
|
||||||
CloseSctpSocket();
|
CloseSctpSocket();
|
||||||
|
SctpDataEngine::ReleaseEngine();
|
||||||
}
|
}
|
||||||
|
|
||||||
sockaddr_conn SctpDataMediaChannel::GetSctpSockAddr(int port) {
|
sockaddr_conn SctpDataMediaChannel::GetSctpSockAddr(int port) {
|
||||||
|
@ -91,6 +91,12 @@ class SctpDataEngine : public DataEngineInterface {
|
|||||||
|
|
||||||
virtual const std::vector<DataCodec>& data_codecs() { return codecs_; }
|
virtual const std::vector<DataCodec>& data_codecs() { return codecs_; }
|
||||||
|
|
||||||
|
// Manages the lifetime of the usrsctp library data. Each SctpDataEngine
|
||||||
|
// and SctpDataMediaChannel AddRefEngine the library at construction, and
|
||||||
|
// ReleaseEngine at shutdown.
|
||||||
|
static void AddRefEngine();
|
||||||
|
static void ReleaseEngine();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static int usrsctp_engines_count;
|
static int usrsctp_engines_count;
|
||||||
std::vector<DataCodec> codecs_;
|
std::vector<DataCodec> codecs_;
|
||||||
|
@ -2632,6 +2632,15 @@ bool WebRtcVideoMediaChannel::SetSendRtpHeaderExtensions(
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (send_time_extension) {
|
||||||
|
// For video RTP packets, we would like to update AbsoluteSendTimeHeader
|
||||||
|
// Extension closer to the network, @ socket level before sending.
|
||||||
|
// Pushing the extension id to socket layer.
|
||||||
|
MediaChannel::SetOption(NetworkInterface::ST_RTP,
|
||||||
|
talk_base::Socket::OPT_RTP_SENDTIME_EXTN_ID,
|
||||||
|
send_time_extension->id);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
|
||||||
#include "talk/base/basictypes.h"
|
#include "talk/base/basictypes.h"
|
||||||
#include "talk/base/socketaddress.h"
|
#include "talk/base/socketaddress.h"
|
||||||
#include "talk/p2p/base/constants.h"
|
#include "talk/p2p/base/constants.h"
|
||||||
@ -163,13 +164,30 @@ class Candidate {
|
|||||||
return ToStringInternal(true);
|
return ToStringInternal(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 GetPriority(uint32 type_preference) const {
|
uint32 GetPriority(uint32 type_preference,
|
||||||
|
int network_adapter_preference) const {
|
||||||
// RFC 5245 - 4.1.2.1.
|
// RFC 5245 - 4.1.2.1.
|
||||||
// priority = (2^24)*(type preference) +
|
// priority = (2^24)*(type preference) +
|
||||||
// (2^8)*(local preference) +
|
// (2^8)*(local preference) +
|
||||||
// (2^0)*(256 - component ID)
|
// (2^0)*(256 - component ID)
|
||||||
|
|
||||||
|
// |local_preference| length is 2 bytes, 0-65535 inclusive.
|
||||||
|
// In our implemenation we will partion local_preference into
|
||||||
|
// 0 1
|
||||||
|
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | NIC Pref | Addr Pref |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// NIC Type - Type of the network adapter e.g. 3G/Wifi/Wired.
|
||||||
|
// Addr Pref - Address preference value as per RFC 3484.
|
||||||
|
// local preference is calculated as - NIC Type << 8 | Addr_Pref.
|
||||||
|
|
||||||
int addr_pref = IPAddressPrecedence(address_.ipaddr());
|
int addr_pref = IPAddressPrecedence(address_.ipaddr());
|
||||||
return (type_preference << 24) | (addr_pref << 8) | (256 - component_);
|
int local_preference = (network_adapter_preference << 8) | addr_pref;
|
||||||
|
|
||||||
|
return (type_preference << 24) |
|
||||||
|
(local_preference << 8) |
|
||||||
|
(256 - component_);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -177,9 +195,9 @@ class Candidate {
|
|||||||
std::ostringstream ost;
|
std::ostringstream ost;
|
||||||
std::string address = sensitive ? address_.ToSensitiveString() :
|
std::string address = sensitive ? address_.ToSensitiveString() :
|
||||||
address_.ToString();
|
address_.ToString();
|
||||||
ost << "Cand[" << id_ << ":" << component_ << ":"
|
ost << "Cand[" << foundation_ << ":" << component_ << ":"
|
||||||
<< type_ << ":" << protocol_ << ":"
|
<< protocol_ << ":" << priority_ << ":"
|
||||||
<< network_name_ << ":" << address << ":"
|
<< address << ":" << type_ << ":" << related_address_ << ":"
|
||||||
<< username_ << ":" << password_ << "]";
|
<< username_ << ":" << password_ << "]";
|
||||||
return ost.str();
|
return ost.str();
|
||||||
}
|
}
|
||||||
|
@ -493,7 +493,8 @@ void P2PTransportChannel::OnUnknownAddress(
|
|||||||
port->Network()->name(), 0U,
|
port->Network()->name(), 0U,
|
||||||
talk_base::ToString<uint32>(talk_base::ComputeCrc32(id)));
|
talk_base::ToString<uint32>(talk_base::ComputeCrc32(id)));
|
||||||
new_remote_candidate.set_priority(
|
new_remote_candidate.set_priority(
|
||||||
new_remote_candidate.GetPriority(ICE_TYPE_PREFERENCE_SRFLX));
|
new_remote_candidate.GetPriority(ICE_TYPE_PREFERENCE_SRFLX,
|
||||||
|
port->Network()->preference()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (port->IceProtocol() == ICEPROTO_RFC5245) {
|
if (port->IceProtocol() == ICEPROTO_RFC5245) {
|
||||||
|
@ -1559,8 +1559,11 @@ TEST_F(P2PTransportChannelMultihomedTest, DISABLED_TestBasic) {
|
|||||||
// Test that we can quickly switch links if an interface goes down.
|
// Test that we can quickly switch links if an interface goes down.
|
||||||
TEST_F(P2PTransportChannelMultihomedTest, TestFailover) {
|
TEST_F(P2PTransportChannelMultihomedTest, TestFailover) {
|
||||||
AddAddress(0, kPublicAddrs[0]);
|
AddAddress(0, kPublicAddrs[0]);
|
||||||
AddAddress(1, kPublicAddrs[1]);
|
// Adding alternate address will make sure |kPublicAddrs| has the higher
|
||||||
|
// priority than others. This is due to FakeNetwork::AddInterface method.
|
||||||
AddAddress(1, kAlternateAddrs[1]);
|
AddAddress(1, kAlternateAddrs[1]);
|
||||||
|
AddAddress(1, kPublicAddrs[1]);
|
||||||
|
|
||||||
// Use only local ports for simplicity.
|
// Use only local ports for simplicity.
|
||||||
SetAllocatorFlags(0, kOnlyLocalPorts);
|
SetAllocatorFlags(0, kOnlyLocalPorts);
|
||||||
SetAllocatorFlags(1, kOnlyLocalPorts);
|
SetAllocatorFlags(1, kOnlyLocalPorts);
|
||||||
|
@ -258,7 +258,7 @@ void Port::AddAddress(const talk_base::SocketAddress& address,
|
|||||||
c.set_type(type);
|
c.set_type(type);
|
||||||
c.set_protocol(protocol);
|
c.set_protocol(protocol);
|
||||||
c.set_address(address);
|
c.set_address(address);
|
||||||
c.set_priority(c.GetPriority(type_preference));
|
c.set_priority(c.GetPriority(type_preference, network_->preference()));
|
||||||
c.set_username(username_fragment());
|
c.set_username(username_fragment());
|
||||||
c.set_password(password_);
|
c.set_password(password_);
|
||||||
c.set_network_name(network_->name());
|
c.set_network_name(network_->name());
|
||||||
|
@ -53,8 +53,8 @@ using talk_base::Thread;
|
|||||||
static const SocketAddress kClientAddr("11.11.11.11", 0);
|
static const SocketAddress kClientAddr("11.11.11.11", 0);
|
||||||
static const SocketAddress kClientIPv6Addr(
|
static const SocketAddress kClientIPv6Addr(
|
||||||
"2401:fa00:4:1000:be30:5bff:fee5:c3", 0);
|
"2401:fa00:4:1000:be30:5bff:fee5:c3", 0);
|
||||||
|
static const SocketAddress kClientAddr2("22.22.22.22", 0);
|
||||||
static const SocketAddress kNatAddr("77.77.77.77", talk_base::NAT_SERVER_PORT);
|
static const SocketAddress kNatAddr("77.77.77.77", talk_base::NAT_SERVER_PORT);
|
||||||
static const SocketAddress kRemoteClientAddr("22.22.22.22", 0);
|
|
||||||
static const SocketAddress kStunAddr("99.99.99.1", cricket::STUN_SERVER_PORT);
|
static const SocketAddress kStunAddr("99.99.99.1", cricket::STUN_SERVER_PORT);
|
||||||
static const SocketAddress kRelayUdpIntAddr("99.99.99.2", 5000);
|
static const SocketAddress kRelayUdpIntAddr("99.99.99.2", 5000);
|
||||||
static const SocketAddress kRelayUdpExtAddr("99.99.99.3", 5001);
|
static const SocketAddress kRelayUdpExtAddr("99.99.99.3", 5001);
|
||||||
@ -492,6 +492,23 @@ TEST_F(PortAllocatorTest, TestGetAllPortsNoUdpAllowed) {
|
|||||||
EXPECT_TRUE_WAIT(candidate_allocation_done_, 9000);
|
EXPECT_TRUE_WAIT(candidate_allocation_done_, 9000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(PortAllocatorTest, TestCandidatePriorityOfMultipleInterfaces) {
|
||||||
|
AddInterface(kClientAddr);
|
||||||
|
AddInterface(kClientAddr2);
|
||||||
|
// Allocating only host UDP ports. This is done purely for testing
|
||||||
|
// convenience.
|
||||||
|
allocator().set_flags(cricket::PORTALLOCATOR_DISABLE_TCP |
|
||||||
|
cricket::PORTALLOCATOR_DISABLE_STUN |
|
||||||
|
cricket::PORTALLOCATOR_DISABLE_RELAY);
|
||||||
|
EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
|
||||||
|
session_->StartGettingPorts();
|
||||||
|
EXPECT_TRUE_WAIT(candidate_allocation_done_, kDefaultAllocationTimeout);
|
||||||
|
ASSERT_EQ(2U, candidates_.size());
|
||||||
|
EXPECT_EQ(2U, ports_.size());
|
||||||
|
// Candidates priorities should be different.
|
||||||
|
EXPECT_NE(candidates_[0].priority(), candidates_[1].priority());
|
||||||
|
}
|
||||||
|
|
||||||
// Test to verify ICE restart process.
|
// Test to verify ICE restart process.
|
||||||
TEST_F(PortAllocatorTest, TestGetAllPortsRestarts) {
|
TEST_F(PortAllocatorTest, TestGetAllPortsRestarts) {
|
||||||
AddInterface(kClientAddr);
|
AddInterface(kClientAddr);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user