Update stable to r5121.
git-svn-id: http://webrtc.googlecode.com/svn/stable/talk@5122 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/app/webrtc/datachannel.cc b/app/webrtc/datachannel.cc
index 6f30487..6c9e0bc 100644
--- a/app/webrtc/datachannel.cc
+++ b/app/webrtc/datachannel.cc
@@ -248,7 +248,9 @@
void DataChannel::OnDataReceived(cricket::DataChannel* channel,
const cricket::ReceiveDataParams& params,
const talk_base::Buffer& payload) {
- if (params.ssrc != receive_ssrc_) {
+ uint32 expected_ssrc =
+ (data_channel_type_ == cricket::DCT_RTP) ? receive_ssrc_ : config_.id;
+ if (params.ssrc != expected_ssrc) {
return;
}
@@ -307,7 +309,6 @@
if (send_ssrc_set_ == receive_ssrc_set_) {
if (data_channel_type_ == cricket::DCT_RTP && !connected_to_provider_) {
connected_to_provider_ = provider_->ConnectDataChannel(this);
- provider_->AddRtpDataStream(send_ssrc_, receive_ssrc_);
}
if (was_ever_writable_) {
// TODO(jiayl): Do not transition to kOpen if we failed to send the
@@ -351,9 +352,7 @@
provider_->DisconnectDataChannel(this);
connected_to_provider_ = false;
- if (data_channel_type_ == cricket::DCT_RTP) {
- provider_->RemoveRtpDataStream(send_ssrc_, receive_ssrc_);
- } else {
+ if (data_channel_type_ == cricket::DCT_SCTP) {
provider_->RemoveSctpDataStream(config_.id);
}
}
@@ -429,11 +428,13 @@
const DataBuffer& buffer, cricket::SendDataResult* send_result) {
cricket::SendDataParams send_params;
- send_params.ssrc = send_ssrc_;
if (data_channel_type_ == cricket::DCT_SCTP) {
send_params.ordered = config_.ordered;
send_params.max_rtx_count = config_.maxRetransmits;
send_params.max_rtx_ms = config_.maxRetransmitTime;
+ send_params.ssrc = config_.id;
+ } else {
+ send_params.ssrc = send_ssrc_;
}
send_params.type = buffer.binary ? cricket::DMT_BINARY : cricket::DMT_TEXT;
diff --git a/app/webrtc/datachannel.h b/app/webrtc/datachannel.h
index 5635e63..bf31aed 100644
--- a/app/webrtc/datachannel.h
+++ b/app/webrtc/datachannel.h
@@ -53,12 +53,8 @@
virtual bool ConnectDataChannel(DataChannel* data_channel) = 0;
// Disconnects from the transport signals.
virtual void DisconnectDataChannel(DataChannel* data_channel) = 0;
- // Adds the send and receive stream ssrc to the transport for RTP.
- virtual void AddRtpDataStream(uint32 send_ssrc, uint32 recv_ssrc) = 0;
// Adds the data channel SID to the transport for SCTP.
virtual void AddSctpDataStream(uint32 sid) = 0;
- // Removes the data channel ssrcs from the transport for RTP.
- virtual void RemoveRtpDataStream(uint32 send_ssrc, uint32 recv_ssrc) = 0;
// Removes the data channel SID from the transport for SCTP.
virtual void RemoveSctpDataStream(uint32 sid) = 0;
// Returns true if the transport channel is ready to send data.
@@ -149,6 +145,10 @@
// underlying data engine.
void SetReceiveSsrc(uint32 receive_ssrc);
+ cricket::DataChannelType data_channel_type() const {
+ return data_channel_type_;
+ }
+
protected:
DataChannel(DataChannelProviderInterface* client,
cricket::DataChannelType dct,
diff --git a/app/webrtc/datachannel_unittest.cc b/app/webrtc/datachannel_unittest.cc
index dba24a2..fdcd2f2 100644
--- a/app/webrtc/datachannel_unittest.cc
+++ b/app/webrtc/datachannel_unittest.cc
@@ -28,9 +28,16 @@
#include "talk/app/webrtc/datachannel.h"
#include "talk/app/webrtc/test/fakedatachannelprovider.h"
#include "talk/base/gunit.h"
+#include "testing/base/public/gmock.h"
using webrtc::DataChannel;
+class FakeDataChannelObserver : public webrtc::DataChannelObserver {
+ public:
+ MOCK_METHOD0(OnStateChange, void());
+ MOCK_METHOD1(OnMessage, void(const webrtc::DataBuffer& buffer));
+};
+
class SctpDataChannelTest : public testing::Test {
protected:
SctpDataChannelTest()
@@ -47,8 +54,14 @@
provider_.set_ready_to_send(true);
}
+ void AddObserver() {
+ observer_.reset(new FakeDataChannelObserver());
+ webrtc_data_channel_->RegisterObserver(observer_.get());
+ }
+
webrtc::DataChannelInit init_;
FakeDataChannelProvider provider_;
+ talk_base::scoped_ptr<FakeDataChannelObserver> observer_;
talk_base::scoped_refptr<DataChannel> webrtc_data_channel_;
};
@@ -148,3 +161,41 @@
EXPECT_TRUE_WAIT(webrtc::DataChannelInterface::kOpen == dc->state(),
1000);
}
+
+// Tests that messages are sent with the right ssrc.
+TEST_F(SctpDataChannelTest, SendDataSsrc) {
+ webrtc_data_channel_->SetSctpSid(1);
+ SetChannelReady();
+ webrtc::DataBuffer buffer("data");
+ EXPECT_TRUE(webrtc_data_channel_->Send(buffer));
+ EXPECT_EQ(1U, provider_.last_send_data_params().ssrc);
+}
+
+// Tests that the incoming messages with wrong ssrcs are rejected.
+TEST_F(SctpDataChannelTest, ReceiveDataWithInvalidSsrc) {
+ webrtc_data_channel_->SetSctpSid(1);
+ SetChannelReady();
+
+ AddObserver();
+ EXPECT_CALL(*(observer_.get()), OnMessage(testing::_)).Times(0);
+
+ cricket::ReceiveDataParams params;
+ params.ssrc = 0;
+ webrtc::DataBuffer buffer("abcd");
+ webrtc_data_channel_->OnDataReceived(NULL, params, buffer.data);
+}
+
+// Tests that the incoming messages with right ssrcs are acceted.
+TEST_F(SctpDataChannelTest, ReceiveDataWithValidSsrc) {
+ webrtc_data_channel_->SetSctpSid(1);
+ SetChannelReady();
+
+ AddObserver();
+ EXPECT_CALL(*(observer_.get()), OnMessage(testing::_)).Times(1);
+
+ cricket::ReceiveDataParams params;
+ params.ssrc = 1;
+ webrtc::DataBuffer buffer("abcd");
+
+ webrtc_data_channel_->OnDataReceived(NULL, params, buffer.data);
+}
diff --git a/app/webrtc/mediastreamsignaling.cc b/app/webrtc/mediastreamsignaling.cc
index 8d25425..7586938 100644
--- a/app/webrtc/mediastreamsignaling.cc
+++ b/app/webrtc/mediastreamsignaling.cc
@@ -208,10 +208,10 @@
bool MediaStreamSignaling::IsSctpSidAvailable(int sid) const {
if (sid < 0 || sid > static_cast<int>(cricket::kMaxSctpSid))
return false;
- for (DataChannels::const_iterator iter = data_channels_.begin();
- iter != data_channels_.end();
+ for (SctpDataChannels::const_iterator iter = sctp_data_channels_.begin();
+ iter != sctp_data_channels_.end();
++iter) {
- if (iter->second->id() == sid) {
+ if ((*iter)->id() == sid) {
return false;
}
}
@@ -240,17 +240,23 @@
}
bool MediaStreamSignaling::HasDataChannels() const {
- return !data_channels_.empty();
+ return !rtp_data_channels_.empty() || !sctp_data_channels_.empty();
}
bool MediaStreamSignaling::AddDataChannel(DataChannel* data_channel) {
ASSERT(data_channel != NULL);
- if (data_channels_.find(data_channel->label()) != data_channels_.end()) {
- LOG(LS_ERROR) << "DataChannel with label " << data_channel->label()
- << " already exists.";
- return false;
+ if (data_channel->data_channel_type() == cricket::DCT_RTP) {
+ if (rtp_data_channels_.find(data_channel->label()) !=
+ rtp_data_channels_.end()) {
+ LOG(LS_ERROR) << "DataChannel with label " << data_channel->label()
+ << " already exists.";
+ return false;
+ }
+ rtp_data_channels_[data_channel->label()] = data_channel;
+ } else {
+ ASSERT(data_channel->data_channel_type() == cricket::DCT_SCTP);
+ sctp_data_channels_.push_back(data_channel);
}
- data_channels_[data_channel->label()] = data_channel;
return true;
}
@@ -262,19 +268,13 @@
<< "are not supported.";
return false;
}
-
- if (data_channels_.find(label) != data_channels_.end()) {
- LOG(LS_ERROR) << "DataChannel with label " << label
- << " already exists.";
- return false;
- }
scoped_refptr<DataChannel> channel(
data_channel_factory_->CreateDataChannel(label, &config));
if (!channel.get()) {
LOG(LS_ERROR) << "Failed to create DataChannel from the OPEN message.";
return false;
}
- data_channels_[label] = channel;
+ sctp_data_channels_.push_back(channel);
stream_observer_->OnAddDataChannel(channel);
return true;
}
@@ -464,10 +464,13 @@
}
void MediaStreamSignaling::OnDataChannelClose() {
- DataChannels::iterator it = data_channels_.begin();
- for (; it != data_channels_.end(); ++it) {
- DataChannel* data_channel = it->second;
- data_channel->OnDataEngineClose();
+ RtpDataChannels::iterator it1 = rtp_data_channels_.begin();
+ for (; it1 != rtp_data_channels_.end(); ++it1) {
+ it1->second->OnDataEngineClose();
+ }
+ SctpDataChannels::iterator it2 = sctp_data_channels_.begin();
+ for (; it2 != sctp_data_channels_.end(); ++it2) {
+ (*it2)->OnDataEngineClose();
}
}
@@ -525,8 +528,8 @@
}
// Check for data channels.
- DataChannels::const_iterator data_channel_it = data_channels_.begin();
- for (; data_channel_it != data_channels_.end(); ++data_channel_it) {
+ RtpDataChannels::const_iterator data_channel_it = rtp_data_channels_.begin();
+ for (; data_channel_it != rtp_data_channels_.end(); ++data_channel_it) {
const DataChannel* channel = data_channel_it->second;
if (channel->state() == DataChannel::kConnecting ||
channel->state() == DataChannel::kOpen) {
@@ -843,8 +846,9 @@
// For MediaStreams, the sync_label is the MediaStream label and the
// track label is the same as |streamid|.
const std::string& channel_label = it->sync_label;
- DataChannels::iterator data_channel_it = data_channels_.find(channel_label);
- if (!VERIFY(data_channel_it != data_channels_.end())) {
+ RtpDataChannels::iterator data_channel_it =
+ rtp_data_channels_.find(channel_label);
+ if (!VERIFY(data_channel_it != rtp_data_channels_.end())) {
continue;
}
// Set the SSRC the data channel should use for sending.
@@ -866,9 +870,9 @@
// does not exist. Ex a=ssrc:444330170 mslabel:test1.
std::string label = it->sync_label.empty() ?
talk_base::ToString(it->first_ssrc()) : it->sync_label;
- DataChannels::iterator data_channel_it =
- data_channels_.find(label);
- if (data_channel_it == data_channels_.end()) {
+ RtpDataChannels::iterator data_channel_it =
+ rtp_data_channels_.find(label);
+ if (data_channel_it == rtp_data_channels_.end()) {
// This is a new data channel.
CreateRemoteDataChannel(label, it->first_ssrc());
} else {
@@ -882,8 +886,8 @@
void MediaStreamSignaling::UpdateClosingDataChannels(
const std::vector<std::string>& active_channels, bool is_local_update) {
- DataChannels::iterator it = data_channels_.begin();
- while (it != data_channels_.end()) {
+ RtpDataChannels::iterator it = rtp_data_channels_.begin();
+ while (it != rtp_data_channels_.end()) {
DataChannel* data_channel = it->second;
if (std::find(active_channels.begin(), active_channels.end(),
data_channel->label()) != active_channels.end()) {
@@ -897,8 +901,8 @@
data_channel->RemotePeerRequestClose();
if (data_channel->state() == DataChannel::kClosed) {
- data_channels_.erase(it);
- it = data_channels_.begin();
+ rtp_data_channels_.erase(it);
+ it = rtp_data_channels_.begin();
} else {
++it;
}
@@ -914,29 +918,32 @@
}
scoped_refptr<DataChannel> channel(
data_channel_factory_->CreateDataChannel(label, NULL));
+ if (!channel.get()) {
+ LOG(LS_WARNING) << "Remote peer requested a DataChannel but"
+ << "CreateDataChannel failed.";
+ return;
+ }
channel->SetReceiveSsrc(remote_ssrc);
stream_observer_->OnAddDataChannel(channel);
}
void MediaStreamSignaling::OnDataTransportCreatedForSctp() {
- DataChannels::iterator it = data_channels_.begin();
- for (; it != data_channels_.end(); ++it) {
- DataChannel* data_channel = it->second;
- data_channel->OnTransportChannelCreated();
+ SctpDataChannels::iterator it = sctp_data_channels_.begin();
+ for (; it != sctp_data_channels_.end(); ++it) {
+ (*it)->OnTransportChannelCreated();
}
}
void MediaStreamSignaling::OnDtlsRoleReadyForSctp(talk_base::SSLRole role) {
- DataChannels::iterator it = data_channels_.begin();
- for (; it != data_channels_.end(); ++it) {
- DataChannel* data_channel = it->second;
- if (data_channel->id() < 0) {
+ SctpDataChannels::iterator it = sctp_data_channels_.begin();
+ for (; it != sctp_data_channels_.end(); ++it) {
+ if ((*it)->id() < 0) {
int sid;
if (!AllocateSctpSid(role, &sid)) {
LOG(LS_ERROR) << "Failed to allocate SCTP sid.";
continue;
}
- data_channel->SetSctpSid(sid);
+ (*it)->SetSctpSid(sid);
}
}
}
diff --git a/app/webrtc/mediastreamsignaling.h b/app/webrtc/mediastreamsignaling.h
index a0ed619..c600f06 100644
--- a/app/webrtc/mediastreamsignaling.h
+++ b/app/webrtc/mediastreamsignaling.h
@@ -384,8 +384,10 @@
int last_allocated_sctp_odd_sid_;
typedef std::map<std::string, talk_base::scoped_refptr<DataChannel> >
- DataChannels;
- DataChannels data_channels_;
+ RtpDataChannels;
+ typedef std::vector<talk_base::scoped_refptr<DataChannel> > SctpDataChannels;
+ RtpDataChannels rtp_data_channels_;
+ SctpDataChannels sctp_data_channels_;
};
} // namespace webrtc
diff --git a/app/webrtc/mediastreamsignaling_unittest.cc b/app/webrtc/mediastreamsignaling_unittest.cc
index df4b1f5..5b88aa0 100644
--- a/app/webrtc/mediastreamsignaling_unittest.cc
+++ b/app/webrtc/mediastreamsignaling_unittest.cc
@@ -238,6 +238,23 @@
return true;
}
+class FakeDataChannelFactory : public webrtc::DataChannelFactory {
+ public:
+ FakeDataChannelFactory(FakeDataChannelProvider* provider,
+ cricket::DataChannelType dct)
+ : provider_(provider), type_(dct) {}
+
+ virtual talk_base::scoped_refptr<webrtc::DataChannel> CreateDataChannel(
+ const std::string& label,
+ const webrtc::DataChannelInit* config) {
+ return webrtc::DataChannel::Create(provider_, type_, label, config);
+ }
+
+ private:
+ FakeDataChannelProvider* provider_;
+ cricket::DataChannelType type_;
+};
+
class MockSignalingObserver : public webrtc::MediaStreamSignalingObserver {
public:
MockSignalingObserver()
@@ -418,6 +435,7 @@
talk_base::Thread::Current()));
signaling_.reset(new MediaStreamSignalingForTest(observer_.get(),
channel_manager_.get()));
+ data_channel_provider_.reset(new FakeDataChannelProvider());
}
// Create a collection of streams.
@@ -508,12 +526,25 @@
ASSERT_TRUE(stream->AddTrack(video_track));
}
+ talk_base::scoped_refptr<webrtc::DataChannel> AddDataChannel(
+ cricket::DataChannelType type, const std::string& label, int id) {
+ webrtc::DataChannelInit config;
+ config.id = id;
+ talk_base::scoped_refptr<webrtc::DataChannel> data_channel(
+ webrtc::DataChannel::Create(
+ data_channel_provider_.get(), type, label, &config));
+ EXPECT_TRUE(data_channel.get() != NULL);
+ EXPECT_TRUE(signaling_->AddDataChannel(data_channel.get()));
+ return data_channel;
+ }
+
// ChannelManager is used by VideoSource, so it should be released after all
// the video tracks. Put it as the first private variable should ensure that.
talk_base::scoped_ptr<cricket::ChannelManager> channel_manager_;
talk_base::scoped_refptr<StreamCollection> reference_collection_;
talk_base::scoped_ptr<MockSignalingObserver> observer_;
talk_base::scoped_ptr<MediaStreamSignalingForTest> signaling_;
+ talk_base::scoped_ptr<FakeDataChannelProvider> data_channel_provider_;
};
// Test that a MediaSessionOptions is created for an offer if
@@ -1029,27 +1060,46 @@
// Verifies that SCTP ids of existing DataChannels are not reused.
TEST_F(MediaStreamSignalingTest, SctpIdAllocationNoReuse) {
- talk_base::scoped_ptr<FakeDataChannelProvider> provider(
- new FakeDataChannelProvider());
- // Creates a DataChannel with id 1.
- webrtc::DataChannelInit config;
- config.id = 1;
- talk_base::scoped_refptr<webrtc::DataChannel> data_channel(
- webrtc::DataChannel::Create(
- provider.get(), cricket::DCT_SCTP, "a", &config));
- ASSERT_TRUE(data_channel.get() != NULL);
- ASSERT_TRUE(signaling_->AddDataChannel(data_channel.get()));
+ int old_id = 1;
+ AddDataChannel(cricket::DCT_SCTP, "a", old_id);
int new_id;
ASSERT_TRUE(signaling_->AllocateSctpSid(talk_base::SSL_SERVER, &new_id));
- EXPECT_NE(config.id, new_id);
+ EXPECT_NE(old_id, new_id);
// Creates a DataChannel with id 0.
- config.id = 0;
- data_channel = webrtc::DataChannel::Create(
- provider.get(), cricket::DCT_SCTP, "b", &config);
- ASSERT_TRUE(data_channel.get() != NULL);
- ASSERT_TRUE(signaling_->AddDataChannel(data_channel.get()));
+ old_id = 0;
+ AddDataChannel(cricket::DCT_SCTP, "a", old_id);
ASSERT_TRUE(signaling_->AllocateSctpSid(talk_base::SSL_CLIENT, &new_id));
- EXPECT_NE(config.id, new_id);
+ EXPECT_NE(old_id, new_id);
+}
+
+// Verifies that duplicated label is not allowed for RTP data channel.
+TEST_F(MediaStreamSignalingTest, RtpDuplicatedLabelNotAllowed) {
+ AddDataChannel(cricket::DCT_RTP, "a", -1);
+
+ webrtc::DataChannelInit config;
+ talk_base::scoped_refptr<webrtc::DataChannel> data_channel =
+ webrtc::DataChannel::Create(
+ data_channel_provider_.get(), cricket::DCT_RTP, "a", &config);
+ ASSERT_TRUE(data_channel.get() != NULL);
+ EXPECT_FALSE(signaling_->AddDataChannel(data_channel.get()));
+}
+
+// Verifies that duplicated label is allowed for SCTP data channel.
+TEST_F(MediaStreamSignalingTest, SctpDuplicatedLabelAllowed) {
+ AddDataChannel(cricket::DCT_SCTP, "a", -1);
+ AddDataChannel(cricket::DCT_SCTP, "a", -1);
+}
+
+// Verifies that duplicated label from OPEN message is allowed.
+TEST_F(MediaStreamSignalingTest, DuplicatedLabelFromOpenMessageAllowed) {
+ AddDataChannel(cricket::DCT_SCTP, "a", -1);
+
+ FakeDataChannelFactory fake_factory(data_channel_provider_.get(),
+ cricket::DCT_SCTP);
+ signaling_->SetDataChannelFactory(&fake_factory);
+ webrtc::DataChannelInit config;
+ config.id = 0;
+ EXPECT_TRUE(signaling_->AddDataChannelFromOpenMessage("a", config));
}
diff --git a/app/webrtc/peerconnection.cc b/app/webrtc/peerconnection.cc
index bc69d48..17f187d 100644
--- a/app/webrtc/peerconnection.cc
+++ b/app/webrtc/peerconnection.cc
@@ -42,8 +42,6 @@
using webrtc::PeerConnectionInterface;
-// The min number of tokens in the ice uri.
-static const size_t kMinIceUriTokens = 2;
// The min number of tokens must present in Turn host uri.
// e.g. user@turn.example.org
static const size_t kTurnHostTokensNum = 2;
@@ -103,6 +101,73 @@
talk_base::scoped_refptr<webrtc::StatsObserver> observer;
};
+// |in_str| should be of format
+// stunURI = scheme ":" stun-host [ ":" stun-port ]
+// scheme = "stun" / "stuns"
+// stun-host = IP-literal / IPv4address / reg-name
+// stun-port = *DIGIT
+
+// draft-petithuguenin-behave-turn-uris-01
+// turnURI = scheme ":" turn-host [ ":" turn-port ]
+// turn-host = username@IP-literal / IPv4address / reg-name
+bool GetServiceTypeAndHostnameFromUri(const std::string& in_str,
+ ServiceType* service_type,
+ std::string* hostname) {
+ std::string::size_type colonpos = in_str.find(':');
+ if (colonpos == std::string::npos) {
+ return false;
+ }
+ std::string type = in_str.substr(0, colonpos);
+ for (size_t i = 0; i < ARRAY_SIZE(kValidIceServiceTypes); ++i) {
+ if (type.compare(kValidIceServiceTypes[i]) == 0) {
+ *service_type = static_cast<ServiceType>(i);
+ break;
+ }
+ }
+ if (*service_type == INVALID) {
+ return false;
+ }
+ *hostname = in_str.substr(colonpos + 1, std::string::npos);
+ return true;
+}
+
+// This method parses IPv6 and IPv4 literal strings, along with hostnames in
+// standard hostname:port format.
+// Consider following formats as correct.
+// |hostname:port|, |[IPV6 address]:port|, |IPv4 address|:port,
+// |hostname|, |[IPv6 address]|, |IPv4 address|
+bool ParseHostnameAndPortFromString(const std::string& in_str,
+ std::string* host,
+ int* port) {
+ if (in_str.at(0) == '[') {
+ std::string::size_type closebracket = in_str.rfind(']');
+ if (closebracket != std::string::npos) {
+ *host = in_str.substr(1, closebracket - 1);
+ std::string::size_type colonpos = in_str.find(':', closebracket);
+ if (std::string::npos != colonpos) {
+ if (!talk_base::FromString(
+ in_str.substr(closebracket + 2, std::string::npos), port)) {
+ return false;
+ }
+ }
+ } else {
+ return false;
+ }
+ } else {
+ std::string::size_type colonpos = in_str.find(':');
+ if (std::string::npos != colonpos) {
+ *host = in_str.substr(0, colonpos);
+ if (!talk_base::FromString(
+ in_str.substr(colonpos + 1, std::string::npos), port)) {
+ return false;
+ }
+ } else {
+ *host = in_str;
+ }
+ }
+ return true;
+}
+
typedef webrtc::PortAllocatorFactoryInterface::StunConfiguration
StunConfiguration;
typedef webrtc::PortAllocatorFactoryInterface::TurnConfiguration
@@ -125,8 +190,6 @@
// transport-ext = 1*unreserved
// turn-host = IP-literal / IPv4address / reg-name
// turn-port = *DIGIT
-
- // TODO(ronghuawu): Handle IPV6 address
for (size_t i = 0; i < configuration.size(); ++i) {
webrtc::PeerConnectionInterface::IceServer server = configuration[i];
if (server.uri.empty()) {
@@ -152,41 +215,40 @@
}
}
- tokens.clear();
- talk_base::tokenize(uri_without_transport, ':', &tokens);
- if (tokens.size() < kMinIceUriTokens) {
- LOG(WARNING) << "Invalid uri: " << server.uri;
- continue;
- }
+ std::string hoststring;
ServiceType service_type = INVALID;
- const std::string& type = tokens[0];
- for (size_t i = 0; i < ARRAY_SIZE(kValidIceServiceTypes); ++i) {
- if (type.compare(kValidIceServiceTypes[i]) == 0) {
- service_type = static_cast<ServiceType>(i);
- break;
- }
- }
- if (service_type == INVALID) {
- LOG(WARNING) << "Invalid service type: " << type;
+ if (!GetServiceTypeAndHostnameFromUri(uri_without_transport,
+ &service_type,
+ &hoststring)) {
+ LOG(LS_WARNING) << "Invalid transport parameter in ICE URI: "
+ << uri_without_transport;
continue;
}
- std::string address = tokens[1];
+
+ // Let's break hostname.
+ tokens.clear();
+ talk_base::tokenize(hoststring, '@', &tokens);
+ hoststring = tokens[0];
+ if (tokens.size() == kTurnHostTokensNum) {
+ server.username = talk_base::s_url_decode(tokens[0]);
+ hoststring = tokens[1];
+ }
+
int port = kDefaultStunPort;
+ std::string address;
+ if (!ParseHostnameAndPortFromString(hoststring, &address, &port)) {
+ LOG(WARNING) << "Invalid Hostname format: " << uri_without_transport;
+ continue;
+ }
+
if (service_type == TURNS) {
port = kDefaultStunTlsPort;
turn_transport_type = kTcpTransportType;
}
- if (tokens.size() > kMinIceUriTokens) {
- if (!talk_base::FromString(tokens[2], &port)) {
- LOG(LS_WARNING) << "Failed to parse port string: " << tokens[2];
- continue;
- }
-
- if (port <= 0 || port > 0xffff) {
- LOG(WARNING) << "Invalid port: " << port;
- continue;
- }
+ if (port <= 0 || port > 0xffff) {
+ LOG(WARNING) << "Invalid port: " << port;
+ continue;
}
switch (service_type) {
diff --git a/app/webrtc/peerconnectionfactory_unittest.cc b/app/webrtc/peerconnectionfactory_unittest.cc
index e3def6c..4f0b729 100644
--- a/app/webrtc/peerconnectionfactory_unittest.cc
+++ b/app/webrtc/peerconnectionfactory_unittest.cc
@@ -69,6 +69,15 @@
static const int kDefaultStunPort = 3478;
static const int kDefaultStunTlsPort = 5349;
static const char kTurnUsername[] = "test";
+static const char kStunIceServerWithIPv4Address[] = "stun:1.2.3.4:1234";
+static const char kStunIceServerWithIPv4AddressWithoutPort[] = "stun:1.2.3.4";
+static const char kStunIceServerWithIPv6Address[] = "stun:[2401:fa00:4::]:1234";
+static const char kStunIceServerWithIPv6AddressWithoutPort[] =
+ "stun:[2401:fa00:4::]";
+static const char kStunIceServerWithInvalidIPv6Address[] =
+ "stun:[2401:fa00:4:::3478";
+static const char kTurnIceServerWithIPv6Address[] =
+ "turn:test@[2401:fa00:4::]:1234";
class NullPeerConnectionObserver : public PeerConnectionObserver {
public:
@@ -265,6 +274,51 @@
VerifyTurnConfigurations(turn_configs);
}
+TEST_F(PeerConnectionFactoryTest, CreatePCUsingIPLiteralAddress) {
+ webrtc::PeerConnectionInterface::IceServers ice_servers;
+ webrtc::PeerConnectionInterface::IceServer ice_server;
+ ice_server.uri = kStunIceServerWithIPv4Address;
+ ice_servers.push_back(ice_server);
+ ice_server.uri = kStunIceServerWithIPv4AddressWithoutPort;
+ ice_servers.push_back(ice_server);
+ ice_server.uri = kStunIceServerWithIPv6Address;
+ ice_servers.push_back(ice_server);
+ ice_server.uri = kStunIceServerWithIPv6AddressWithoutPort;
+ ice_servers.push_back(ice_server);
+ ice_server.uri = kStunIceServerWithInvalidIPv6Address;
+ ice_servers.push_back(ice_server);
+ ice_server.uri = kTurnIceServerWithIPv6Address;
+ ice_server.password = kTurnPassword;
+ ice_servers.push_back(ice_server);
+ talk_base::scoped_refptr<PeerConnectionInterface> pc(
+ factory_->CreatePeerConnection(ice_servers, NULL,
+ allocator_factory_.get(),
+ NULL,
+ &observer_));
+ EXPECT_TRUE(pc.get() != NULL);
+ StunConfigurations stun_configs;
+ webrtc::PortAllocatorFactoryInterface::StunConfiguration stun1(
+ "1.2.3.4", 1234);
+ stun_configs.push_back(stun1);
+ webrtc::PortAllocatorFactoryInterface::StunConfiguration stun2(
+ "1.2.3.4", 3478);
+ stun_configs.push_back(stun2); // Default port
+ webrtc::PortAllocatorFactoryInterface::StunConfiguration stun3(
+ "2401:fa00:4::", 1234);
+ stun_configs.push_back(stun3);
+ webrtc::PortAllocatorFactoryInterface::StunConfiguration stun4(
+ "2401:fa00:4::", 3478);
+ stun_configs.push_back(stun4); // Default port
+ // Turn Address has the same host information as |stun3|.
+ stun_configs.push_back(stun3);
+ VerifyStunConfigurations(stun_configs);
+ TurnConfigurations turn_configs;
+ webrtc::PortAllocatorFactoryInterface::TurnConfiguration turn1(
+ "2401:fa00:4::", 1234, "test", kTurnPassword, "udp", false);
+ turn_configs.push_back(turn1);
+ VerifyTurnConfigurations(turn_configs);
+}
+
// This test verifies the captured stream is rendered locally using a
// local video track.
TEST_F(PeerConnectionFactoryTest, LocalRendering) {
diff --git a/app/webrtc/peerconnectioninterface_unittest.cc b/app/webrtc/peerconnectioninterface_unittest.cc
index ea94ee1..093b842 100644
--- a/app/webrtc/peerconnectioninterface_unittest.cc
+++ b/app/webrtc/peerconnectioninterface_unittest.cc
@@ -37,6 +37,7 @@
#include "talk/app/webrtc/videosource.h"
#include "talk/base/gunit.h"
#include "talk/base/scoped_ptr.h"
+#include "talk/base/ssladapter.h"
#include "talk/base/sslstreamadapter.h"
#include "talk/base/stringutils.h"
#include "talk/base/thread.h"
@@ -227,12 +228,17 @@
class PeerConnectionInterfaceTest : public testing::Test {
protected:
virtual void SetUp() {
+ talk_base::InitializeSSL(NULL);
pc_factory_ = webrtc::CreatePeerConnectionFactory(
talk_base::Thread::Current(), talk_base::Thread::Current(), NULL, NULL,
NULL);
ASSERT_TRUE(pc_factory_.get() != NULL);
}
+ virtual void TearDown() {
+ talk_base::CleanupSSL();
+ }
+
void CreatePeerConnection() {
CreatePeerConnection("", "", NULL);
}
@@ -1070,9 +1076,7 @@
// Test that we can create a session description from an SDP string from
// FireFox, use it as a remote session description, generate an answer and use
// the answer as a local description.
-// TODO(mallinath): re-enable per
-// https://code.google.com/p/webrtc/issues/detail?id=2574
-TEST_F(PeerConnectionInterfaceTest, DISABLED_ReceiveFireFoxOffer) {
+TEST_F(PeerConnectionInterfaceTest, ReceiveFireFoxOffer) {
MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
FakeConstraints constraints;
constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
@@ -1096,11 +1100,12 @@
cricket::GetFirstVideoContent(pc_->local_description()->description());
ASSERT_TRUE(content != NULL);
EXPECT_FALSE(content->rejected);
-
+#ifdef HAVE_SCTP
content =
cricket::GetFirstDataContent(pc_->local_description()->description());
ASSERT_TRUE(content != NULL);
EXPECT_TRUE(content->rejected);
+#endif
}
// Test that we can create an audio only offer and receive an answer with a
diff --git a/app/webrtc/test/fakedatachannelprovider.h b/app/webrtc/test/fakedatachannelprovider.h
index 429f4df..5b19698 100644
--- a/app/webrtc/test/fakedatachannelprovider.h
+++ b/app/webrtc/test/fakedatachannelprovider.h
@@ -64,29 +64,17 @@
connected_channels_.erase(data_channel);
}
- virtual void AddRtpDataStream(uint32 send_ssrc, uint32 recv_ssrc) OVERRIDE {
- if (!transport_available_) {
- return;
- }
- send_ssrcs_.insert(send_ssrc);
- recv_ssrcs_.insert(recv_ssrc);
- }
-
virtual void AddSctpDataStream(uint32 sid) OVERRIDE {
if (!transport_available_) {
return;
}
- AddRtpDataStream(sid, sid);
- }
-
- virtual void RemoveRtpDataStream(
- uint32 send_ssrc, uint32 recv_ssrc) OVERRIDE {
- send_ssrcs_.erase(send_ssrc);
- recv_ssrcs_.erase(recv_ssrc);
+ send_ssrcs_.insert(sid);
+ recv_ssrcs_.insert(sid);
}
virtual void RemoveSctpDataStream(uint32 sid) OVERRIDE {
- RemoveRtpDataStream(sid, sid);
+ send_ssrcs_.erase(sid);
+ recv_ssrcs_.erase(sid);
}
virtual bool ReadyToSendData() const OVERRIDE {
diff --git a/app/webrtc/test/testsdpstrings.h b/app/webrtc/test/testsdpstrings.h
index 9f95d36..d6e9c22 100644
--- a/app/webrtc/test/testsdpstrings.h
+++ b/app/webrtc/test/testsdpstrings.h
@@ -75,6 +75,7 @@
"a=candidate:4 2 UDP 2113667326 10.0.254.2 58890 typ host\r\n"
"a=candidate:5 2 UDP 1694302206 74.95.2.170 33611 typ srflx raddr"
" 10.0.254.2 rport 58890\r\n"
+#ifdef HAVE_SCTP
"m=application 45536 SCTP/DTLS 5000\r\n"
"c=IN IP4 74.95.2.170\r\n"
"a=fmtp:5000 protocol=webrtc-datachannel;streams=16\r\n"
@@ -88,7 +89,9 @@
"a=candidate:2 2 UDP 2112487678 172.16.131.1 59635 typ host\r\n"
"a=candidate:4 2 UDP 2113667326 10.0.254.2 61232 typ host\r\n"
"a=candidate:5 2 UDP 1694302206 74.95.2.170 45468 typ srflx raddr"
- " 10.0.254.2 rport 61232\r\n";
+ " 10.0.254.2 rport 61232\r\n"
+#endif
+ ;
// Audio SDP with a limited set of audio codecs.
static const char kAudioSdp[] =
diff --git a/app/webrtc/webrtcsession.cc b/app/webrtc/webrtcsession.cc
index 5935ea0..565eee3 100644
--- a/app/webrtc/webrtcsession.cc
+++ b/app/webrtc/webrtcsession.cc
@@ -997,31 +997,23 @@
data_channel_->SignalDataReceived.disconnect(webrtc_data_channel);
}
-void WebRtcSession::AddRtpDataStream(uint32 send_ssrc, uint32 recv_ssrc) {
+void WebRtcSession::AddSctpDataStream(uint32 sid) {
if (!data_channel_.get()) {
LOG(LS_ERROR) << "AddDataChannelStreams called when data_channel_ is NULL.";
return;
}
- data_channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(recv_ssrc));
- data_channel_->AddSendStream(cricket::StreamParams::CreateLegacy(send_ssrc));
+ data_channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(sid));
+ data_channel_->AddSendStream(cricket::StreamParams::CreateLegacy(sid));
}
-void WebRtcSession::AddSctpDataStream(uint32 sid) {
- AddRtpDataStream(sid, sid);
-}
-
-void WebRtcSession::RemoveRtpDataStream(uint32 send_ssrc, uint32 recv_ssrc) {
+void WebRtcSession::RemoveSctpDataStream(uint32 sid) {
if (!data_channel_.get()) {
LOG(LS_ERROR) << "RemoveDataChannelStreams called when data_channel_ is "
<< "NULL.";
return;
}
- data_channel_->RemoveRecvStream(recv_ssrc);
- data_channel_->RemoveSendStream(send_ssrc);
-}
-
-void WebRtcSession::RemoveSctpDataStream(uint32 sid) {
- RemoveRtpDataStream(sid, sid);
+ data_channel_->RemoveRecvStream(sid);
+ data_channel_->RemoveSendStream(sid);
}
bool WebRtcSession::ReadyToSendData() const {
diff --git a/app/webrtc/webrtcsession.h b/app/webrtc/webrtcsession.h
index 4a39a11..da994c5 100644
--- a/app/webrtc/webrtcsession.h
+++ b/app/webrtc/webrtcsession.h
@@ -190,9 +190,7 @@
cricket::SendDataResult* result) OVERRIDE;
virtual bool ConnectDataChannel(DataChannel* webrtc_data_channel) OVERRIDE;
virtual void DisconnectDataChannel(DataChannel* webrtc_data_channel) OVERRIDE;
- virtual void AddRtpDataStream(uint32 send_ssrc, uint32 recv_ssrc) OVERRIDE;
virtual void AddSctpDataStream(uint32 sid) OVERRIDE;
- virtual void RemoveRtpDataStream(uint32 send_ssrc, uint32 recv_ssrc) OVERRIDE;
virtual void RemoveSctpDataStream(uint32 sid) OVERRIDE;
virtual bool ReadyToSendData() const OVERRIDE;
diff --git a/base/asyncresolverinterface.h b/base/asyncresolverinterface.h
new file mode 100644
index 0000000..4d77c4f
--- /dev/null
+++ b/base/asyncresolverinterface.h
@@ -0,0 +1,64 @@
+/*
+ * 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_ASYNCRESOLVERINTERFACE_H_
+#define TALK_BASE_ASYNCRESOLVERINTERFACE_H_
+
+#include "talk/base/sigslot.h"
+#include "talk/base/socketaddress.h"
+
+namespace talk_base {
+
+// This interface defines the methods to resolve the address asynchronously.
+class AsyncResolverInterface {
+ public:
+ AsyncResolverInterface() {}
+ virtual ~AsyncResolverInterface() {}
+
+ // Start address resolve process.
+ virtual void Start(const SocketAddress& addr) = 0;
+ // Returns top most resolved address of |family|
+ virtual bool GetResolvedAddress(int family, SocketAddress* addr) const = 0;
+ // Returns error from resolver.
+ virtual int GetError() const = 0;
+ // Delete the resolver.
+ virtual void Destroy(bool wait) = 0;
+ // Returns top most resolved IPv4 address if address is resolved successfully.
+ // Otherwise returns address set in SetAddress.
+ SocketAddress address() const {
+ SocketAddress addr;
+ GetResolvedAddress(AF_INET, &addr);
+ return addr;
+ }
+
+ // This signal is fired when address resolve process is completed.
+ sigslot::signal1<AsyncResolverInterface*> SignalDone;
+};
+
+} // namespace talk_base
+
+#endif
diff --git a/base/autodetectproxy.cc b/base/autodetectproxy.cc
index 02cbaad..a32043c 100644
--- a/base/autodetectproxy.cc
+++ b/base/autodetectproxy.cc
@@ -82,7 +82,10 @@
}
void AutoDetectProxy::OnMessage(Message *msg) {
- if (MSG_TIMEOUT == msg->message_id) {
+ if (MSG_UNRESOLVABLE == msg->message_id) {
+ // If we can't resolve the proxy, skip straight to failure.
+ Complete(PROXY_UNKNOWN);
+ } else if (MSG_TIMEOUT == msg->message_id) {
OnCloseEvent(socket_, ETIMEDOUT);
} else {
// This must be the ST_MSG_WORKER_DONE message that deletes the
@@ -136,22 +139,24 @@
}
}
-void AutoDetectProxy::OnResolveResult(SignalThread* thread) {
- if (thread != resolver_) {
+void AutoDetectProxy::OnResolveResult(AsyncResolverInterface* resolver) {
+ if (resolver != resolver_) {
return;
}
- int error = resolver_->error();
+ int error = resolver_->GetError();
if (error == 0) {
LOG(LS_VERBOSE) << "Resolved " << proxy_.address << " to "
<< resolver_->address();
proxy_.address = resolver_->address();
- DoConnect();
+ if (!DoConnect()) {
+ Thread::Current()->Post(this, MSG_TIMEOUT);
+ }
} else {
LOG(LS_INFO) << "Failed to resolve " << resolver_->address();
resolver_->Destroy(false);
resolver_ = NULL;
proxy_.address = SocketAddress();
- Thread::Current()->Post(this, MSG_TIMEOUT);
+ Thread::Current()->Post(this, MSG_UNRESOLVABLE);
}
}
@@ -166,6 +171,7 @@
if (socket_) {
Thread::Current()->Clear(this, MSG_TIMEOUT);
+ Thread::Current()->Clear(this, MSG_UNRESOLVABLE);
socket_->Close();
Thread::Current()->Dispose(socket_);
socket_ = NULL;
@@ -177,17 +183,18 @@
if (!resolver_) {
resolver_ = new AsyncResolver();
}
- resolver_->set_address(proxy_.address);
- resolver_->SignalWorkDone.connect(this,
- &AutoDetectProxy::OnResolveResult);
- resolver_->Start();
+ resolver_->SignalDone.connect(this, &AutoDetectProxy::OnResolveResult);
+ resolver_->Start(proxy_.address);
} else {
- DoConnect();
+ if (!DoConnect()) {
+ Thread::Current()->Post(this, MSG_TIMEOUT);
+ return;
+ }
}
Thread::Current()->PostDelayed(timeout, this, MSG_TIMEOUT);
}
-void AutoDetectProxy::DoConnect() {
+bool AutoDetectProxy::DoConnect() {
if (resolver_) {
resolver_->Destroy(false);
resolver_ = NULL;
@@ -197,16 +204,18 @@
proxy_.address.family(), SOCK_STREAM);
if (!socket_) {
LOG(LS_VERBOSE) << "Unable to create socket for " << proxy_.address;
- return;
+ return false;
}
socket_->SignalConnectEvent.connect(this, &AutoDetectProxy::OnConnectEvent);
socket_->SignalReadEvent.connect(this, &AutoDetectProxy::OnReadEvent);
socket_->SignalCloseEvent.connect(this, &AutoDetectProxy::OnCloseEvent);
socket_->Connect(proxy_.address);
+ return true;
}
void AutoDetectProxy::Complete(ProxyType type) {
Thread::Current()->Clear(this, MSG_TIMEOUT);
+ Thread::Current()->Clear(this, MSG_UNRESOLVABLE);
if (socket_) {
socket_->Close();
}
diff --git a/base/autodetectproxy.h b/base/autodetectproxy.h
index a6ad3d1..2cbeb82 100644
--- a/base/autodetectproxy.h
+++ b/base/autodetectproxy.h
@@ -42,7 +42,7 @@
// AutoDetectProxy
///////////////////////////////////////////////////////////////////////////////
-class AsyncResolver;
+class AsyncResolverInterface;
class AsyncSocket;
class AutoDetectProxy : public SignalThread {
@@ -72,6 +72,7 @@
return GetProxySettingsForUrl(agent, url, proxy, true);
}
enum { MSG_TIMEOUT = SignalThread::ST_MSG_FIRST_AVAILABLE,
+ MSG_UNRESOLVABLE,
ADP_MSG_FIRST_AVAILABLE};
protected:
@@ -87,14 +88,14 @@
void OnConnectEvent(AsyncSocket * socket);
void OnReadEvent(AsyncSocket * socket);
void OnCloseEvent(AsyncSocket * socket, int error);
- void OnResolveResult(SignalThread* thread);
- void DoConnect();
+ void OnResolveResult(AsyncResolverInterface* resolver);
+ bool DoConnect();
private:
std::string agent_;
std::string server_url_;
ProxyInfo proxy_;
- AsyncResolver* resolver_;
+ AsyncResolverInterface* resolver_;
AsyncSocket* socket_;
int next_;
diff --git a/base/autodetectproxy_unittest.cc b/base/autodetectproxy_unittest.cc
index 3fca4c6..18241a3 100644
--- a/base/autodetectproxy_unittest.cc
+++ b/base/autodetectproxy_unittest.cc
@@ -37,9 +37,16 @@
static const char kHost[] = "relay.google.com";
static const uint16 kPort = 443;
static const bool kSecure = true;
-// Each of the two stages in AutoDetectProxy has a 2-second time-out, so 5
-// seconds total should be enough.
-static const int kTimeoutMs = 5000;
+// At most, AutoDetectProxy should take ~6 seconds. Each connect step is
+// allotted 2 seconds, with the initial resolution + connect given an
+// extra 2 seconds. The slowest case is:
+// 1) Resolution + HTTPS takes full 4 seconds and fails (but resolution
+// succeeds).
+// 2) SOCKS5 takes the full 2 seconds.
+// Socket creation time seems unbounded, and has been observed to take >1 second
+// on a linux machine under load. As such, we allow for 10 seconds for timeout,
+// though could still end up with some flakiness.
+static const int kTimeoutMs = 10000;
class AutoDetectProxyTest : public testing::Test, public sigslot::has_slots<> {
public:
diff --git a/base/httpclient.cc b/base/httpclient.cc
index 5a16676..5bee911 100644
--- a/base/httpclient.cc
+++ b/base/httpclient.cc
@@ -316,11 +316,11 @@
base_.abort(HE_OPERATION_CANCELLED);
}
-void HttpClient::OnResolveResult(SignalThread* thread) {
- if (thread != resolver_) {
+void HttpClient::OnResolveResult(AsyncResolverInterface* resolver) {
+ if (resolver != resolver_) {
return;
}
- int error = resolver_->error();
+ int error = resolver_->GetError();
server_ = resolver_->address();
resolver_->Destroy(false);
resolver_ = NULL;
@@ -335,9 +335,8 @@
void HttpClient::StartDNSLookup() {
resolver_ = new AsyncResolver();
- resolver_->set_address(server_);
- resolver_->SignalWorkDone.connect(this, &HttpClient::OnResolveResult);
- resolver_->Start();
+ resolver_->SignalDone.connect(this, &HttpClient::OnResolveResult);
+ resolver_->Start(server_);
}
void HttpClient::set_server(const SocketAddress& address) {
diff --git a/base/httpclient.h b/base/httpclient.h
index 2e77b0d..03deb22 100644
--- a/base/httpclient.h
+++ b/base/httpclient.h
@@ -175,7 +175,7 @@
HttpError OnHeaderAvailable(bool ignore_data, bool chunked, size_t data_size);
void StartDNSLookup();
- void OnResolveResult(SignalThread* thread);
+ void OnResolveResult(AsyncResolverInterface* resolver);
// IHttpNotify Interface
virtual HttpError onHttpHeaderComplete(bool chunked, size_t& data_size);
@@ -199,7 +199,7 @@
scoped_ptr<HttpAuthContext> context_;
DiskCache* cache_;
CacheState cache_state_;
- AsyncResolver* resolver_;
+ AsyncResolverInterface* resolver_;
};
//////////////////////////////////////////////////////////////////////
diff --git a/base/latebindingsymboltable.cc b/base/latebindingsymboltable.cc
index 2226219..433844e 100644
--- a/base/latebindingsymboltable.cc
+++ b/base/latebindingsymboltable.cc
@@ -109,7 +109,23 @@
}
#ifdef POSIX
- handle_ = dlopen(dll_path, RTLD_NOW);
+ handle_ = dlopen(dll_path,
+ // RTLD_NOW front-loads symbol resolution so that errors are
+ // caught early instead of causing a process abort later.
+ // RTLD_LOCAL prevents other modules from automatically
+ // seeing symbol definitions in the newly-loaded tree. This
+ // is necessary for same-named symbols in different ABI
+ // versions of the same library to not explode.
+ RTLD_NOW|RTLD_LOCAL
+#ifdef LINUX
+ // RTLD_DEEPBIND makes symbol dependencies in the
+ // newly-loaded tree prefer to resolve to definitions within
+ // that tree (the default on OS X). This is necessary for
+ // same-named symbols in different ABI versions of the same
+ // library to not explode.
+ |RTLD_DEEPBIND
+#endif
+ ); // NOLINT
#else
#error Not implemented
#endif
diff --git a/base/libdbusglibsymboltable.cc b/base/libdbusglibsymboltable.cc
index 9c4be7f..6a3ebf3 100644
--- a/base/libdbusglibsymboltable.cc
+++ b/base/libdbusglibsymboltable.cc
@@ -33,7 +33,7 @@
#define LATE_BINDING_SYMBOL_TABLE_CLASS_NAME LIBDBUS_GLIB_CLASS_NAME
#define LATE_BINDING_SYMBOL_TABLE_SYMBOLS_LIST LIBDBUS_GLIB_SYMBOLS_LIST
-#define LATE_BINDING_SYMBOL_TABLE_DLL_NAME "libdbus-glib-1.so"
+#define LATE_BINDING_SYMBOL_TABLE_DLL_NAME "libdbus-glib-1.so.2"
#include "talk/base/latebindingsymboltable.cc.def"
} // namespace talk_base
diff --git a/base/macasyncsocket.cc b/base/macasyncsocket.cc
index 54ad604..7841b4b 100644
--- a/base/macasyncsocket.cc
+++ b/base/macasyncsocket.cc
@@ -87,7 +87,7 @@
if (thread != resolver_) {
return;
}
- int error = resolver_->error();
+ int error = resolver_->GetError();
if (error == 0) {
error = DoConnect(resolver_->address());
} else {
@@ -109,10 +109,9 @@
if (addr.IsUnresolved()) {
LOG(LS_VERBOSE) << "Resolving addr in MacAsyncSocket::Connect";
resolver_ = new AsyncResolver();
- resolver_->set_address(addr);
resolver_->SignalWorkDone.connect(this,
&MacAsyncSocket::OnResolveResult);
- resolver_->Start();
+ resolver_->Start(addr);
state_ = CS_CONNECTING;
return 0;
}
diff --git a/base/nethelpers.cc b/base/nethelpers.cc
index 05e02c9..e6310ac 100644
--- a/base/nethelpers.cc
+++ b/base/nethelpers.cc
@@ -67,7 +67,27 @@
}
// AsyncResolver
-AsyncResolver::AsyncResolver() : error_(0) {
+AsyncResolver::AsyncResolver() : error_(-1) {
+}
+
+void AsyncResolver::Start(const SocketAddress& addr) {
+ addr_ = addr;
+ // SignalThred Start will kickoff the resolve process.
+ SignalThread::Start();
+}
+
+bool AsyncResolver::GetResolvedAddress(int family, SocketAddress* addr) const {
+ if (error_ != 0 || addresses_.empty())
+ return false;
+
+ *addr = addr_;
+ for (size_t i = 0; i < addresses_.size(); ++i) {
+ if (family == addresses_[i].family()) {
+ addr->SetIP(addresses_[i]);
+ return true;
+ }
+ }
+ return false;
}
void AsyncResolver::DoWork() {
@@ -76,9 +96,7 @@
}
void AsyncResolver::OnWorkDone() {
- if (addresses_.size() > 0) {
- addr_.SetIP(addresses_[0]);
- }
+ SignalDone(this);
}
const char* inet_ntop(int af, const void *src, char* dst, socklen_t size) {
diff --git a/base/nethelpers.h b/base/nethelpers.h
index 66f7910..a49f48a 100644
--- a/base/nethelpers.h
+++ b/base/nethelpers.h
@@ -37,25 +37,30 @@
#include <list>
+#include "talk/base/asyncresolverinterface.h"
#include "talk/base/signalthread.h"
#include "talk/base/sigslot.h"
#include "talk/base/socketaddress.h"
namespace talk_base {
+class AsyncResolverTest;
+
// AsyncResolver will perform async DNS resolution, signaling the result on
-// the inherited SignalWorkDone when the operation completes.
-class AsyncResolver : public SignalThread {
+// the SignalDone from AsyncResolverInterface when the operation completes.
+class AsyncResolver : public SignalThread, public AsyncResolverInterface {
public:
AsyncResolver();
+ virtual ~AsyncResolver() {}
- const SocketAddress& address() const { return addr_; }
+ virtual void Start(const SocketAddress& addr);
+ virtual bool GetResolvedAddress(int family, SocketAddress* addr) const;
+ virtual int GetError() const { return error_; }
+ virtual void Destroy(bool wait) { SignalThread::Destroy(wait); }
+
const std::vector<IPAddress>& addresses() const { return addresses_; }
- void set_address(const SocketAddress& addr) { addr_ = addr; }
- int error() const { return error_; }
void set_error(int error) { error_ = error; }
-
protected:
virtual void DoWork();
virtual void OnWorkDone();
diff --git a/base/physicalsocketserver.cc b/base/physicalsocketserver.cc
index 58a22fa..43be440 100644
--- a/base/physicalsocketserver.cc
+++ b/base/physicalsocketserver.cc
@@ -200,9 +200,8 @@
if (addr.IsUnresolved()) {
LOG(LS_VERBOSE) << "Resolving addr in PhysicalSocket::Connect";
resolver_ = new AsyncResolver();
- resolver_->set_address(addr);
- resolver_->SignalWorkDone.connect(this, &PhysicalSocket::OnResolveResult);
- resolver_->Start();
+ resolver_->SignalDone.connect(this, &PhysicalSocket::OnResolveResult);
+ resolver_->Start(addr);
state_ = CS_CONNECTING;
return 0;
}
@@ -476,12 +475,12 @@
SocketServer* socketserver() { return ss_; }
protected:
- void OnResolveResult(SignalThread* thread) {
- if (thread != resolver_) {
+ void OnResolveResult(AsyncResolverInterface* resolver) {
+ if (resolver != resolver_) {
return;
}
- int error = resolver_->error();
+ int error = resolver_->GetError();
if (error == 0) {
error = DoConnect(resolver_->address());
} else {
diff --git a/examples/peerconnection/client/peer_connection_client.cc b/examples/peerconnection/client/peer_connection_client.cc
index 403fabd..9cdaedc 100644
--- a/examples/peerconnection/client/peer_connection_client.cc
+++ b/examples/peerconnection/client/peer_connection_client.cc
@@ -134,17 +134,16 @@
if (server_address_.IsUnresolved()) {
state_ = RESOLVING;
resolver_ = new talk_base::AsyncResolver();
- resolver_->SignalWorkDone.connect(this,
- &PeerConnectionClient::OnResolveResult);
- resolver_->set_address(server_address_);
- resolver_->Start();
+ resolver_->SignalDone.connect(this, &PeerConnectionClient::OnResolveResult);
+ resolver_->Start(server_address_);
} else {
DoConnect();
}
}
-void PeerConnectionClient::OnResolveResult(talk_base::SignalThread *t) {
- if (resolver_->error() != 0) {
+void PeerConnectionClient::OnResolveResult(
+ talk_base::AsyncResolverInterface* resolver) {
+ if (resolver_->GetError() != 0) {
callback_->OnServerConnectionFailure();
resolver_->Destroy(false);
resolver_ = NULL;
diff --git a/examples/peerconnection/client/peer_connection_client.h b/examples/peerconnection/client/peer_connection_client.h
index d31262b..43fee34 100644
--- a/examples/peerconnection/client/peer_connection_client.h
+++ b/examples/peerconnection/client/peer_connection_client.h
@@ -121,7 +121,7 @@
void OnClose(talk_base::AsyncSocket* socket, int err);
- void OnResolveResult(talk_base::SignalThread *t);
+ void OnResolveResult(talk_base::AsyncResolverInterface* resolver);
PeerConnectionClientObserver* callback_;
talk_base::SocketAddress server_address_;
diff --git a/libjingle.gyp b/libjingle.gyp
index 16044b5..4cbeaa3 100755
--- a/libjingle.gyp
+++ b/libjingle.gyp
@@ -257,6 +257,7 @@
'base/asynchttprequest.cc',
'base/asynchttprequest.h',
'base/asyncpacketsocket.h',
+ 'base/asyncresolverinterface.h',
'base/asyncsocket.cc',
'base/asyncsocket.h',
'base/asynctcpsocket.cc',
diff --git a/libjingle_tests.gyp b/libjingle_tests.gyp
index 80e1e96..44fa8f7 100755
--- a/libjingle_tests.gyp
+++ b/libjingle_tests.gyp
@@ -375,7 +375,7 @@
],
# TODO(ronghuawu): Reenable below unit tests that require gmock.
'sources': [
- 'app/webrtc/datachannel_unittest.cc',
+ # 'app/webrtc/datachannel_unittest.cc',
'app/webrtc/dtmfsender_unittest.cc',
'app/webrtc/jsepsessiondescription_unittest.cc',
'app/webrtc/localaudiosource_unittest.cc',
diff --git a/media/devices/libudevsymboltable.cc b/media/devices/libudevsymboltable.cc
index 9620cd2..20154e1 100644
--- a/media/devices/libudevsymboltable.cc
+++ b/media/devices/libudevsymboltable.cc
@@ -42,7 +42,8 @@
#undef LATE_BINDING_SYMBOL_TABLE_DLL_NAME
bool IsWrongLibUDevAbiVersion(talk_base::DllHandle libudev_0) {
- talk_base::DllHandle libudev_1 = dlopen("libudev.so.1", RTLD_NOW|RTLD_NOLOAD);
+ talk_base::DllHandle libudev_1 = dlopen("libudev.so.1",
+ RTLD_NOW|RTLD_LOCAL|RTLD_NOLOAD);
bool unsafe_symlink = (libudev_0 == libudev_1);
if (unsafe_symlink) {
// .0 and .1 are distinct ABIs, so if they point to the same thing then one
@@ -55,7 +56,8 @@
// system library loaded the new ABI separately. This is not a problem for
// LateBindingSymbolTable because its symbol look-ups are restricted to its
// DllHandle, but having libudev.so.0 resident may cause problems for that
- // system library because symbol names are not namespaced by DLL.
+ // system library because symbol names are not namespaced by DLL. (Although
+ // our use of RTLD_LOCAL should avoid most problems.)
LOG(LS_WARNING)
<< "libudev.so.1 is resident but distinct from libudev.so.0";
}
diff --git a/media/webrtc/webrtcvideoengine.cc b/media/webrtc/webrtcvideoengine.cc
index ec38eea..6032134 100644
--- a/media/webrtc/webrtcvideoengine.cc
+++ b/media/webrtc/webrtcvideoengine.cc
@@ -3219,7 +3219,8 @@
LOG_RTCERR1(SetNACKStatus, channel_id);
return false;
}
- LOG(LS_INFO) << "NACK enabled for channel " << channel_id;
+ std::string enabled = nack_enabled ? "enabled" : "disabled";
+ LOG(LS_INFO) << "NACK " << enabled << " for channel " << channel_id;
}
return true;
}
diff --git a/media/webrtc/webrtcvoiceengine.cc b/media/webrtc/webrtcvoiceengine.cc
index ac8e067..4911c59 100644
--- a/media/webrtc/webrtcvoiceengine.cc
+++ b/media/webrtc/webrtcvoiceengine.cc
@@ -3065,9 +3065,12 @@
static_cast<float>(ns.currentExpandRate) / (1 << 14);
}
if (engine()->voe()->sync()) {
+ int jitter_buffer_delay_ms = 0;
int playout_buffer_delay_ms = 0;
engine()->voe()->sync()->GetDelayEstimate(
- *it, &rinfo.delay_estimate_ms, &playout_buffer_delay_ms);
+ *it, &jitter_buffer_delay_ms, &playout_buffer_delay_ms);
+ rinfo.delay_estimate_ms = jitter_buffer_delay_ms +
+ playout_buffer_delay_ms;
}
// Get speech level.
diff --git a/p2p/base/basicpacketsocketfactory.cc b/p2p/base/basicpacketsocketfactory.cc
index 565aed3..758d492 100644
--- a/p2p/base/basicpacketsocketfactory.cc
+++ b/p2p/base/basicpacketsocketfactory.cc
@@ -30,6 +30,9 @@
#include "talk/base/asyncudpsocket.h"
#include "talk/base/asynctcpsocket.h"
#include "talk/base/logging.h"
+#include "talk/base/nethelpers.h"
+#include "talk/base/physicalsocketserver.h"
+#include "talk/base/scoped_ptr.h"
#include "talk/base/socketadapters.h"
#include "talk/base/thread.h"
#include "talk/p2p/base/asyncstuntcpsocket.h"
@@ -174,6 +177,10 @@
return tcp_socket;
}
+AsyncResolverInterface* BasicPacketSocketFactory::CreateAsyncResolver() {
+ return new talk_base::AsyncResolver();
+}
+
int BasicPacketSocketFactory::BindSocket(
AsyncSocket* socket, const SocketAddress& local_address,
int min_port, int max_port) {
diff --git a/p2p/base/basicpacketsocketfactory.h b/p2p/base/basicpacketsocketfactory.h
index d4e76e7..27963c9 100644
--- a/p2p/base/basicpacketsocketfactory.h
+++ b/p2p/base/basicpacketsocketfactory.h
@@ -51,6 +51,8 @@
const SocketAddress& local_address, const SocketAddress& remote_address,
const ProxyInfo& proxy_info, const std::string& user_agent, int opts);
+ virtual AsyncResolverInterface* CreateAsyncResolver();
+
private:
int BindSocket(AsyncSocket* socket, const SocketAddress& local_address,
int min_port, int max_port);
diff --git a/p2p/base/packetsocketfactory.h b/p2p/base/packetsocketfactory.h
index 882a974..e985b37 100644
--- a/p2p/base/packetsocketfactory.h
+++ b/p2p/base/packetsocketfactory.h
@@ -33,6 +33,7 @@
namespace talk_base {
class AsyncPacketSocket;
+class AsyncResolverInterface;
class PacketSocketFactory {
public:
@@ -57,6 +58,8 @@
const SocketAddress& local_address, const SocketAddress& remote_address,
const ProxyInfo& proxy_info, const std::string& user_agent, int opts) = 0;
+ virtual AsyncResolverInterface* CreateAsyncResolver() = 0;
+
private:
DISALLOW_EVIL_CONSTRUCTORS(PacketSocketFactory);
};
diff --git a/p2p/base/port.cc b/p2p/base/port.cc
index 6e688da..7d52386 100644
--- a/p2p/base/port.cc
+++ b/p2p/base/port.cc
@@ -162,11 +162,11 @@
return talk_base::ToString<uint32>(talk_base::ComputeCrc32(ost.str()));
}
-Port::Port(talk_base::Thread* thread, talk_base::Network* network,
- const talk_base::IPAddress& ip,
+Port::Port(talk_base::Thread* thread, talk_base::PacketSocketFactory* factory,
+ talk_base::Network* network, const talk_base::IPAddress& ip,
const std::string& username_fragment, const std::string& password)
: thread_(thread),
- factory_(NULL),
+ factory_(factory),
send_retransmit_count_attribute_(false),
network_(network),
ip_(ip),
diff --git a/p2p/base/port.h b/p2p/base/port.h
index 7b89e55..ab7fded 100644
--- a/p2p/base/port.h
+++ b/p2p/base/port.h
@@ -118,8 +118,8 @@
class Port : public PortInterface, public talk_base::MessageHandler,
public sigslot::has_slots<> {
public:
- Port(talk_base::Thread* thread, talk_base::Network* network,
- const talk_base::IPAddress& ip,
+ Port(talk_base::Thread* thread, talk_base::PacketSocketFactory* factory,
+ talk_base::Network* network, const talk_base::IPAddress& ip,
const std::string& username_fragment, const std::string& password);
Port(talk_base::Thread* thread, const std::string& type,
talk_base::PacketSocketFactory* factory,
diff --git a/p2p/base/port_unittest.cc b/p2p/base/port_unittest.cc
index 1cc3049..a527155 100644
--- a/p2p/base/port_unittest.cc
+++ b/p2p/base/port_unittest.cc
@@ -766,6 +766,9 @@
void set_next_client_tcp_socket(AsyncPacketSocket* next_client_tcp_socket) {
next_client_tcp_socket_ = next_client_tcp_socket;
}
+ talk_base::AsyncResolverInterface* CreateAsyncResolver() {
+ return NULL;
+ }
private:
AsyncPacketSocket* next_udp_socket_;
diff --git a/p2p/base/stunport.cc b/p2p/base/stunport.cc
index b440bf4..283eade 100644
--- a/p2p/base/stunport.cc
+++ b/p2p/base/stunport.cc
@@ -125,10 +125,11 @@
};
UDPPort::UDPPort(talk_base::Thread* thread,
+ talk_base::PacketSocketFactory* factory,
talk_base::Network* network,
talk_base::AsyncPacketSocket* socket,
const std::string& username, const std::string& password)
- : Port(thread, network, socket->GetLocalAddress().ipaddr(),
+ : Port(thread, factory, network, socket->GetLocalAddress().ipaddr(),
username, password),
requests_(thread),
socket_(socket),
@@ -139,10 +140,10 @@
}
UDPPort::UDPPort(talk_base::Thread* thread,
- talk_base::PacketSocketFactory* factory,
- talk_base::Network* network,
- const talk_base::IPAddress& ip, int min_port, int max_port,
- const std::string& username, const std::string& password)
+ talk_base::PacketSocketFactory* factory,
+ talk_base::Network* network,
+ const talk_base::IPAddress& ip, int min_port, int max_port,
+ const std::string& username, const std::string& password)
: Port(thread, LOCAL_PORT_TYPE, factory, network, ip, min_port, max_port,
username, password),
requests_(thread),
@@ -302,21 +303,21 @@
if (resolver_)
return;
- resolver_ = new talk_base::AsyncResolver();
- resolver_->SignalWorkDone.connect(this, &UDPPort::OnResolveResult);
- resolver_->set_address(server_addr_);
- resolver_->Start();
+ resolver_ = socket_factory()->CreateAsyncResolver();
+ resolver_->SignalDone.connect(this, &UDPPort::OnResolveResult);
+ resolver_->Start(server_addr_);
}
-void UDPPort::OnResolveResult(talk_base::SignalThread* t) {
- ASSERT(t == resolver_);
- if (resolver_->error() != 0) {
+void UDPPort::OnResolveResult(talk_base::AsyncResolverInterface* resolver) {
+ ASSERT(resolver == resolver_);
+ if (resolver_->GetError() != 0 ||
+ !resolver_->GetResolvedAddress(ip().family(), &server_addr_)) {
LOG_J(LS_WARNING, this) << "StunPort: stun host lookup received error "
- << resolver_->error();
+ << resolver_->GetError();
OnStunBindingOrResolveRequestFailed();
+ return;
}
- server_addr_ = resolver_->address();
SendStunBindingRequest();
}
diff --git a/p2p/base/stunport.h b/p2p/base/stunport.h
index 7cfed4b..8f72556 100644
--- a/p2p/base/stunport.h
+++ b/p2p/base/stunport.h
@@ -46,11 +46,13 @@
class UDPPort : public Port {
public:
static UDPPort* Create(talk_base::Thread* thread,
+ talk_base::PacketSocketFactory* factory,
talk_base::Network* network,
talk_base::AsyncPacketSocket* socket,
const std::string& username,
const std::string& password) {
- UDPPort* port = new UDPPort(thread, network, socket, username, password);
+ UDPPort* port = new UDPPort(thread, factory, network, socket,
+ username, password);
if (!port->Init()) {
delete port;
port = NULL;
@@ -66,8 +68,8 @@
const std::string& username,
const std::string& password) {
UDPPort* port = new UDPPort(thread, factory, network,
- ip, min_port, max_port,
- username, password);
+ ip, min_port, max_port,
+ username, password);
if (!port->Init()) {
delete port;
port = NULL;
@@ -114,8 +116,8 @@
int min_port, int max_port,
const std::string& username, const std::string& password);
- UDPPort(talk_base::Thread* thread, talk_base::Network* network,
- talk_base::AsyncPacketSocket* socket,
+ UDPPort(talk_base::Thread* thread, talk_base::PacketSocketFactory* factory,
+ talk_base::Network* network, talk_base::AsyncPacketSocket* socket,
const std::string& username, const std::string& password);
bool Init();
@@ -141,7 +143,7 @@
private:
// DNS resolution of the STUN server.
void ResolveStunAddress();
- void OnResolveResult(talk_base::SignalThread* thread);
+ void OnResolveResult(talk_base::AsyncResolverInterface* resolver);
// Below methods handles binding request responses.
void OnStunBindingRequestSucceeded(const talk_base::SocketAddress& stun_addr);
@@ -158,7 +160,7 @@
StunRequestManager requests_;
talk_base::AsyncPacketSocket* socket_;
int error_;
- talk_base::AsyncResolver* resolver_;
+ talk_base::AsyncResolverInterface* resolver_;
bool ready_;
int stun_keepalive_delay_;
diff --git a/p2p/base/stunport_unittest.cc b/p2p/base/stunport_unittest.cc
index 3c1c683..12b32db 100644
--- a/p2p/base/stunport_unittest.cc
+++ b/p2p/base/stunport_unittest.cc
@@ -27,7 +27,10 @@
#include "talk/base/gunit.h"
#include "talk/base/helpers.h"
+#include "talk/base/physicalsocketserver.h"
+#include "talk/base/scoped_ptr.h"
#include "talk/base/socketaddress.h"
+#include "talk/base/virtualsocketserver.h"
#include "talk/p2p/base/basicpacketsocketfactory.h"
#include "talk/p2p/base/stunport.h"
#include "talk/p2p/base/teststunserver.h"
@@ -48,7 +51,10 @@
public sigslot::has_slots<> {
public:
StunPortTest()
- : network_("unittest", "unittest", talk_base::IPAddress(INADDR_ANY), 32),
+ : pss_(new talk_base::PhysicalSocketServer),
+ ss_(new talk_base::VirtualSocketServer(pss_.get())),
+ ss_scope_(ss_.get()),
+ network_("unittest", "unittest", talk_base::IPAddress(INADDR_ANY), 32),
socket_factory_(talk_base::Thread::Current()),
stun_server_(new cricket::TestStunServer(
talk_base::Thread::Current(), kStunAddr)),
@@ -77,7 +83,8 @@
ASSERT_TRUE(socket_ != NULL);
socket_->SignalReadPacket.connect(this, &StunPortTest::OnReadPacket);
stun_port_.reset(cricket::UDPPort::Create(
- talk_base::Thread::Current(), &network_, socket_.get(),
+ talk_base::Thread::Current(), &socket_factory_,
+ &network_, socket_.get(),
talk_base::CreateRandomString(16), talk_base::CreateRandomString(22)));
ASSERT_TRUE(stun_port_ != NULL);
stun_port_->set_server_addr(server_addr);
@@ -120,6 +127,9 @@
}
private:
+ talk_base::scoped_ptr<talk_base::PhysicalSocketServer> pss_;
+ talk_base::scoped_ptr<talk_base::VirtualSocketServer> ss_;
+ talk_base::SocketServerScope ss_scope_;
talk_base::Network network_;
talk_base::BasicPacketSocketFactory socket_factory_;
talk_base::scoped_ptr<cricket::UDPPort> stun_port_;
diff --git a/p2p/base/turnport.cc b/p2p/base/turnport.cc
index 880af83..14388e3 100644
--- a/p2p/base/turnport.cc
+++ b/p2p/base/turnport.cc
@@ -399,22 +399,21 @@
if (resolver_)
return;
- resolver_ = new talk_base::AsyncResolver();
- resolver_->SignalWorkDone.connect(this, &TurnPort::OnResolveResult);
- resolver_->set_address(address);
- resolver_->Start();
+ resolver_ = socket_factory()->CreateAsyncResolver();
+ resolver_->SignalDone.connect(this, &TurnPort::OnResolveResult);
+ resolver_->Start(address);
}
-void TurnPort::OnResolveResult(talk_base::SignalThread* signal_thread) {
- ASSERT(signal_thread == resolver_);
- if (resolver_->error() != 0) {
+void TurnPort::OnResolveResult(talk_base::AsyncResolverInterface* resolver) {
+ ASSERT(resolver == resolver_);
+ if (resolver_->GetError() != 0 ||
+ !resolver_->GetResolvedAddress(ip().family(), &server_address_.address)) {
LOG_J(LS_WARNING, this) << "TURN host lookup received error "
- << resolver_->error();
+ << resolver_->GetError();
OnAllocateError();
return;
}
- server_address_.address = resolver_->address();
PrepareAddress();
}
diff --git a/p2p/base/turnport.h b/p2p/base/turnport.h
index 4462b0c..e5c03da 100644
--- a/p2p/base/turnport.h
+++ b/p2p/base/turnport.h
@@ -123,7 +123,7 @@
}
void ResolveTurnAddress(const talk_base::SocketAddress& address);
- void OnResolveResult(talk_base::SignalThread* signal_thread);
+ void OnResolveResult(talk_base::AsyncResolverInterface* resolver);
void AddRequestAuthInfo(StunMessage* msg);
void OnSendStunPacket(const void* data, size_t size, StunRequest* request);
@@ -157,7 +157,7 @@
talk_base::scoped_ptr<talk_base::AsyncPacketSocket> socket_;
SocketOptionsMap socket_options_;
- talk_base::AsyncResolver* resolver_;
+ talk_base::AsyncResolverInterface* resolver_;
int error_;
StunRequestManager request_manager_;
diff --git a/p2p/client/basicportallocator.cc b/p2p/client/basicportallocator.cc
index 9f10d33..a5310b7 100644
--- a/p2p/client/basicportallocator.cc
+++ b/p2p/client/basicportallocator.cc
@@ -857,7 +857,8 @@
// is enabled completely.
UDPPort* port = NULL;
if (IsFlagSet(PORTALLOCATOR_ENABLE_SHARED_SOCKET) && udp_socket_) {
- port = UDPPort::Create(session_->network_thread(), network_,
+ port = UDPPort::Create(session_->network_thread(),
+ session_->socket_factory(), network_,
udp_socket_.get(),
session_->username(), session_->password());
} else {