Fix an issue in IPv6 support.
When creating connections on turn port, check whether the local and remote candidates have the same IP address family, instead of checking the address family of the local socket against the remote candidate. BUG=5871 R=deadbeef@webrtc.org, pthatcher@webrtc.org Review URL: https://codereview.webrtc.org/2083803002 . Cr-Commit-Position: refs/heads/master@{#13269}
This commit is contained in:
parent
14f97f5bc6
commit
f4ae6dc763
@ -291,7 +291,7 @@ void TurnPort::PrepareAddress() {
|
||||
if (!IsCompatibleAddress(server_address_.address)) {
|
||||
LOG(LS_ERROR) << "IP address family does not match: "
|
||||
<< "server: " << server_address_.address.family()
|
||||
<< "local: " << ip().family();
|
||||
<< " local: " << ip().family();
|
||||
OnAllocateError();
|
||||
return;
|
||||
}
|
||||
@ -438,14 +438,10 @@ void TurnPort::OnAllocateMismatch() {
|
||||
++allocate_mismatch_retries_;
|
||||
}
|
||||
|
||||
Connection* TurnPort::CreateConnection(const Candidate& address,
|
||||
Connection* TurnPort::CreateConnection(const Candidate& remote_candidate,
|
||||
CandidateOrigin origin) {
|
||||
// TURN-UDP can only connect to UDP candidates.
|
||||
if (!SupportsProtocol(address.protocol())) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!IsCompatibleAddress(address.address())) {
|
||||
if (!SupportsProtocol(remote_candidate.protocol())) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -453,15 +449,19 @@ Connection* TurnPort::CreateConnection(const Candidate& address,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Create an entry, if needed, so we can get our permissions set up correctly.
|
||||
CreateOrRefreshEntry(address.address());
|
||||
|
||||
// A TURN port will have two candiates, STUN and TURN. STUN may not
|
||||
// present in all cases. If present stun candidate will be added first
|
||||
// and TURN candidate later.
|
||||
for (size_t index = 0; index < Candidates().size(); ++index) {
|
||||
if (Candidates()[index].type() == RELAY_PORT_TYPE) {
|
||||
ProxyConnection* conn = new ProxyConnection(this, index, address);
|
||||
const Candidate& local_candidate = Candidates()[index];
|
||||
if (local_candidate.type() == RELAY_PORT_TYPE &&
|
||||
local_candidate.address().family() ==
|
||||
remote_candidate.address().family()) {
|
||||
// Create an entry, if needed, so we can get our permissions set up
|
||||
// correctly.
|
||||
CreateOrRefreshEntry(remote_candidate.address());
|
||||
ProxyConnection* conn =
|
||||
new ProxyConnection(this, index, remote_candidate);
|
||||
AddOrReplaceConnection(conn);
|
||||
return conn;
|
||||
}
|
||||
|
||||
@ -44,6 +44,8 @@ static const SocketAddress kLocalAddr1("11.11.11.11", 0);
|
||||
static const SocketAddress kLocalAddr2("22.22.22.22", 0);
|
||||
static const SocketAddress kLocalIPv6Addr(
|
||||
"2401:fa00:4:1000:be30:5bff:fee5:c3", 0);
|
||||
static const SocketAddress kLocalIPv6Addr2(
|
||||
"2401:fa00:4:2000:be30:5bff:fee5:d4", 0);
|
||||
static const SocketAddress kTurnUdpIntAddr("99.99.99.3",
|
||||
cricket::TURN_SERVER_PORT);
|
||||
static const SocketAddress kTurnTcpIntAddr("99.99.99.4",
|
||||
@ -58,9 +60,8 @@ static const SocketAddress kTurnIPv6IntAddr(
|
||||
cricket::TURN_SERVER_PORT);
|
||||
static const SocketAddress kTurnUdpIPv6IntAddr(
|
||||
"2400:4030:1:2c00:be30:abcd:efab:cdef", cricket::TURN_SERVER_PORT);
|
||||
static const SocketAddress kTurnUdpIPv6ExtAddr(
|
||||
"2620:0:1000:1b03:2e41:38ff:fea6:f2a4", 0);
|
||||
|
||||
static const char kCandidateFoundation[] = "foundation";
|
||||
static const char kIceUfrag1[] = "TESTICEUFRAG0001";
|
||||
static const char kIceUfrag2[] = "TESTICEUFRAG0002";
|
||||
static const char kIcePwd1[] = "TESTICEPWD00000000000001";
|
||||
@ -596,7 +597,7 @@ TEST_F(TurnPortTest, DISABLED_TestTurnTcpOnAddressResolveFailure) {
|
||||
|
||||
// In case of UDP on address resolve failure, TurnPort will not create socket
|
||||
// and return allocate failure.
|
||||
TEST_F(TurnPortTest, DISABLED_TestTurnUdpOnAdressResolveFailure) {
|
||||
TEST_F(TurnPortTest, DISABLED_TestTurnUdpOnAddressResolveFailure) {
|
||||
CreateTurnPort(kTurnUsername, kTurnPassword, cricket::ProtocolAddress(
|
||||
rtc::SocketAddress("www.webrtc-blah-blah.com", 3478),
|
||||
cricket::PROTO_UDP));
|
||||
@ -1014,6 +1015,35 @@ TEST_F(TurnPortTest, TestTurnLocalIPv6AddressServerIPv6ExtenalIPv4) {
|
||||
EXPECT_NE(0, turn_port_->Candidates()[0].address().port());
|
||||
}
|
||||
|
||||
// Tests that the local and remote candidate address families should match when
|
||||
// a connection is created. Specifically, if a TURN port has an IPv6 address,
|
||||
// its local candidate will still be an IPv4 address and it can only create
|
||||
// connections with IPv4 remote candidates.
|
||||
TEST_F(TurnPortTest, TestCandidateAddressFamilyMatch) {
|
||||
turn_server_.AddInternalSocket(kTurnUdpIPv6IntAddr, cricket::PROTO_UDP);
|
||||
|
||||
CreateTurnPort(kLocalIPv6Addr, kTurnUsername, kTurnPassword,
|
||||
kTurnUdpIPv6ProtoAddr);
|
||||
turn_port_->PrepareAddress();
|
||||
EXPECT_TRUE_WAIT(turn_ready_, kTimeout);
|
||||
ASSERT_EQ(1U, turn_port_->Candidates().size());
|
||||
|
||||
// Create an IPv4 candidate. It will match the TURN candidate.
|
||||
cricket::Candidate remote_candidate(cricket::ICE_CANDIDATE_COMPONENT_RTP,
|
||||
"udp", kLocalAddr2, 0, "", "", "local", 0,
|
||||
kCandidateFoundation);
|
||||
remote_candidate.set_address(kLocalAddr2);
|
||||
Connection* conn =
|
||||
turn_port_->CreateConnection(remote_candidate, Port::ORIGIN_MESSAGE);
|
||||
EXPECT_NE(nullptr, conn);
|
||||
|
||||
// Set the candidate address family to IPv6. It won't match the TURN
|
||||
// candidate.
|
||||
remote_candidate.set_address(kLocalIPv6Addr2);
|
||||
conn = turn_port_->CreateConnection(remote_candidate, Port::ORIGIN_MESSAGE);
|
||||
EXPECT_EQ(nullptr, conn);
|
||||
}
|
||||
|
||||
TEST_F(TurnPortTest, TestOriginHeader) {
|
||||
CreateTurnPortWithOrigin(kLocalAddr1, kTurnUsername, kTurnPassword,
|
||||
kTurnUdpProtoAddr, kTestOrigin);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user