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/dns/dns_protocol.h"
9 #include "net/dns/mdns_client_impl.h"
15 const char kMDnsMulticastGroupIPv4
[] = "224.0.0.251";
16 const char kMDnsMulticastGroupIPv6
[] = "FF02::FB";
18 IPEndPoint
GetMDnsIPEndPoint(const char* address
) {
19 IPAddressNumber multicast_group_number
;
20 bool success
= ParseIPLiteralToNumber(address
,
21 &multicast_group_number
);
23 return IPEndPoint(multicast_group_number
,
24 dns_protocol::kDefaultPortMulticast
);
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());
33 socket
->AllowAddressReuse();
34 socket
->SetMulticastInterface(interface_index
);
36 int rv
= socket
->Listen(bind_endpoint
);
40 return socket
->JoinGroup(multicast_addr
.address());
46 scoped_ptr
<MDnsSocketFactory
> MDnsSocketFactory::CreateDefault() {
47 return scoped_ptr
<MDnsSocketFactory
>(new MDnsSocketFactoryImpl
);
51 scoped_ptr
<MDnsClient
> MDnsClient::CreateDefault() {
52 return scoped_ptr
<MDnsClient
>(new MDnsClientImpl());
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
);
67 InterfaceIndexFamilyList
GetMDnsInterfacesToBind() {
68 NetworkInterfaceList network_list
;
69 InterfaceIndexFamilyList interfaces
;
70 if (!GetNetworkList(&network_list
, INCLUDE_HOST_SCOPE_VIRTUAL_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
) {
76 std::make_pair(network_list
[i
].interface_index
, family
));
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()),
86 scoped_ptr
<DatagramServerSocket
> CreateAndBindMDnsSocket(
87 AddressFamily address_family
,
88 uint32 interface_index
) {
89 scoped_ptr
<DatagramServerSocket
> socket(
90 new UDPServerSocket(NULL
, NetLog::Source()));
92 IPEndPoint multicast_addr
= GetMDnsIPEndPoint(address_family
);
93 int rv
= Bind(multicast_addr
, interface_index
, socket
.get());
96 VLOG(1) << "Bind failed, endpoint=" << multicast_addr
.ToStringWithoutPort()
99 return socket
.PassAs
<DatagramServerSocket
>();