diff --git a/webrtc/base/nethelpers.cc b/webrtc/base/nethelpers.cc index 6c2ef9c5f6..6c11ef8c38 100644 --- a/webrtc/base/nethelpers.cc +++ b/webrtc/base/nethelpers.cc @@ -141,6 +141,26 @@ int inet_pton(int af, const char* src, void *dst) { #endif } +bool HasIPv4Enabled() { +#if defined(WEBRTC_POSIX) && !defined(__native_client__) + bool has_ipv4 = false; + struct ifaddrs* ifa; + if (getifaddrs(&ifa) < 0) { + return false; + } + for (struct ifaddrs* cur = ifa; cur != nullptr; cur = cur->ifa_next) { + if (cur->ifa_addr->sa_family == AF_INET) { + has_ipv4 = true; + break; + } + } + freeifaddrs(ifa); + return has_ipv4; +#else + return true; +#endif +} + bool HasIPv6Enabled() { #if defined(WEBRTC_WIN) if (IsWindowsVistaOrLater()) { diff --git a/webrtc/base/nethelpers.h b/webrtc/base/nethelpers.h index 2c72c0b3c2..b0727f861b 100644 --- a/webrtc/base/nethelpers.h +++ b/webrtc/base/nethelpers.h @@ -59,6 +59,7 @@ class AsyncResolver : public SignalThread, public AsyncResolverInterface { const char* inet_ntop(int af, const void *src, char* dst, socklen_t size); int inet_pton(int af, const char* src, void *dst); +bool HasIPv4Enabled(); bool HasIPv6Enabled(); } // namespace rtc diff --git a/webrtc/base/physicalsocketserver_unittest.cc b/webrtc/base/physicalsocketserver_unittest.cc index e2f05e977f..20e66ce2b6 100644 --- a/webrtc/base/physicalsocketserver_unittest.cc +++ b/webrtc/base/physicalsocketserver_unittest.cc @@ -22,6 +22,12 @@ namespace rtc { +#define MAYBE_SKIP_IPV4 \ + if (!HasIPv4Enabled()) { \ + LOG(LS_INFO) << "No IPv4... skipping"; \ + return; \ + } + #define MAYBE_SKIP_IPV6 \ if (!HasIPv6Enabled()) { \ LOG(LS_INFO) << "No IPv6... skipping"; \ @@ -164,6 +170,7 @@ int FakeSocketDispatcher::DoSendTo(SOCKET socket, const char* buf, int len, } TEST_F(PhysicalSocketTest, TestConnectIPv4) { + MAYBE_SKIP_IPV4; SocketTest::TestConnectIPv4(); } @@ -172,6 +179,7 @@ TEST_F(PhysicalSocketTest, TestConnectIPv6) { } TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupIPv4) { + MAYBE_SKIP_IPV4; SocketTest::TestConnectWithDnsLookupIPv4(); } @@ -180,6 +188,7 @@ TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupIPv6) { } TEST_F(PhysicalSocketTest, TestConnectFailIPv4) { + MAYBE_SKIP_IPV4; SocketTest::TestConnectFailIPv4(); } @@ -258,6 +267,7 @@ void PhysicalSocketTest::ConnectInternalAcceptError(const IPAddress& loopback) { } TEST_F(PhysicalSocketTest, TestConnectAcceptErrorIPv4) { + MAYBE_SKIP_IPV4; ConnectInternalAcceptError(kIPv4Loopback); } @@ -284,6 +294,7 @@ void PhysicalSocketTest::WritableAfterPartialWrite(const IPAddress& loopback) { #define MAYBE_TestWritableAfterPartialWriteIPv4 TestWritableAfterPartialWriteIPv4 #endif TEST_F(PhysicalSocketTest, MAYBE_TestWritableAfterPartialWriteIPv4) { + MAYBE_SKIP_IPV4; WritableAfterPartialWrite(kIPv4Loopback); } @@ -303,6 +314,7 @@ TEST_F(PhysicalSocketTest, TestConnectFailIPv6) { } TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupFailIPv4) { + MAYBE_SKIP_IPV4; SocketTest::TestConnectWithDnsLookupFailIPv4(); } @@ -312,6 +324,7 @@ TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupFailIPv6) { TEST_F(PhysicalSocketTest, TestConnectWithClosedSocketIPv4) { + MAYBE_SKIP_IPV4; SocketTest::TestConnectWithClosedSocketIPv4(); } @@ -320,6 +333,7 @@ TEST_F(PhysicalSocketTest, TestConnectWithClosedSocketIPv6) { } TEST_F(PhysicalSocketTest, TestConnectWhileNotClosedIPv4) { + MAYBE_SKIP_IPV4; SocketTest::TestConnectWhileNotClosedIPv4(); } @@ -328,6 +342,7 @@ TEST_F(PhysicalSocketTest, TestConnectWhileNotClosedIPv6) { } TEST_F(PhysicalSocketTest, TestServerCloseDuringConnectIPv4) { + MAYBE_SKIP_IPV4; SocketTest::TestServerCloseDuringConnectIPv4(); } @@ -336,6 +351,7 @@ TEST_F(PhysicalSocketTest, TestServerCloseDuringConnectIPv6) { } TEST_F(PhysicalSocketTest, TestClientCloseDuringConnectIPv4) { + MAYBE_SKIP_IPV4; SocketTest::TestClientCloseDuringConnectIPv4(); } @@ -344,6 +360,7 @@ TEST_F(PhysicalSocketTest, TestClientCloseDuringConnectIPv6) { } TEST_F(PhysicalSocketTest, TestServerCloseIPv4) { + MAYBE_SKIP_IPV4; SocketTest::TestServerCloseIPv4(); } @@ -352,6 +369,7 @@ TEST_F(PhysicalSocketTest, TestServerCloseIPv6) { } TEST_F(PhysicalSocketTest, TestCloseInClosedCallbackIPv4) { + MAYBE_SKIP_IPV4; SocketTest::TestCloseInClosedCallbackIPv4(); } @@ -360,6 +378,7 @@ TEST_F(PhysicalSocketTest, TestCloseInClosedCallbackIPv6) { } TEST_F(PhysicalSocketTest, TestSocketServerWaitIPv4) { + MAYBE_SKIP_IPV4; SocketTest::TestSocketServerWaitIPv4(); } @@ -368,6 +387,7 @@ TEST_F(PhysicalSocketTest, TestSocketServerWaitIPv6) { } TEST_F(PhysicalSocketTest, TestTcpIPv4) { + MAYBE_SKIP_IPV4; SocketTest::TestTcpIPv4(); } @@ -376,6 +396,7 @@ TEST_F(PhysicalSocketTest, TestTcpIPv6) { } TEST_F(PhysicalSocketTest, TestUdpIPv4) { + MAYBE_SKIP_IPV4; SocketTest::TestUdpIPv4(); } @@ -399,6 +420,7 @@ TEST_F(PhysicalSocketTest, TestUdpIPv6) { #define MAYBE_TestUdpReadyToSendIPv4 TestUdpReadyToSendIPv4 #endif TEST_F(PhysicalSocketTest, MAYBE_TestUdpReadyToSendIPv4) { + MAYBE_SKIP_IPV4; SocketTest::TestUdpReadyToSendIPv4(); } @@ -413,6 +435,7 @@ TEST_F(PhysicalSocketTest, MAYBE_TestUdpReadyToSendIPv6) { } TEST_F(PhysicalSocketTest, TestGetSetOptionsIPv4) { + MAYBE_SKIP_IPV4; SocketTest::TestGetSetOptionsIPv4(); } @@ -425,6 +448,7 @@ TEST_F(PhysicalSocketTest, TestGetSetOptionsIPv6) { // We don't get recv timestamps on Mac. #if !defined(WEBRTC_MAC) TEST_F(PhysicalSocketTest, TestSocketRecvTimestampIPv4) { + MAYBE_SKIP_IPV4; SocketTest::TestSocketRecvTimestampIPv4(); } @@ -437,6 +461,7 @@ TEST_F(PhysicalSocketTest, TestSocketRecvTimestampIPv6) { // (not loopback), Bind will return an error. TEST_F(PhysicalSocketTest, BindFailsIfNetworkBinderFailsForNonLoopbackInterface) { + MAYBE_SKIP_IPV4; FakeNetworkBinder fake_network_binder; server_->set_network_binder(&fake_network_binder); std::unique_ptr socket( @@ -449,6 +474,7 @@ TEST_F(PhysicalSocketTest, // Network binder shouldn't be used if the socket is bound to the "any" IP. TEST_F(PhysicalSocketTest, NetworkBinderIsNotUsedForAnyIp) { + MAYBE_SKIP_IPV4; FakeNetworkBinder fake_network_binder; server_->set_network_binder(&fake_network_binder); std::unique_ptr socket( @@ -462,6 +488,7 @@ TEST_F(PhysicalSocketTest, // tolerated. TEST_F(PhysicalSocketTest, BindSucceedsIfNetworkBinderFailsForLoopbackInterface) { + MAYBE_SKIP_IPV4; FakeNetworkBinder fake_network_binder; server_->set_network_binder(&fake_network_binder); std::unique_ptr socket( diff --git a/webrtc/base/testclient_unittest.cc b/webrtc/base/testclient_unittest.cc index 685499448f..8392abfa94 100644 --- a/webrtc/base/testclient_unittest.cc +++ b/webrtc/base/testclient_unittest.cc @@ -18,6 +18,18 @@ using namespace rtc; +#define MAYBE_SKIP_IPV4 \ + if (!HasIPv4Enabled()) { \ + LOG(LS_INFO) << "No IPv4... skipping"; \ + return; \ + } + +#define MAYBE_SKIP_IPV6 \ + if (!HasIPv6Enabled()) { \ + LOG(LS_INFO) << "No IPv6... skipping"; \ + return; \ + } + void TestUdpInternal(const SocketAddress& loopback) { Thread *main = Thread::Current(); AsyncSocket* socket = main->socketserver() @@ -53,6 +65,7 @@ void TestTcpInternal(const SocketAddress& loopback) { // Tests whether the TestClient can send UDP to itself. TEST(TestClientTest, TestUdpIPv4) { + MAYBE_SKIP_IPV4; TestUdpInternal(SocketAddress("127.0.0.1", 0)); } @@ -62,15 +75,13 @@ TEST(TestClientTest, TestUdpIPv4) { #define MAYBE_TestUdpIPv6 TestUdpIPv6 #endif TEST(TestClientTest, MAYBE_TestUdpIPv6) { - if (HasIPv6Enabled()) { - TestUdpInternal(SocketAddress("::1", 0)); - } else { - LOG(LS_INFO) << "Skipping IPv6 test."; - } + MAYBE_SKIP_IPV6; + TestUdpInternal(SocketAddress("::1", 0)); } // Tests whether the TestClient can connect to a server and exchange data. TEST(TestClientTest, TestTcpIPv4) { + MAYBE_SKIP_IPV4; TestTcpInternal(SocketAddress("127.0.0.1", 0)); } @@ -80,9 +91,6 @@ TEST(TestClientTest, TestTcpIPv4) { #define MAYBE_TestTcpIPv6 TestTcpIPv6 #endif TEST(TestClientTest, MAYBE_TestTcpIPv6) { - if (HasIPv6Enabled()) { - TestTcpInternal(SocketAddress("::1", 0)); - } else { - LOG(LS_INFO) << "Skipping IPv6 test."; - } + MAYBE_SKIP_IPV6; + TestTcpInternal(SocketAddress("::1", 0)); } diff --git a/webrtc/p2p/base/portallocator_unittest.cc b/webrtc/p2p/base/portallocator_unittest.cc index ac1c862f5f..b9f6a373fb 100644 --- a/webrtc/p2p/base/portallocator_unittest.cc +++ b/webrtc/p2p/base/portallocator_unittest.cc @@ -11,7 +11,9 @@ #include #include "webrtc/base/gunit.h" +#include "webrtc/base/physicalsocketserver.h" #include "webrtc/base/thread.h" +#include "webrtc/base/virtualsocketserver.h" #include "webrtc/p2p/base/fakeportallocator.h" #include "webrtc/p2p/base/portallocator.h" @@ -25,7 +27,10 @@ static const char kTurnPassword[] = "test"; class PortAllocatorTest : public testing::Test, public sigslot::has_slots<> { public: - PortAllocatorTest() { + PortAllocatorTest() + : pss_(new rtc::PhysicalSocketServer), + vss_(new rtc::VirtualSocketServer(pss_.get())), + main_(vss_.get()) { allocator_.reset( new cricket::FakePortAllocator(rtc::Thread::Current(), nullptr)); } @@ -76,6 +81,9 @@ class PortAllocatorTest : public testing::Test, public sigslot::has_slots<> { return count; } + std::unique_ptr pss_; + std::unique_ptr vss_; + rtc::AutoSocketServerThread main_; std::unique_ptr allocator_; rtc::SocketAddress stun_server_1{"11.11.11.11", 3478}; rtc::SocketAddress stun_server_2{"22.22.22.22", 3478}; diff --git a/webrtc/p2p/base/stunport_unittest.cc b/webrtc/p2p/base/stunport_unittest.cc index 9fbcfec5cb..841151d11b 100644 --- a/webrtc/p2p/base/stunport_unittest.cc +++ b/webrtc/p2p/base/stunport_unittest.cc @@ -246,7 +246,7 @@ TEST_F(StunPortTestWithRealClock, TestPrepareAddressHostnameFail) { // additional candidate generation. TEST_F(StunPortTest, TestKeepAliveResponse) { SetKeepaliveDelay(500); // 500ms of keepalive delay. - CreateStunPort(kStunHostnameAddr); + CreateStunPort(kStunAddr1); PrepareAddress(); EXPECT_TRUE_SIMULATED_WAIT(done(), kTimeoutMs, fake_clock); ASSERT_EQ(1U, port()->Candidates().size()); diff --git a/webrtc/p2p/client/basicportallocator_unittest.cc b/webrtc/p2p/client/basicportallocator_unittest.cc index 6cc2259f0f..bb3e0d71a3 100644 --- a/webrtc/p2p/client/basicportallocator_unittest.cc +++ b/webrtc/p2p/client/basicportallocator_unittest.cc @@ -11,13 +11,6 @@ #include #include -#include "webrtc/p2p/base/basicpacketsocketfactory.h" -#include "webrtc/p2p/base/p2pconstants.h" -#include "webrtc/p2p/base/p2ptransportchannel.h" -#include "webrtc/p2p/base/testrelayserver.h" -#include "webrtc/p2p/base/teststunserver.h" -#include "webrtc/p2p/base/testturnserver.h" -#include "webrtc/p2p/client/basicportallocator.h" #include "webrtc/base/fakeclock.h" #include "webrtc/base/fakenetwork.h" #include "webrtc/base/firewallsocketserver.h" @@ -27,17 +20,31 @@ #include "webrtc/base/logging.h" #include "webrtc/base/natserver.h" #include "webrtc/base/natsocketfactory.h" +#include "webrtc/base/nethelpers.h" #include "webrtc/base/network.h" #include "webrtc/base/physicalsocketserver.h" #include "webrtc/base/socketaddress.h" #include "webrtc/base/ssladapter.h" #include "webrtc/base/thread.h" #include "webrtc/base/virtualsocketserver.h" +#include "webrtc/p2p/base/basicpacketsocketfactory.h" +#include "webrtc/p2p/base/p2pconstants.h" +#include "webrtc/p2p/base/p2ptransportchannel.h" +#include "webrtc/p2p/base/testrelayserver.h" +#include "webrtc/p2p/base/teststunserver.h" +#include "webrtc/p2p/base/testturnserver.h" +#include "webrtc/p2p/client/basicportallocator.h" using rtc::IPAddress; using rtc::SocketAddress; using rtc::Thread; +#define MAYBE_SKIP_IPV4 \ + if (!rtc::HasIPv4Enabled()) { \ + LOG(LS_INFO) << "No IPv4... skipping"; \ + return; \ + } + static const SocketAddress kAnyAddr("0.0.0.0", 0); static const SocketAddress kClientAddr("11.11.11.11", 0); static const SocketAddress kClientAddr2("22.22.22.22", 0); @@ -1523,6 +1530,9 @@ TEST_F(BasicPortAllocatorTest, // using the fake clock. TEST_F(BasicPortAllocatorTestWithRealClock, TestSharedSocketWithServerAddressResolve) { + // This test relies on a real query for "localhost", so it won't work on an + // IPv6-only machine. + MAYBE_SKIP_IPV4; turn_server_.AddInternalSocket(rtc::SocketAddress("127.0.0.1", 3478), PROTO_UDP); AddInterface(kClientAddr); diff --git a/webrtc/p2p/stunprober/stunprober.cc b/webrtc/p2p/stunprober/stunprober.cc index f32a2002fb..2ec77323da 100644 --- a/webrtc/p2p/stunprober/stunprober.cc +++ b/webrtc/p2p/stunprober/stunprober.cc @@ -280,6 +280,19 @@ bool StunProber::Prepare(const std::vector& servers, timeout_ms_ = timeout_ms; servers_ = servers; observer_ = observer; + // Remove addresses that are already resolved. + for (auto it = servers_.begin(); it != servers_.end();) { + if (it->ipaddr().family() != AF_UNSPEC) { + all_servers_addrs_.push_back(*it); + it = servers_.erase(it); + } else { + ++it; + } + } + if (servers_.empty()) { + CreateSockets(); + return true; + } return ResolveServerName(servers_.back()); } @@ -339,6 +352,10 @@ void StunProber::OnServerResolved(rtc::AsyncResolverInterface* resolver) { return; } + CreateSockets(); +} + +void StunProber::CreateSockets() { // Dedupe. std::set addrs(all_servers_addrs_.begin(), all_servers_addrs_.end()); diff --git a/webrtc/p2p/stunprober/stunprober.h b/webrtc/p2p/stunprober/stunprober.h index dbb67c6167..c7cc33c02f 100644 --- a/webrtc/p2p/stunprober/stunprober.h +++ b/webrtc/p2p/stunprober/stunprober.h @@ -175,6 +175,8 @@ class StunProber : public sigslot::has_slots<> { void OnSocketReady(rtc::AsyncPacketSocket* socket, const rtc::SocketAddress& addr); + void CreateSockets(); + bool Done() { return num_request_sent_ >= requests_per_ip_ * all_servers_addrs_.size(); } diff --git a/webrtc/pc/peerconnectioninterface_unittest.cc b/webrtc/pc/peerconnectioninterface_unittest.cc index 8b8b49c722..de62104acf 100644 --- a/webrtc/pc/peerconnectioninterface_unittest.cc +++ b/webrtc/pc/peerconnectioninterface_unittest.cc @@ -22,10 +22,12 @@ #include "webrtc/api/rtpsenderinterface.h" #include "webrtc/api/test/fakeconstraints.h" #include "webrtc/base/gunit.h" +#include "webrtc/base/physicalsocketserver.h" #include "webrtc/base/ssladapter.h" #include "webrtc/base/sslstreamadapter.h" #include "webrtc/base/stringutils.h" #include "webrtc/base/thread.h" +#include "webrtc/base/virtualsocketserver.h" #include "webrtc/media/base/fakevideocapturer.h" #include "webrtc/media/sctp/sctptransportinternal.h" #include "webrtc/p2p/base/fakeportallocator.h" @@ -659,7 +661,10 @@ class PeerConnectionFactoryForTest : public webrtc::PeerConnectionFactory { class PeerConnectionInterfaceTest : public testing::Test { protected: - PeerConnectionInterfaceTest() { + PeerConnectionInterfaceTest() + : pss_(new rtc::PhysicalSocketServer), + vss_(new rtc::VirtualSocketServer(pss_.get())), + main_(vss_.get()) { #ifdef WEBRTC_ANDROID webrtc::InitializeAndroidObjects(); #endif @@ -1123,6 +1128,9 @@ class PeerConnectionInterfaceTest : public testing::Test { return audio_desc->streams()[0].cname; } + std::unique_ptr pss_; + std::unique_ptr vss_; + rtc::AutoSocketServerThread main_; cricket::FakePortAllocator* port_allocator_ = nullptr; FakeRTCCertificateGenerator* fake_certificate_generator_ = nullptr; rtc::scoped_refptr pc_factory_;