diff --git a/talk/app/webrtc/peerconnection.cc b/talk/app/webrtc/peerconnection.cc index 2dce562ae8..d0c4cc276b 100644 --- a/talk/app/webrtc/peerconnection.cc +++ b/talk/app/webrtc/peerconnection.cc @@ -341,17 +341,18 @@ bool PeerConnection::Initialize( int portallocator_flags = port_allocator_->flags(); portallocator_flags |= cricket::PORTALLOCATOR_ENABLE_BUNDLE | cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG | - cricket::PORTALLOCATOR_ENABLE_SHARED_SOCKET; + cricket::PORTALLOCATOR_ENABLE_SHARED_SOCKET | + cricket::PORTALLOCATOR_ENABLE_IPV6; bool value; // If IPv6 flag was specified, we'll not override it by experiment. if (FindConstraint( constraints, MediaConstraintsInterface::kEnableIPv6, &value, NULL)) { - if (value) { - portallocator_flags |= cricket::PORTALLOCATOR_ENABLE_IPV6; + if (!value) { + portallocator_flags &= ~(cricket::PORTALLOCATOR_ENABLE_IPV6); } } else if (webrtc::field_trial::FindFullName("WebRTC-IPv6Default") == - "Enabled") { - portallocator_flags |= cricket::PORTALLOCATOR_ENABLE_IPV6; + "Disabled") { + portallocator_flags &= ~(cricket::PORTALLOCATOR_ENABLE_IPV6); } port_allocator_->set_flags(portallocator_flags); diff --git a/webrtc/base/ipaddress.cc b/webrtc/base/ipaddress.cc index 300c69bcdc..be709c834b 100644 --- a/webrtc/base/ipaddress.cc +++ b/webrtc/base/ipaddress.cc @@ -432,6 +432,12 @@ bool IPIs6To4(const IPAddress& ip) { return IPIsHelper(ip, k6To4Prefix, 16); } +bool IPIsLinkLocal(const IPAddress& ip) { + // Can't use the helper because the prefix is 10 bits. + in6_addr addr = ip.ipv6_address(); + return addr.s6_addr[0] == 0xFE && (addr.s6_addr[1] & 0x80) == 0x80; +} + bool IPIsSiteLocal(const IPAddress& ip) { // Can't use the helper because the prefix is 10 bits. in6_addr addr = ip.ipv6_address(); diff --git a/webrtc/base/ipaddress.h b/webrtc/base/ipaddress.h index 12db5c5bfd..3d77c28b2f 100644 --- a/webrtc/base/ipaddress.h +++ b/webrtc/base/ipaddress.h @@ -162,6 +162,7 @@ size_t HashIP(const IPAddress& ip); // These are only really applicable for IPv6 addresses. bool IPIs6Bone(const IPAddress& ip); bool IPIs6To4(const IPAddress& ip); +bool IPIsLinkLocal(const IPAddress& ip); bool IPIsSiteLocal(const IPAddress& ip); bool IPIsTeredo(const IPAddress& ip); bool IPIsULA(const IPAddress& ip); diff --git a/webrtc/base/network.cc b/webrtc/base/network.cc index bbebe8a36e..613dcad763 100644 --- a/webrtc/base/network.cc +++ b/webrtc/base/network.cc @@ -601,6 +601,14 @@ bool BasicNetworkManager::IsIgnoredNetwork(const Network& network) const { if (network.prefix().family() == AF_INET) { return (network.prefix().v4AddressAsHostOrderInteger() < 0x01000000); } + + // Linklocal addresses require scope id to be bound successfully. However, our + // IPAddress structure doesn't carry that so the information is lost and + // causes binding failure. + if (network.prefix().family() == AF_INET6 && + IPIsLinkLocal(network.GetBestIP())) { + return true; + } return false; } diff --git a/webrtc/base/network_unittest.cc b/webrtc/base/network_unittest.cc index 662dc70dff..fdf75caf37 100644 --- a/webrtc/base/network_unittest.cc +++ b/webrtc/base/network_unittest.cc @@ -285,13 +285,13 @@ TEST_F(NetworkTest, TestBasicMergeNetworkList) { void SetupNetworks(NetworkManager::NetworkList* list) { IPAddress ip; IPAddress prefix; - EXPECT_TRUE(IPFromString("fe80::1234:5678:abcd:ef12", &ip)); - EXPECT_TRUE(IPFromString("fe80::", &prefix)); + EXPECT_TRUE(IPFromString("abcd::1234:5678:abcd:ef12", &ip)); + EXPECT_TRUE(IPFromString("abcd::", &prefix)); // First, fake link-locals. Network ipv6_eth0_linklocalnetwork("test_eth0", "Test NetworkAdapter 1", prefix, 64); ipv6_eth0_linklocalnetwork.AddIP(ip); - EXPECT_TRUE(IPFromString("fe80::5678:abcd:ef12:3456", &ip)); + EXPECT_TRUE(IPFromString("abcd::5678:abcd:ef12:3456", &ip)); Network ipv6_eth1_linklocalnetwork("test_eth1", "Test NetworkAdapter 2", prefix, 64); ipv6_eth1_linklocalnetwork.AddIP(ip);