| Index: webrtc/p2p/base/turnport_unittest.cc
|
| diff --git a/webrtc/p2p/base/turnport_unittest.cc b/webrtc/p2p/base/turnport_unittest.cc
|
| index 73426cc5053f8b7b5b92cce4ea1daae3ffdbccf4..7e0e291defdc5713fe0d9dbd183569e9f9cf54e9 100644
|
| --- a/webrtc/p2p/base/turnport_unittest.cc
|
| +++ b/webrtc/p2p/base/turnport_unittest.cc
|
| @@ -11,6 +11,7 @@
|
| #include <dirent.h>
|
| #endif
|
|
|
| +#include <list>
|
| #include <memory>
|
|
|
| #include "webrtc/p2p/base/basicpacketsocketfactory.h"
|
| @@ -143,7 +144,6 @@ class TurnPortTest : public testing::Test,
|
| TurnPortTest()
|
| : ss_(new TurnPortTestVirtualSocketServer()),
|
| main_(ss_.get()),
|
| - network_("unittest", "unittest", rtc::IPAddress(INADDR_ANY), 32),
|
| socket_factory_(rtc::Thread::Current()),
|
| turn_server_(&main_, kTurnUdpIntAddr, kTurnUdpExtAddr),
|
| turn_ready_(false),
|
| @@ -156,7 +156,6 @@ class TurnPortTest : public testing::Test,
|
| // so far", so we need to start the fake clock at a nonzero time...
|
| // TODO(deadbeef): Fix this.
|
| fake_clock_.AdvanceTime(rtc::TimeDelta::FromSeconds(1));
|
| - network_.AddIP(rtc::IPAddress(INADDR_ANY));
|
| }
|
|
|
| virtual void OnMessage(rtc::Message* msg) {
|
| @@ -165,21 +164,6 @@ class TurnPortTest : public testing::Test,
|
| test_finish_ = true;
|
| }
|
|
|
| - void ConnectSignalAddressReadyToSetLocalhostAsAltenertativeLocalAddress() {
|
| - rtc::AsyncPacketSocket* socket = turn_port_->socket();
|
| - rtc::VirtualSocket* virtual_socket =
|
| - ss_->LookupBinding(socket->GetLocalAddress());
|
| - virtual_socket->SignalAddressReady.connect(
|
| - this, &TurnPortTest::SetLocalhostAsAltenertativeLocalAddress);
|
| - }
|
| -
|
| - void SetLocalhostAsAltenertativeLocalAddress(
|
| - rtc::VirtualSocket* socket,
|
| - const rtc::SocketAddress& address) {
|
| - SocketAddress local_address("127.0.0.1", 2000);
|
| - socket->SetAlternativeLocalAddress(local_address);
|
| - }
|
| -
|
| void OnTurnPortComplete(Port* port) {
|
| turn_ready_ = true;
|
| }
|
| @@ -229,24 +213,24 @@ class TurnPortTest : public testing::Test,
|
| return socket;
|
| }
|
|
|
| + rtc::Network* MakeNetwork(const SocketAddress& addr) {
|
| + networks_.emplace_back("unittest", "unittest", addr.ipaddr(), 32);
|
| + networks_.back().AddIP(addr.ipaddr());
|
| + return &networks_.back();
|
| + }
|
| +
|
| void CreateTurnPort(const std::string& username,
|
| const std::string& password,
|
| const ProtocolAddress& server_address) {
|
| - CreateTurnPort(kLocalAddr1, username, password, server_address);
|
| + CreateTurnPortWithAllParams(MakeNetwork(kLocalAddr1), username, password,
|
| + server_address, std::string());
|
| }
|
| void CreateTurnPort(const rtc::SocketAddress& local_address,
|
| const std::string& username,
|
| const std::string& password,
|
| const ProtocolAddress& server_address) {
|
| - RelayCredentials credentials(username, password);
|
| - turn_port_.reset(TurnPort::Create(&main_, &socket_factory_, &network_,
|
| - local_address.ipaddr(), 0, 0,
|
| - kIceUfrag1, kIcePwd1,
|
| - server_address, credentials, 0,
|
| - std::string()));
|
| - // This TURN port will be the controlling.
|
| - turn_port_->SetIceRole(ICEROLE_CONTROLLING);
|
| - ConnectSignals();
|
| + CreateTurnPortWithAllParams(MakeNetwork(local_address), username, password,
|
| + server_address, std::string());
|
| }
|
|
|
| // Should be identical to CreateTurnPort but specifies an origin value
|
| @@ -256,12 +240,30 @@ class TurnPortTest : public testing::Test,
|
| const std::string& password,
|
| const ProtocolAddress& server_address,
|
| const std::string& origin) {
|
| + CreateTurnPortWithAllParams(MakeNetwork(local_address), username, password,
|
| + server_address, origin);
|
| + }
|
| +
|
| + void CreateTurnPortWithNetwork(rtc::Network* network,
|
| + const std::string& username,
|
| + const std::string& password,
|
| + const ProtocolAddress& server_address) {
|
| + CreateTurnPortWithAllParams(network, username, password, server_address,
|
| + std::string());
|
| + }
|
| +
|
| + // Version of CreateTurnPort that takes all possible parameters; all other
|
| + // helper methods call this, such that "SetIceRole" and "ConnectSignals" (and
|
| + // possibly other things in the future) only happen in one place.
|
| + void CreateTurnPortWithAllParams(rtc::Network* network,
|
| + const std::string& username,
|
| + const std::string& password,
|
| + const ProtocolAddress& server_address,
|
| + const std::string& origin) {
|
| RelayCredentials credentials(username, password);
|
| - turn_port_.reset(TurnPort::Create(&main_, &socket_factory_, &network_,
|
| - local_address.ipaddr(), 0, 0,
|
| - kIceUfrag1, kIcePwd1,
|
| - server_address, credentials, 0,
|
| - origin));
|
| + turn_port_.reset(TurnPort::Create(&main_, &socket_factory_, network, 0, 0,
|
| + kIceUfrag1, kIcePwd1, server_address,
|
| + credentials, 0, origin));
|
| // This TURN port will be the controlling.
|
| turn_port_->SetIceRole(ICEROLE_CONTROLLING);
|
| ConnectSignals();
|
| @@ -282,8 +284,8 @@ class TurnPortTest : public testing::Test,
|
|
|
| RelayCredentials credentials(username, password);
|
| turn_port_.reset(TurnPort::Create(
|
| - &main_, &socket_factory_, &network_, socket_.get(), kIceUfrag1,
|
| - kIcePwd1, server_address, credentials, 0, std::string()));
|
| + &main_, &socket_factory_, MakeNetwork(kLocalAddr1), socket_.get(),
|
| + kIceUfrag1, kIcePwd1, server_address, credentials, 0, std::string()));
|
| // This TURN port will be the controlling.
|
| turn_port_->SetIceRole(ICEROLE_CONTROLLING);
|
| ConnectSignals();
|
| @@ -305,8 +307,8 @@ class TurnPortTest : public testing::Test,
|
| void CreateUdpPort() { CreateUdpPort(kLocalAddr2); }
|
|
|
| void CreateUdpPort(const SocketAddress& address) {
|
| - udp_port_.reset(UDPPort::Create(&main_, &socket_factory_, &network_,
|
| - address.ipaddr(), 0, 0, kIceUfrag2,
|
| + udp_port_.reset(UDPPort::Create(&main_, &socket_factory_,
|
| + MakeNetwork(address), 0, 0, kIceUfrag2,
|
| kIcePwd2, std::string(), false));
|
| // UDP port will be controlled.
|
| udp_port_->SetIceRole(ICEROLE_CONTROLLED);
|
| @@ -616,9 +618,12 @@ class TurnPortTest : public testing::Test,
|
|
|
| protected:
|
| rtc::ScopedFakeClock fake_clock_;
|
| + // When a "create port" helper method is called with an IP, we create a
|
| + // Network with that IP and add it to this list. Using a list instead of a
|
| + // vector so that when it grows, pointers aren't invalidated.
|
| + std::list<rtc::Network> networks_;
|
| std::unique_ptr<TurnPortTestVirtualSocketServer> ss_;
|
| rtc::AutoSocketServerThread main_;
|
| - rtc::Network network_;
|
| rtc::BasicPacketSocketFactory socket_factory_;
|
| std::unique_ptr<rtc::AsyncPacketSocket> socket_;
|
| TestTurnServer turn_server_;
|
| @@ -704,16 +709,79 @@ TEST_F(TurnPortTest, TestTurnTcpAllocate) {
|
| // instead the address that TurnPort originally bound to. The candidate pair
|
| // impacted by this behavior should still be used.
|
| TEST_F(TurnPortTest, TestTurnTcpAllocationWhenProxyChangesAddressToLocalHost) {
|
| + SocketAddress local_address("127.0.0.1", 0);
|
| + // After calling this, when TurnPort attempts to get a socket bound to
|
| + // kLocalAddr, it will end up using localhost instead.
|
| + ss_->SetAlternativeLocalAddress(kLocalAddr1.ipaddr(), local_address.ipaddr());
|
| +
|
| turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
|
| - CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
|
| + CreateTurnPort(kLocalAddr1, kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
|
| EXPECT_EQ(0, turn_port_->SetOption(rtc::Socket::OPT_SNDBUF, 10 * 1024));
|
| turn_port_->PrepareAddress();
|
| - ConnectSignalAddressReadyToSetLocalhostAsAltenertativeLocalAddress();
|
| EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 3, fake_clock_);
|
| ASSERT_EQ(1U, turn_port_->Candidates().size());
|
| EXPECT_EQ(kTurnUdpExtAddr.ipaddr(),
|
| turn_port_->Candidates()[0].address().ipaddr());
|
| EXPECT_NE(0, turn_port_->Candidates()[0].address().port());
|
| +
|
| + // Verify that the socket actually used localhost, otherwise this test isn't
|
| + // doing what it meant to.
|
| + ASSERT_EQ(local_address.ipaddr(),
|
| + turn_port_->Candidates()[0].related_address().ipaddr());
|
| +}
|
| +
|
| +// If the address the socket ends up bound to does not match any address of the
|
| +// TurnPort's Network, then the socket should be discarded and no candidates
|
| +// should be signaled. In the context of ICE, where one TurnPort is created for
|
| +// each Network, when this happens it's likely that the unexpected address is
|
| +// associated with some other Network, which another TurnPort is already
|
| +// covering.
|
| +TEST_F(TurnPortTest,
|
| + TurnTcpAllocationDiscardedIfBoundAddressDoesNotMatchNetwork) {
|
| + // Sockets bound to kLocalAddr1 will actually end up with kLocalAddr2.
|
| + ss_->SetAlternativeLocalAddress(kLocalAddr1.ipaddr(), kLocalAddr2.ipaddr());
|
| +
|
| + // Set up TURN server to use TCP (this logic only exists for TCP).
|
| + turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
|
| +
|
| + // Create TURN port and tell it to start allocation.
|
| + CreateTurnPort(kLocalAddr1, kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
|
| + turn_port_->PrepareAddress();
|
| +
|
| + // Shouldn't take more than 1 RTT to realize the bound address isn't the one
|
| + // expected.
|
| + EXPECT_TRUE_SIMULATED_WAIT(turn_error_, kSimulatedRtt, fake_clock_);
|
| +}
|
| +
|
| +// A caveat for the above logic: if the socket ends up bound to one of the IPs
|
| +// associated with the Network, just not the "best" one, this is ok.
|
| +TEST_F(TurnPortTest, TurnTcpAllocationNotDiscardedIfNotBoundToBestIP) {
|
| + // Sockets bound to kLocalAddr1 will actually end up with kLocalAddr2.
|
| + ss_->SetAlternativeLocalAddress(kLocalAddr1.ipaddr(), kLocalAddr2.ipaddr());
|
| +
|
| + // Set up a network with kLocalAddr1 as the "best" IP, and kLocalAddr2 as an
|
| + // alternate.
|
| + rtc::Network* network = MakeNetwork(kLocalAddr1);
|
| + network->AddIP(kLocalAddr2.ipaddr());
|
| + ASSERT_EQ(kLocalAddr1.ipaddr(), network->GetBestIP());
|
| +
|
| + // Set up TURN server to use TCP (this logic only exists for TCP).
|
| + turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
|
| +
|
| + // Create TURN port using our special Network, and tell it to start
|
| + // allocation.
|
| + CreateTurnPortWithNetwork(network, kTurnUsername, kTurnPassword,
|
| + kTurnTcpProtoAddr);
|
| + turn_port_->PrepareAddress();
|
| +
|
| + // Candidate should be gathered as normally.
|
| + EXPECT_TRUE_SIMULATED_WAIT(turn_ready_, kSimulatedRtt * 3, fake_clock_);
|
| + ASSERT_EQ(1U, turn_port_->Candidates().size());
|
| +
|
| + // Verify that the socket actually used the alternate address, otherwise this
|
| + // test isn't doing what it meant to.
|
| + ASSERT_EQ(kLocalAddr2.ipaddr(),
|
| + turn_port_->Candidates()[0].related_address().ipaddr());
|
| }
|
|
|
| // Testing turn port will attempt to create TCP socket on address resolution
|
|
|