OLD | NEW |
| (Empty) |
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, INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES)) | |
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.Pass(); | |
100 } | |
101 | |
102 } // namespace net | |
OLD | NEW |