Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(35)

Side by Side Diff: net/dns/mdns_client_impl.cc

Issue 87693002: Refactored to make MDnsSocketFactory return array of sockets. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/dns/mdns_client_impl.h ('k') | net/dns/mdns_client_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/dns/mdns_client_impl.h" 5 #include "net/dns/mdns_client_impl.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/message_loop/message_loop_proxy.h" 8 #include "base/message_loop/message_loop_proxy.h"
9 #include "base/stl_util.h" 9 #include "base/stl_util.h"
10 #include "base/time/default_clock.h" 10 #include "base/time/default_clock.h"
11 #include "net/base/dns_util.h" 11 #include "net/base/dns_util.h"
12 #include "net/base/net_errors.h" 12 #include "net/base/net_errors.h"
13 #include "net/base/net_log.h" 13 #include "net/base/net_log.h"
14 #include "net/base/rand_callback.h" 14 #include "net/base/rand_callback.h"
15 #include "net/dns/dns_protocol.h" 15 #include "net/dns/dns_protocol.h"
16 #include "net/dns/record_rdata.h" 16 #include "net/dns/record_rdata.h"
17 #include "net/udp/datagram_socket.h" 17 #include "net/udp/datagram_socket.h"
18 18
19 // TODO(gene): Remove this temporary method of disabling NSEC support once it 19 // TODO(gene): Remove this temporary method of disabling NSEC support once it
20 // becomes clear whether this feature should be 20 // becomes clear whether this feature should be
21 // supported. http://crbug.com/255232 21 // supported. http://crbug.com/255232
22 #define ENABLE_NSEC 22 #define ENABLE_NSEC
23 23
24 namespace net { 24 namespace net {
25 25
26 namespace { 26 namespace {
27
27 const unsigned MDnsTransactionTimeoutSeconds = 3; 28 const unsigned MDnsTransactionTimeoutSeconds = 3;
29
30 int Bind(const IPEndPoint& multicast_addr, DatagramServerSocket* socket) {
31 IPAddressNumber address_any(multicast_addr.address().size());
32 IPEndPoint bind_endpoint(address_any, multicast_addr.port());
33
34 socket->AllowAddressReuse();
35 int rv = socket->Listen(bind_endpoint);
36 if (rv < OK)
37 return rv;
38
39 socket->SetMulticastLoopbackMode(false);
40 return socket->JoinGroup(multicast_addr.address());
28 } 41 }
29 42
43 void CreateAndBindSocket(AddressFamily address_family,
44 ScopedVector<DatagramServerSocket>* sockets) {
45 scoped_ptr<DatagramServerSocket> socket(
46 new UDPServerSocket(NULL, NetLog::Source()));
47
48 IPEndPoint multicast_addr = GetMDnsIPEndPoint(address_family);
49 int rv = Bind(multicast_addr, socket.get());
50 if (rv == OK) {
51 sockets->push_back(socket.release());
52 } else {
53 VLOG(1) << "Bind failed, endpoint=" << multicast_addr.ToStringWithoutPort()
54 << ", error=" << rv;
55 }
56 }
57
58 } // namespace
59
60 void MDnsSocketFactoryImpl::CreateSockets(
61 ScopedVector<DatagramServerSocket>* sockets) {
62 CreateAndBindSocket(ADDRESS_FAMILY_IPV4, sockets);
63 CreateAndBindSocket(ADDRESS_FAMILY_IPV6, sockets);
64 }
65
66
67
30 MDnsConnection::SocketHandler::SocketHandler( 68 MDnsConnection::SocketHandler::SocketHandler(
31 MDnsConnection* connection, const IPEndPoint& multicast_addr, 69 scoped_ptr<DatagramServerSocket> socket,
32 MDnsConnection::SocketFactory* socket_factory) 70 MDnsConnection* connection)
33 : socket_(socket_factory->CreateSocket()), connection_(connection), 71 : socket_(socket.Pass()),
34 response_(new DnsResponse(dns_protocol::kMaxMulticastSize)), 72 connection_(connection),
35 multicast_addr_(multicast_addr) { 73 response_(dns_protocol::kMaxMulticastSize) {
36 } 74 }
37 75
38 MDnsConnection::SocketHandler::~SocketHandler() { 76 MDnsConnection::SocketHandler::~SocketHandler() {
39 } 77 }
40 78
41 int MDnsConnection::SocketHandler::Start() { 79 int MDnsConnection::SocketHandler::Start() {
80 IPEndPoint end_point;
81 int rv = socket_->GetLocalAddress(&end_point);
82 if (rv != OK)
83 return rv;
84 DCHECK(end_point.GetFamily() == ADDRESS_FAMILY_IPV4 ||
85 end_point.GetFamily() == ADDRESS_FAMILY_IPV6);
86 multicast_addr_ = GetMDnsIPEndPoint(end_point.GetFamily());
42 return DoLoop(0); 87 return DoLoop(0);
43 } 88 }
44 89
45 int MDnsConnection::SocketHandler::DoLoop(int rv) { 90 int MDnsConnection::SocketHandler::DoLoop(int rv) {
46 do { 91 do {
47 if (rv > 0) 92 if (rv > 0)
48 connection_->OnDatagramReceived(response_.get(), recv_addr_, rv); 93 connection_->OnDatagramReceived(&response_, recv_addr_, rv);
49 94
50 rv = socket_->RecvFrom( 95 rv = socket_->RecvFrom(
51 response_->io_buffer(), 96 response_.io_buffer(),
52 response_->io_buffer()->size(), 97 response_.io_buffer()->size(),
53 &recv_addr_, 98 &recv_addr_,
54 base::Bind(&MDnsConnection::SocketHandler::OnDatagramReceived, 99 base::Bind(&MDnsConnection::SocketHandler::OnDatagramReceived,
55 base::Unretained(this))); 100 base::Unretained(this)));
56 } while (rv > 0); 101 } while (rv > 0);
57 102
58 if (rv != ERR_IO_PENDING) 103 if (rv != ERR_IO_PENDING)
59 return rv; 104 return rv;
60 105
61 return OK; 106 return OK;
62 } 107 }
63 108
64 void MDnsConnection::SocketHandler::OnDatagramReceived(int rv) { 109 void MDnsConnection::SocketHandler::OnDatagramReceived(int rv) {
65 if (rv >= OK) 110 if (rv >= OK)
66 rv = DoLoop(rv); 111 rv = DoLoop(rv);
67 112
68 if (rv != OK) 113 if (rv != OK)
69 connection_->OnError(this, rv); 114 connection_->OnError(this, rv);
70 } 115 }
71 116
72 int MDnsConnection::SocketHandler::Send(IOBuffer* buffer, unsigned size) { 117 int MDnsConnection::SocketHandler::Send(IOBuffer* buffer, unsigned size) {
73 return socket_->SendTo( 118 return socket_->SendTo(buffer, size, multicast_addr_,
74 buffer, size, multicast_addr_, 119 base::Bind(&MDnsConnection::SocketHandler::SendDone,
75 base::Bind(&MDnsConnection::SocketHandler::SendDone, 120 base::Unretained(this) ));
76 base::Unretained(this) ));
77 } 121 }
78 122
79 void MDnsConnection::SocketHandler::SendDone(int rv) { 123 void MDnsConnection::SocketHandler::SendDone(int rv) {
80 // TODO(noamsml): Retry logic. 124 // TODO(noamsml): Retry logic.
81 } 125 }
82 126
83 int MDnsConnection::SocketHandler::Bind() {
84 IPAddressNumber address_any(multicast_addr_.address().size());
85
86 IPEndPoint bind_endpoint(address_any, multicast_addr_.port());
87
88 socket_->AllowAddressReuse();
89 int rv = socket_->Listen(bind_endpoint);
90
91 if (rv < OK) return rv;
92
93 socket_->SetMulticastLoopbackMode(false);
94
95 return socket_->JoinGroup(multicast_addr_.address());
96 }
97
98 MDnsConnection::MDnsConnection(MDnsConnection::Delegate* delegate) : 127 MDnsConnection::MDnsConnection(MDnsConnection::Delegate* delegate) :
99 delegate_(delegate) { 128 delegate_(delegate) {
100 } 129 }
101 130
102 MDnsConnection::~MDnsConnection() { 131 MDnsConnection::~MDnsConnection() {
103 } 132 }
104 133
105 bool MDnsConnection::Init(MDnsConnection::SocketFactory* socket_factory) { 134 bool MDnsConnection::Init(MDnsSocketFactory* socket_factory) {
106 // TODO(vitalybuka): crbug.com/297690 Make socket_factory return list 135 ScopedVector<DatagramServerSocket> sockets;
107 // of initialized sockets. 136 socket_factory->CreateSockets(&sockets);
108 socket_handlers_.push_back(
109 new SocketHandler(this, GetMDnsIPEndPoint(ADDRESS_FAMILY_IPV4),
110 socket_factory));
111 socket_handlers_.push_back(
112 new SocketHandler(this, GetMDnsIPEndPoint(ADDRESS_FAMILY_IPV6),
113 socket_factory));
114 137
115 for (size_t i = 0; i < socket_handlers_.size();) { 138 for (size_t i = 0; i < sockets.size(); ++i) {
116 int rv = socket_handlers_[i]->Bind(); 139 socket_handlers_.push_back(
117 if (rv != OK) { 140 new MDnsConnection::SocketHandler(make_scoped_ptr(sockets[i]), this));
118 socket_handlers_.erase(socket_handlers_.begin() + i);
119 VLOG(1) << "Bind failed, socket=" << i << ", error=" << rv;
120 } else {
121 ++i;
122 }
123 } 141 }
142 sockets.weak_clear();
124 143
125 // All unbound sockets need to be bound before processing untrusted input. 144 // All unbound sockets need to be bound before processing untrusted input.
126 // This is done for security reasons, so that an attacker can't get an unbound 145 // This is done for security reasons, so that an attacker can't get an unbound
127 // socket. 146 // socket.
128 for (size_t i = 0; i < socket_handlers_.size();) { 147 for (size_t i = 0; i < socket_handlers_.size();) {
129 int rv = socket_handlers_[i]->Start(); 148 int rv = socket_handlers_[i]->Start();
130 if (rv != OK) { 149 if (rv != OK) {
131 socket_handlers_.erase(socket_handlers_.begin() + i); 150 socket_handlers_.erase(socket_handlers_.begin() + i);
132 VLOG(1) << "Start failed, socket=" << i << ", error=" << rv; 151 VLOG(1) << "Start failed, socket=" << i << ", error=" << rv;
133 } else { 152 } else {
(...skipping 26 matching lines...) Expand all
160 179
161 void MDnsConnection::OnDatagramReceived( 180 void MDnsConnection::OnDatagramReceived(
162 DnsResponse* response, 181 DnsResponse* response,
163 const IPEndPoint& recv_addr, 182 const IPEndPoint& recv_addr,
164 int bytes_read) { 183 int bytes_read) {
165 // TODO(noamsml): More sophisticated error handling. 184 // TODO(noamsml): More sophisticated error handling.
166 DCHECK_GT(bytes_read, 0); 185 DCHECK_GT(bytes_read, 0);
167 delegate_->HandlePacket(response, bytes_read); 186 delegate_->HandlePacket(response, bytes_read);
168 } 187 }
169 188
170 class MDnsConnectionSocketFactoryImpl
171 : public MDnsConnection::SocketFactory {
172 public:
173 MDnsConnectionSocketFactoryImpl();
174 virtual ~MDnsConnectionSocketFactoryImpl();
175
176 virtual scoped_ptr<DatagramServerSocket> CreateSocket() OVERRIDE;
177 };
178
179 MDnsConnectionSocketFactoryImpl::MDnsConnectionSocketFactoryImpl() {
180 }
181
182 MDnsConnectionSocketFactoryImpl::~MDnsConnectionSocketFactoryImpl() {
183 }
184
185 scoped_ptr<DatagramServerSocket>
186 MDnsConnectionSocketFactoryImpl::CreateSocket() {
187 return scoped_ptr<DatagramServerSocket>(new UDPServerSocket(
188 NULL, NetLog::Source()));
189 }
190
191 // static
192 scoped_ptr<MDnsConnection::SocketFactory>
193 MDnsConnection::SocketFactory::CreateDefault() {
194 return scoped_ptr<MDnsConnection::SocketFactory>(
195 new MDnsConnectionSocketFactoryImpl);
196 }
197
198 MDnsClientImpl::Core::Core(MDnsClientImpl* client) 189 MDnsClientImpl::Core::Core(MDnsClientImpl* client)
199 : client_(client), connection_(new MDnsConnection(this)) { 190 : client_(client), connection_(new MDnsConnection(this)) {
200 } 191 }
201 192
202 MDnsClientImpl::Core::~Core() { 193 MDnsClientImpl::Core::~Core() {
203 STLDeleteValues(&listeners_); 194 STLDeleteValues(&listeners_);
204 } 195 }
205 196
206 bool MDnsClientImpl::Core::Init(MDnsConnection::SocketFactory* socket_factory) { 197 bool MDnsClientImpl::Core::Init(MDnsSocketFactory* socket_factory) {
207 return connection_->Init(socket_factory); 198 return connection_->Init(socket_factory);
208 } 199 }
209 200
210 bool MDnsClientImpl::Core::SendQuery(uint16 rrtype, std::string name) { 201 bool MDnsClientImpl::Core::SendQuery(uint16 rrtype, std::string name) {
211 std::string name_dns; 202 std::string name_dns;
212 if (!DNSDomainFromDot(name, &name_dns)) 203 if (!DNSDomainFromDot(name, &name_dns))
213 return false; 204 return false;
214 205
215 DnsQuery query(0, name_dns, rrtype); 206 DnsQuery query(0, name_dns, rrtype);
216 query.set_flags(0); // Remove the RD flag from the query. It is unneeded. 207 query.set_flags(0); // Remove the RD flag from the query. It is unneeded.
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
427 AlertListeners(MDnsListener::RECORD_REMOVED, 418 AlertListeners(MDnsListener::RECORD_REMOVED,
428 ListenerKey(record->name(), record->type()), record); 419 ListenerKey(record->name(), record->type()), record);
429 } 420 }
430 421
431 void MDnsClientImpl::Core::QueryCache( 422 void MDnsClientImpl::Core::QueryCache(
432 uint16 rrtype, const std::string& name, 423 uint16 rrtype, const std::string& name,
433 std::vector<const RecordParsed*>* records) const { 424 std::vector<const RecordParsed*>* records) const {
434 cache_.FindDnsRecords(rrtype, name, records, base::Time::Now()); 425 cache_.FindDnsRecords(rrtype, name, records, base::Time::Now());
435 } 426 }
436 427
437 MDnsClientImpl::MDnsClientImpl( 428 MDnsClientImpl::MDnsClientImpl() {
438 scoped_ptr<MDnsConnection::SocketFactory> socket_factory)
439 : socket_factory_(socket_factory.Pass()) {
440 } 429 }
441 430
442 MDnsClientImpl::~MDnsClientImpl() { 431 MDnsClientImpl::~MDnsClientImpl() {
443 } 432 }
444 433
445 bool MDnsClientImpl::StartListening() { 434 bool MDnsClientImpl::StartListening(MDnsSocketFactory* socket_factory) {
446 DCHECK(!core_.get()); 435 DCHECK(!core_.get());
447 core_.reset(new Core(this)); 436 core_.reset(new Core(this));
448 if (!core_->Init(socket_factory_.get())) { 437 if (!core_->Init(socket_factory)) {
449 core_.reset(); 438 core_.reset();
450 return false; 439 return false;
451 } 440 }
452 return true; 441 return true;
453 } 442 }
454 443
455 void MDnsClientImpl::StopListening() { 444 void MDnsClientImpl::StopListening() {
456 core_.reset(); 445 core_.reset();
457 } 446 }
458 447
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
664 653
665 void MDnsTransactionImpl::OnNsecRecord(const std::string& name, unsigned type) { 654 void MDnsTransactionImpl::OnNsecRecord(const std::string& name, unsigned type) {
666 TriggerCallback(RESULT_NSEC, NULL); 655 TriggerCallback(RESULT_NSEC, NULL);
667 } 656 }
668 657
669 void MDnsTransactionImpl::OnCachePurged() { 658 void MDnsTransactionImpl::OnCachePurged() {
670 // TODO(noamsml): Cache purge situations not yet implemented 659 // TODO(noamsml): Cache purge situations not yet implemented
671 } 660 }
672 661
673 } // namespace net 662 } // namespace net
OLDNEW
« no previous file with comments | « net/dns/mdns_client_impl.h ('k') | net/dns/mdns_client_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698