Ensuring that UDP TURN servers are always used as STUN servers.

This was already working in most cases, but not for some corner cases:
* If the PORTALLOCATOR_ENABLE_SHARED_SOCKET flag is not set
* If both a STUN server and TURN server are configured

I added unit tests for these cases, and centralized the code that gets
STUN server addresses in order to fix these and any related issues.

BUG=webrtc:4215

Review URL: https://codereview.webrtc.org/1215713003

Cr-Commit-Position: refs/heads/master@{#9596}
This commit is contained in:
deadbeef
2015-07-16 10:22:21 -07:00
committed by Commit bot
parent d848d5e74a
commit c5d0d95fd8
12 changed files with 340 additions and 95 deletions

View File

@ -18,6 +18,7 @@
#include "webrtc/base/network.h"
#include "webrtc/base/physicalsocketserver.h"
#include "webrtc/base/testclient.h"
#include "webrtc/base/asynctcpsocket.h"
#include "webrtc/base/virtualsocketserver.h"
#include "webrtc/test/testsupport/gtest_disable.h"
@ -36,6 +37,11 @@ TestClient* CreateTestClient(
return new TestClient(socket);
}
TestClient* CreateTCPTestClient(AsyncSocket* socket) {
AsyncTCPSocket* packet_socket = new AsyncTCPSocket(socket, false);
return new TestClient(packet_socket);
}
// Tests that when sending from internal_addr to external_addrs through the
// NAT type specified by nat_type, all external addrs receive the sent packet
// and, if exp_same is true, all use the same mapped-address on the NAT.
@ -48,10 +54,11 @@ void TestSend(
SocketAddress server_addr = internal_addr;
server_addr.SetPort(0); // Auto-select a port
NATServer* nat = new NATServer(
nat_type, internal, server_addr, external, external_addrs[0]);
NATServer* nat = new NATServer(nat_type, internal, server_addr, server_addr,
external, external_addrs[0]);
NATSocketFactory* natsf = new NATSocketFactory(internal,
nat->internal_address());
nat->internal_udp_address(),
nat->internal_tcp_address());
TestClient* in = CreateTestClient(natsf, internal_addr);
TestClient* out[4];
@ -99,10 +106,11 @@ void TestRecv(
SocketAddress server_addr = internal_addr;
server_addr.SetPort(0); // Auto-select a port
NATServer* nat = new NATServer(
nat_type, internal, server_addr, external, external_addrs[0]);
NATServer* nat = new NATServer(nat_type, internal, server_addr, server_addr,
external, external_addrs[0]);
NATSocketFactory* natsf = new NATSocketFactory(internal,
nat->internal_address());
nat->internal_udp_address(),
nat->internal_tcp_address());
TestClient* in = CreateTestClient(natsf, internal_addr);
TestClient* out[4];
@ -295,56 +303,86 @@ TEST(NatTest, TestVirtualIPv6) {
}
}
// TODO: Finish this test
class NatTcpTest : public testing::Test, public sigslot::has_slots<> {
public:
NatTcpTest() : connected_(false) {}
virtual void SetUp() {
int_vss_ = new TestVirtualSocketServer(new PhysicalSocketServer());
ext_vss_ = new TestVirtualSocketServer(new PhysicalSocketServer());
nat_ = new NATServer(NAT_OPEN_CONE, int_vss_, SocketAddress(),
ext_vss_, SocketAddress());
natsf_ = new NATSocketFactory(int_vss_, nat_->internal_address());
NatTcpTest()
: int_addr_("192.168.0.1", 0),
ext_addr_("10.0.0.1", 0),
connected_(false),
int_pss_(new PhysicalSocketServer()),
ext_pss_(new PhysicalSocketServer()),
int_vss_(new TestVirtualSocketServer(int_pss_)),
ext_vss_(new TestVirtualSocketServer(ext_pss_)),
int_thread_(new Thread(int_vss_.get())),
ext_thread_(new Thread(ext_vss_.get())),
nat_(new NATServer(NAT_OPEN_CONE, int_vss_.get(), int_addr_, int_addr_,
ext_vss_.get(), ext_addr_)),
natsf_(new NATSocketFactory(int_vss_.get(),
nat_->internal_udp_address(),
nat_->internal_tcp_address())) {
int_thread_->Start();
ext_thread_->Start();
}
void OnConnectEvent(AsyncSocket* socket) {
connected_ = true;
}
void OnAcceptEvent(AsyncSocket* socket) {
accepted_ = server_->Accept(NULL);
accepted_.reset(server_->Accept(NULL));
}
void OnCloseEvent(AsyncSocket* socket, int error) {
}
void ConnectEvents() {
server_->SignalReadEvent.connect(this, &NatTcpTest::OnAcceptEvent);
client_->SignalConnectEvent.connect(this, &NatTcpTest::OnConnectEvent);
}
TestVirtualSocketServer* int_vss_;
TestVirtualSocketServer* ext_vss_;
NATServer* nat_;
NATSocketFactory* natsf_;
AsyncSocket* client_;
AsyncSocket* server_;
AsyncSocket* accepted_;
SocketAddress int_addr_;
SocketAddress ext_addr_;
bool connected_;
PhysicalSocketServer* int_pss_;
PhysicalSocketServer* ext_pss_;
rtc::scoped_ptr<TestVirtualSocketServer> int_vss_;
rtc::scoped_ptr<TestVirtualSocketServer> ext_vss_;
rtc::scoped_ptr<Thread> int_thread_;
rtc::scoped_ptr<Thread> ext_thread_;
rtc::scoped_ptr<NATServer> nat_;
rtc::scoped_ptr<NATSocketFactory> natsf_;
rtc::scoped_ptr<AsyncSocket> client_;
rtc::scoped_ptr<AsyncSocket> server_;
rtc::scoped_ptr<AsyncSocket> accepted_;
};
TEST_F(NatTcpTest, DISABLED_TestConnectOut) {
server_ = ext_vss_->CreateAsyncSocket(SOCK_STREAM);
server_->Bind(SocketAddress());
TEST_F(NatTcpTest, TestConnectOut) {
server_.reset(ext_vss_->CreateAsyncSocket(SOCK_STREAM));
server_->Bind(ext_addr_);
server_->Listen(5);
client_ = int_vss_->CreateAsyncSocket(SOCK_STREAM);
EXPECT_GE(0, client_->Bind(SocketAddress()));
client_.reset(natsf_->CreateAsyncSocket(SOCK_STREAM));
EXPECT_GE(0, client_->Bind(int_addr_));
EXPECT_GE(0, client_->Connect(server_->GetLocalAddress()));
ConnectEvents();
EXPECT_TRUE_WAIT(connected_, 1000);
EXPECT_EQ(client_->GetRemoteAddress(), server_->GetLocalAddress());
EXPECT_EQ(client_->GetRemoteAddress(), accepted_->GetLocalAddress());
EXPECT_EQ(client_->GetLocalAddress(), accepted_->GetRemoteAddress());
EXPECT_EQ(accepted_->GetRemoteAddress().ipaddr(), ext_addr_.ipaddr());
client_->Close();
rtc::scoped_ptr<rtc::TestClient> in(CreateTCPTestClient(client_.release()));
rtc::scoped_ptr<rtc::TestClient> out(
CreateTCPTestClient(accepted_.release()));
const char* buf = "test_packet";
size_t len = strlen(buf);
in->Send(buf, len);
SocketAddress trans_addr;
EXPECT_TRUE(out->CheckNextPacket(buf, len, &trans_addr));
out->Send(buf, len);
EXPECT_TRUE(in->CheckNextPacket(buf, len, &trans_addr));
}
//#endif
// #endif