Home | History | Annotate | Download | only in dns
      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