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.
5 #include "net/dns/mdns_client.h"
7 #include "net/base/net_errors.h"
8 #include "net/base/network_interfaces.h"
9 #include "net/dns/dns_protocol.h"
10 #include "net/dns/mdns_client_impl.h"
16 const char kMDnsMulticastGroupIPv4
[] = "224.0.0.251";
17 const char kMDnsMulticastGroupIPv6
[] = "FF02::FB";
19 IPEndPoint
GetMDnsIPEndPoint(const char* address
) {
20 IPAddressNumber multicast_group_number
;
21 bool success
= ParseIPLiteralToNumber(address
,
22 &multicast_group_number
);
24 return IPEndPoint(multicast_group_number
,
25 dns_protocol::kDefaultPortMulticast
);
28 int Bind(const IPEndPoint
& multicast_addr
,
29 uint32 interface_index
,
30 DatagramServerSocket
* socket
) {
31 IPAddressNumber
address_any(multicast_addr
.address().size());
32 IPEndPoint
bind_endpoint(address_any
, multicast_addr
.port());
34 socket
->AllowAddressReuse();
35 socket
->SetMulticastInterface(interface_index
);
37 int rv
= socket
->Listen(bind_endpoint
);
41 return socket
->JoinGroup(multicast_addr
.address());
47 scoped_ptr
<MDnsSocketFactory
> MDnsSocketFactory::CreateDefault() {
48 return scoped_ptr
<MDnsSocketFactory
>(new MDnsSocketFactoryImpl
);
52 scoped_ptr
<MDnsClient
> MDnsClient::CreateDefault() {
53 return scoped_ptr
<MDnsClient
>(new MDnsClientImpl());
56 IPEndPoint
GetMDnsIPEndPoint(AddressFamily address_family
) {
57 switch (address_family
) {
58 case ADDRESS_FAMILY_IPV4
:
59 return GetMDnsIPEndPoint(kMDnsMulticastGroupIPv4
);
60 case ADDRESS_FAMILY_IPV6
:
61 return GetMDnsIPEndPoint(kMDnsMulticastGroupIPv6
);
68 InterfaceIndexFamilyList
GetMDnsInterfacesToBind() {
69 NetworkInterfaceList network_list
;
70 InterfaceIndexFamilyList interfaces
;
71 if (!GetNetworkList(&network_list
, INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES
))
73 for (size_t i
= 0; i
< network_list
.size(); ++i
) {
74 AddressFamily family
= GetAddressFamily(network_list
[i
].address
);
75 if (family
== ADDRESS_FAMILY_IPV4
|| family
== ADDRESS_FAMILY_IPV6
) {
77 std::make_pair(network_list
[i
].interface_index
, family
));
80 std::sort(interfaces
.begin(), interfaces
.end());
81 // Interfaces could have multiple addresses. Filter out duplicate entries.
82 interfaces
.erase(std::unique(interfaces
.begin(), interfaces
.end()),
87 scoped_ptr
<DatagramServerSocket
> CreateAndBindMDnsSocket(
88 AddressFamily address_family
,
89 uint32 interface_index
) {
90 scoped_ptr
<DatagramServerSocket
> socket(
91 new UDPServerSocket(NULL
, NetLog::Source()));
93 IPEndPoint multicast_addr
= GetMDnsIPEndPoint(address_family
);
94 int rv
= Bind(multicast_addr
, interface_index
, socket
.get());
97 VLOG(1) << "Bind failed, endpoint=" << multicast_addr
.ToStringWithoutPort()
100 return socket
.Pass();