Add the URL attribute to cricket::Candiate.

The URL of the ICE server will be reconstructed by the Port and the URL
attribute is added to the cricket::Candidate struct so that we can tell
which ICE server the candidate was gathered from.

This CL only changes the native C++ code. The Java and Objc wrapper will
be created in separate CLs.

BUG=webrtc::7128

Review-Url: https://codereview.webrtc.org/2685053004
Cr-Commit-Position: refs/heads/master@{#16591}
This commit is contained in:
zhihuang 2017-02-13 12:47:27 -08:00 committed by Commit bot
parent 9c9d95b2dc
commit 26d99c2e28
11 changed files with 88 additions and 11 deletions

View File

@ -161,7 +161,6 @@ class Candidate {
const std::string& foundation() const {
return foundation_;
}
void set_foundation(const std::string& foundation) {
foundation_ = foundation;
}
@ -184,6 +183,10 @@ class Candidate {
transport_name_ = transport_name;
}
// The URL of the ICE server which this candidate is gathered from.
const std::string& url() const { return url_; }
void set_url(const std::string& url) { url_ = url; }
// Determines whether this candidate is equivalent to the given one.
bool IsEquivalent(const Candidate& c) const {
// We ignore the network name, since that is just debug information, and
@ -284,6 +287,7 @@ class Candidate {
std::string transport_name_;
uint16_t network_id_;
uint16_t network_cost_;
std::string url_;
};
// Used during parsing and writing to map component to channel name

View File

@ -252,6 +252,7 @@ void Port::AddAddress(const rtc::SocketAddress& address,
const std::string& type,
uint32_t type_preference,
uint32_t relay_preference,
const std::string& url,
bool final) {
if (protocol == TCP_PROTOCOL_NAME && type == LOCAL_PORT_TYPE) {
RTC_DCHECK(!tcptype.empty());
@ -268,6 +269,7 @@ void Port::AddAddress(const rtc::SocketAddress& address,
c.set_network_name(network_->name());
c.set_network_type(network_->type());
c.set_related_address(related_address);
c.set_url(url);
candidates_.push_back(c);
SignalCandidateReady(this, c);

View File

@ -332,6 +332,7 @@ class Port : public PortInterface, public rtc::MessageHandler,
const std::string& type,
uint32_t type_preference,
uint32_t relay_preference,
const std::string& url,
bool final);
// Adds the given connection to the map keyed by the remote candidate address.

View File

@ -146,7 +146,7 @@ class TestPort : public Port {
virtual void PrepareAddress() {
rtc::SocketAddress addr(ip(), min_port());
AddAddress(addr, addr, rtc::SocketAddress(), "udp", "", "", Type(),
ICE_TYPE_PREFERENCE_HOST, 0, true);
ICE_TYPE_PREFERENCE_HOST, 0, "", true);
}
virtual bool SupportsProtocol(const std::string& protocol) const {
@ -158,7 +158,7 @@ class TestPort : public Port {
// Exposed for testing candidate building.
void AddCandidateAddress(const rtc::SocketAddress& addr) {
AddAddress(addr, addr, rtc::SocketAddress(), "udp", "", "", Type(),
type_preference_, 0, false);
type_preference_, 0, "", false);
}
void AddCandidateAddress(const rtc::SocketAddress& addr,
const rtc::SocketAddress& base_address,
@ -166,7 +166,7 @@ class TestPort : public Port {
int type_preference,
bool final) {
AddAddress(addr, base_address, rtc::SocketAddress(), "udp", "", "", type,
type_preference, 0, final);
type_preference, 0, "", final);
}
virtual Connection* CreateConnection(const Candidate& remote_candidate,

View File

@ -245,7 +245,7 @@ void RelayPort::SetReady() {
// address.
AddAddress(iter->address, iter->address, rtc::SocketAddress(), proto_name,
proto_name, "", RELAY_PORT_TYPE, ICE_TYPE_PREFERENCE_RELAY_UDP,
0, false);
0, "", false);
}
ready_ = true;
SignalPortComplete(this);

View File

@ -315,7 +315,7 @@ void UDPPort::OnLocalAddressReady(rtc::AsyncPacketSocket* socket,
MaybeSetDefaultLocalAddress(&addr);
AddAddress(addr, addr, rtc::SocketAddress(), UDP_PROTOCOL_NAME, "", "",
LOCAL_PORT_TYPE, ICE_TYPE_PREFERENCE_HOST, 0, false);
LOCAL_PORT_TYPE, ICE_TYPE_PREFERENCE_HOST, 0, "", false);
MaybePrepareStunCandidate();
}
@ -453,9 +453,12 @@ void UDPPort::OnStunBindingRequestSucceeded(
related_address.family());
}
std::ostringstream url;
url << "stun:" << stun_server_addr.ipaddr().ToString() << ":"
<< stun_server_addr.port();
AddAddress(stun_reflected_addr, socket_->GetLocalAddress(), related_address,
UDP_PROTOCOL_NAME, "", "", STUN_PORT_TYPE,
ICE_TYPE_PREFERENCE_SRFLX, 0, false);
ICE_TYPE_PREFERENCE_SRFLX, 0, url.str(), false);
}
MaybeSetPortCompleteOrError();
}

View File

@ -201,6 +201,8 @@ TEST_F(StunPortTest, TestPrepareAddress) {
EXPECT_TRUE_SIMULATED_WAIT(done(), kTimeoutMs, fake_clock);
ASSERT_EQ(1U, port()->Candidates().size());
EXPECT_TRUE(kLocalAddr.EqualIPs(port()->Candidates()[0].address()));
std::string expected_server_url = "stun:127.0.0.1:5000";
EXPECT_EQ(port()->Candidates()[0].url(), expected_server_url);
// TODO: Add IPv6 tests here, once either physicalsocketserver supports
// IPv6, or this test is changed to use VirtualSocketServer.

View File

@ -178,7 +178,7 @@ void TCPPort::PrepareAddress() {
AddAddress(socket_->GetLocalAddress(), socket_->GetLocalAddress(),
rtc::SocketAddress(), TCP_PROTOCOL_NAME, "",
TCPTYPE_PASSIVE_STR, LOCAL_PORT_TYPE,
ICE_TYPE_PREFERENCE_HOST_TCP, 0, true);
ICE_TYPE_PREFERENCE_HOST_TCP, 0, "", true);
} else {
LOG_J(LS_INFO, this) << "Not listening due to firewall restrictions.";
// Note: We still add the address, since otherwise the remote side won't
@ -188,7 +188,7 @@ void TCPPort::PrepareAddress() {
AddAddress(rtc::SocketAddress(ip(), DISCARD_PORT),
rtc::SocketAddress(ip(), 0), rtc::SocketAddress(),
TCP_PROTOCOL_NAME, "", TCPTYPE_ACTIVE_STR, LOCAL_PORT_TYPE,
ICE_TYPE_PREFERENCE_HOST_TCP, 0, true);
ICE_TYPE_PREFERENCE_HOST_TCP, 0, "", true);
}
}
@ -300,7 +300,7 @@ void TCPPort::OnAddressReady(rtc::AsyncPacketSocket* socket,
const rtc::SocketAddress& address) {
AddAddress(address, address, rtc::SocketAddress(), TCP_PROTOCOL_NAME, "",
TCPTYPE_PASSIVE_STR, LOCAL_PORT_TYPE, ICE_TYPE_PREFERENCE_HOST_TCP,
0, true);
0, "", true);
}
TCPConnection::TCPConnection(TCPPort* port,

View File

@ -745,7 +745,7 @@ void TurnPort::OnAllocateSuccess(const rtc::SocketAddress& address,
ProtoToString(server_address_.proto), // The first hop protocol.
"", // TCP canddiate type, empty for turn candidates.
RELAY_PORT_TYPE, GetRelayPreference(server_address_.proto),
server_priority_, true);
server_priority_, ReconstructedServerUrl(), true);
}
void TurnPort::OnAllocateError() {
@ -1073,6 +1073,34 @@ bool TurnPort::SetEntryChannelId(const rtc::SocketAddress& address,
return true;
}
std::string TurnPort::ReconstructedServerUrl() {
// draft-petithuguenin-behave-turn-uris-01
// turnURI = scheme ":" turn-host [ ":" turn-port ]
// [ "?transport=" transport ]
// scheme = "turn" / "turns"
// transport = "udp" / "tcp" / transport-ext
// transport-ext = 1*unreserved
// turn-host = IP-literal / IPv4address / reg-name
// turn-port = *DIGIT
std::string scheme = "turn";
std::string transport = "tcp";
switch (server_address_.proto) {
case PROTO_SSLTCP:
case PROTO_TLS:
scheme = "turns";
break;
case PROTO_UDP:
transport = "udp";
break;
case PROTO_TCP:
break;
}
std::ostringstream url;
url << scheme << ":" << server_address_.address.ipaddr().ToString() << ":"
<< server_address_.address.port() << "?transport=" << transport;
return url.str();
}
TurnAllocateRequest::TurnAllocateRequest(TurnPort* port)
: StunRequest(new TurnMessage()),
port_(port) {

View File

@ -260,6 +260,9 @@ class TurnPort : public Port {
// pruned (a.k.a. write-timed-out). Returns true if a connection is found.
bool FailAndPruneConnection(const rtc::SocketAddress& address);
// Reconstruct the URL of the server which the candidate is gathered from.
std::string ReconstructedServerUrl();
ProtocolAddress server_address_;
TlsCertPolicy tls_cert_policy_ = TlsCertPolicy::TLS_CERT_POLICY_SECURE;
RelayCredentials credentials_;

View File

@ -647,6 +647,40 @@ TEST_F(TurnPortTest, TestTurnPortType) {
EXPECT_EQ(cricket::RELAY_PORT_TYPE, turn_port_->Type());
}
// Tests that the URL of the servers can be correctly reconstructed when
// gathering the candidates.
TEST_F(TurnPortTest, TestReconstructedServerUrl) {
// Connect the TURN server using UDP.
CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
turn_port_->PrepareAddress();
EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 2, fake_clock_);
std::string expected_server_url = "turn:99.99.99.3:3478?transport=udp";
EXPECT_EQ(turn_port_->Candidates()[0].url(), expected_server_url);
// Connect the server with IPV6 using UDP.
turn_ready_ = false;
turn_server_.AddInternalSocket(kTurnUdpIPv6IntAddr, PROTO_UDP);
CreateTurnPort(kLocalIPv6Addr, kTurnUsername, kTurnPassword,
kTurnUdpIPv6ProtoAddr);
turn_port_->PrepareAddress();
EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 2, fake_clock_);
ASSERT_EQ(1U, turn_port_->Candidates().size());
expected_server_url =
"turn:2400:4030:1:2c00:be30:abcd:efab:cdef:3478?transport=udp";
EXPECT_EQ(turn_port_->Candidates()[0].url(), expected_server_url);
// Connection the server using TCP.
turn_ready_ = false;
turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
turn_port_->PrepareAddress();
EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 3, fake_clock_);
ASSERT_EQ(1U, turn_port_->Candidates().size());
expected_server_url = "turn:99.99.99.4:3478?transport=tcp";
EXPECT_EQ(turn_port_->Candidates()[0].url(), expected_server_url);
turn_ready_ = false;
}
// Do a normal TURN allocation.
TEST_F(TurnPortTest, TestTurnAllocate) {
CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);