From b8b0143a11afd495b8e9c1a1cc388cdbd4340b99 Mon Sep 17 00:00:00 2001 From: Peter Thatcher Date: Tue, 7 Jul 2015 16:45:53 -0700 Subject: [PATCH] Tighten link-local routing exclusion check Also add a unit test for this behavior. BUG=https://code.google.com/p/webrtc/issues/detail?id=4823 R=pthatcher@webrtc.org Review URL: https://codereview.webrtc.org/1218293016 . Cr-Commit-Position: refs/heads/master@{#9550} --- webrtc/p2p/base/port.cc | 3 ++- webrtc/p2p/base/port_unittest.cc | 45 ++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/webrtc/p2p/base/port.cc b/webrtc/p2p/base/port.cc index 25b5efd056..72a05b304f 100644 --- a/webrtc/p2p/base/port.cc +++ b/webrtc/p2p/base/port.cc @@ -472,7 +472,8 @@ bool Port::IsCompatibleAddress(const rtc::SocketAddress& addr) { return false; } // Link-local IPv6 ports can only connect to other link-local IPv6 ports. - if (family == AF_INET6 && (IPIsPrivate(ip()) != IPIsPrivate(addr.ipaddr()))) { + if (family == AF_INET6 && + (IPIsLinkLocal(ip()) != IPIsLinkLocal(addr.ipaddr()))) { return false; } return true; diff --git a/webrtc/p2p/base/port_unittest.cc b/webrtc/p2p/base/port_unittest.cc index fb7fc17709..57618b7bc8 100644 --- a/webrtc/p2p/base/port_unittest.cc +++ b/webrtc/p2p/base/port_unittest.cc @@ -538,6 +538,8 @@ class PortTest : public testing::Test, public sigslot::has_slots<> { void TestCrossFamilyPorts(int type); + void ExpectPortsCanConnect(bool can_connect, Port* p1, Port* p2); + // This does all the work and then deletes |port1| and |port2|. void TestConnectivity(const char* name1, Port* port1, const char* name2, Port* port2, @@ -1394,6 +1396,49 @@ TEST_F(PortTest, TestSkipCrossFamilyUdp) { TestCrossFamilyPorts(SOCK_DGRAM); } +void PortTest::ExpectPortsCanConnect(bool can_connect, Port* p1, Port* p2) { + Connection* c = p1->CreateConnection(GetCandidate(p2), + Port::ORIGIN_MESSAGE); + if (can_connect) { + EXPECT_FALSE(NULL == c); + EXPECT_EQ(1U, p1->connections().size()); + } else { + EXPECT_TRUE(NULL == c); + EXPECT_EQ(0U, p1->connections().size()); + } +} + +TEST_F(PortTest, TestUdpV6CrossTypePorts) { + FakePacketSocketFactory factory; + scoped_ptr ports[4]; + SocketAddress addresses[4] = {SocketAddress("2001:db8::1", 0), + SocketAddress("fe80::1", 0), + SocketAddress("fe80::2", 0), + SocketAddress("::1", 0)}; + for (int i = 0; i < 4; i++) { + FakeAsyncPacketSocket *socket = new FakeAsyncPacketSocket(); + factory.set_next_udp_socket(socket); + ports[i].reset(CreateUdpPort(addresses[i], &factory)); + socket->set_state(AsyncPacketSocket::STATE_BINDING); + socket->SignalAddressReady(socket, addresses[i]); + ports[i]->PrepareAddress(); + } + + Port* standard = ports[0].get(); + Port* link_local1 = ports[1].get(); + Port* link_local2 = ports[2].get(); + Port* localhost = ports[3].get(); + + ExpectPortsCanConnect(false, link_local1, standard); + ExpectPortsCanConnect(false, standard, link_local1); + ExpectPortsCanConnect(false, link_local1, localhost); + ExpectPortsCanConnect(false, localhost, link_local1); + + ExpectPortsCanConnect(true, link_local1, link_local2); + ExpectPortsCanConnect(true, localhost, standard); + ExpectPortsCanConnect(true, standard, localhost); +} + // This test verifies DSCP value set through SetOption interface can be // get through DefaultDscpValue. TEST_F(PortTest, TestDefaultDscpValue) {