1 // Copyright 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "net/dns/mdns_client.h" 6 7 #include "net/base/net_errors.h" 8 #include "net/dns/dns_protocol.h" 9 #include "net/dns/mdns_client_impl.h" 10 11 namespace net { 12 13 namespace { 14 15 const char kMDnsMulticastGroupIPv4[] = "224.0.0.251"; 16 const char kMDnsMulticastGroupIPv6[] = "FF02::FB"; 17 18 IPEndPoint GetMDnsIPEndPoint(const char* address) { 19 IPAddressNumber multicast_group_number; 20 bool success = ParseIPLiteralToNumber(address, 21 &multicast_group_number); 22 DCHECK(success); 23 return IPEndPoint(multicast_group_number, 24 dns_protocol::kDefaultPortMulticast); 25 } 26 27 int Bind(const IPEndPoint& multicast_addr, 28 uint32 interface_index, 29 DatagramServerSocket* socket) { 30 IPAddressNumber address_any(multicast_addr.address().size()); 31 IPEndPoint bind_endpoint(address_any, multicast_addr.port()); 32 33 socket->AllowAddressReuse(); 34 socket->SetMulticastInterface(interface_index); 35 36 int rv = socket->Listen(bind_endpoint); 37 if (rv < OK) 38 return rv; 39 40 return socket->JoinGroup(multicast_addr.address()); 41 } 42 43 } // namespace 44 45 // static 46 scoped_ptr<MDnsSocketFactory> MDnsSocketFactory::CreateDefault() { 47 return scoped_ptr<MDnsSocketFactory>(new MDnsSocketFactoryImpl); 48 } 49 50 // static 51 scoped_ptr<MDnsClient> MDnsClient::CreateDefault() { 52 return scoped_ptr<MDnsClient>(new MDnsClientImpl()); 53 } 54 55 IPEndPoint GetMDnsIPEndPoint(AddressFamily address_family) { 56 switch (address_family) { 57 case ADDRESS_FAMILY_IPV4: 58 return GetMDnsIPEndPoint(kMDnsMulticastGroupIPv4); 59 case ADDRESS_FAMILY_IPV6: 60 return GetMDnsIPEndPoint(kMDnsMulticastGroupIPv6); 61 default: 62 NOTREACHED(); 63 return IPEndPoint(); 64 } 65 } 66 67 InterfaceIndexFamilyList GetMDnsInterfacesToBind() { 68 NetworkInterfaceList network_list; 69 InterfaceIndexFamilyList interfaces; 70 if (!GetNetworkList(&network_list)) 71 return interfaces; 72 for (size_t i = 0; i < network_list.size(); ++i) { 73 AddressFamily family = GetAddressFamily(network_list[i].address); 74 if (family == ADDRESS_FAMILY_IPV4 || family == ADDRESS_FAMILY_IPV6) { 75 interfaces.push_back( 76 std::make_pair(network_list[i].interface_index, family)); 77 } 78 } 79 std::sort(interfaces.begin(), interfaces.end()); 80 // Interfaces could have multiple addresses. Filter out duplicate entries. 81 interfaces.erase(std::unique(interfaces.begin(), interfaces.end()), 82 interfaces.end()); 83 return interfaces; 84 } 85 86 scoped_ptr<DatagramServerSocket> CreateAndBindMDnsSocket( 87 AddressFamily address_family, 88 uint32 interface_index) { 89 scoped_ptr<DatagramServerSocket> socket( 90 new UDPServerSocket(NULL, NetLog::Source())); 91 92 IPEndPoint multicast_addr = GetMDnsIPEndPoint(address_family); 93 int rv = Bind(multicast_addr, interface_index, socket.get()); 94 if (rv != OK) { 95 socket.reset(); 96 VLOG(1) << "Bind failed, endpoint=" << multicast_addr.ToStringWithoutPort() 97 << ", error=" << rv; 98 } 99 return socket.PassAs<DatagramServerSocket>(); 100 } 101 102 } // namespace net 103