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

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
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 const unsigned MDnsTransactionTimeoutSeconds = 3; 27 const unsigned MDnsTransactionTimeoutSeconds = 3;
28 } 28 }
29 29
30 MDnsConnection::SocketHandler::SocketHandler( 30 MDnsConnection::SocketHandler::SocketHandler(scoped_ptr<Socket> socket,
31 MDnsConnection* connection, const IPEndPoint& multicast_addr, 31 MDnsConnection* connection)
32 MDnsConnection::SocketFactory* socket_factory) 32 : socket_(socket.Pass()),
33 : socket_(socket_factory->CreateSocket()), connection_(connection), 33 connection_(connection),
34 response_(new DnsResponse(dns_protocol::kMaxMulticastSize)), 34 response_(dns_protocol::kMaxMulticastSize) {
35 multicast_addr_(multicast_addr) {
36 } 35 }
37 36
38 MDnsConnection::SocketHandler::~SocketHandler() { 37 MDnsConnection::SocketHandler::~SocketHandler() {
39 } 38 }
40 39
41 int MDnsConnection::SocketHandler::Start() { 40 int MDnsConnection::SocketHandler::Start() {
42 return DoLoop(0); 41 return DoLoop(0);
43 } 42 }
44 43
45 int MDnsConnection::SocketHandler::DoLoop(int rv) { 44 int MDnsConnection::SocketHandler::DoLoop(int rv) {
46 do { 45 do {
47 if (rv > 0) 46 if (rv > 0)
48 connection_->OnDatagramReceived(response_.get(), recv_addr_, rv); 47 connection_->OnDatagramReceived(&response_, recv_addr_, rv);
49 48
50 rv = socket_->RecvFrom( 49 rv = socket_->RecvFrom(
51 response_->io_buffer(), 50 response_.io_buffer(),
52 response_->io_buffer()->size(), 51 response_.io_buffer()->size(),
53 &recv_addr_, 52 &recv_addr_,
54 base::Bind(&MDnsConnection::SocketHandler::OnDatagramReceived, 53 base::Bind(&MDnsConnection::SocketHandler::OnDatagramReceived,
55 base::Unretained(this))); 54 base::Unretained(this)));
56 } while (rv > 0); 55 } while (rv > 0);
57 56
58 if (rv != ERR_IO_PENDING) 57 if (rv != ERR_IO_PENDING)
59 return rv; 58 return rv;
60 59
61 return OK; 60 return OK;
62 } 61 }
63 62
64 void MDnsConnection::SocketHandler::OnDatagramReceived(int rv) { 63 void MDnsConnection::SocketHandler::OnDatagramReceived(int rv) {
65 if (rv >= OK) 64 if (rv >= OK)
66 rv = DoLoop(rv); 65 rv = DoLoop(rv);
67 66
68 if (rv != OK) 67 if (rv != OK)
69 connection_->OnError(this, rv); 68 connection_->OnError(this, rv);
70 } 69 }
71 70
72 int MDnsConnection::SocketHandler::Send(IOBuffer* buffer, unsigned size) { 71 int MDnsConnection::SocketHandler::Send(IOBuffer* buffer, unsigned size) {
73 return socket_->SendTo( 72 return socket_->SendTo(buffer, size,
74 buffer, size, multicast_addr_, 73 base::Bind(&MDnsConnection::SocketHandler::SendDone,
75 base::Bind(&MDnsConnection::SocketHandler::SendDone, 74 base::Unretained(this) ));
76 base::Unretained(this) ));
77 } 75 }
78 76
79 void MDnsConnection::SocketHandler::SendDone(int rv) { 77 void MDnsConnection::SocketHandler::SendDone(int rv) {
80 // TODO(noamsml): Retry logic. 78 // TODO(noamsml): Retry logic.
81 } 79 }
82 80
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) : 81 MDnsConnection::MDnsConnection(MDnsConnection::Delegate* delegate) :
99 delegate_(delegate) { 82 delegate_(delegate) {
100 } 83 }
101 84
102 MDnsConnection::~MDnsConnection() { 85 MDnsConnection::~MDnsConnection() {
103 } 86 }
104 87
105 bool MDnsConnection::Init(MDnsConnection::SocketFactory* socket_factory) { 88 bool MDnsConnection::Init(MDnsConnection::SocketFactory* socket_factory) {
106 // TODO(vitalybuka): crbug.com/297690 Make socket_factory return list 89 ScopedVector<Socket> sockets;
107 // of initialized sockets. 90 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 91
115 for (size_t i = 0; i < socket_handlers_.size();) { 92 for (size_t i = 0; i < sockets.size(); ++i) {
116 int rv = socket_handlers_[i]->Bind(); 93 socket_handlers_.push_back(
szym 2013/11/27 00:28:09 Empty sockets (which failed to bind in CreateSocke
Vitaly Buka (NO REVIEWS) 2013/11/27 00:45:45 CreateSockets should filter. That was initial idea
117 if (rv != OK) { 94 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 } 95 }
96 sockets.weak_clear();
124 97
125 // All unbound sockets need to be bound before processing untrusted input. 98 // 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 99 // This is done for security reasons, so that an attacker can't get an unbound
127 // socket. 100 // socket.
128 for (size_t i = 0; i < socket_handlers_.size();) { 101 for (size_t i = 0; i < socket_handlers_.size();) {
129 int rv = socket_handlers_[i]->Start(); 102 int rv = socket_handlers_[i]->Start();
130 if (rv != OK) { 103 if (rv != OK) {
131 socket_handlers_.erase(socket_handlers_.begin() + i); 104 socket_handlers_.erase(socket_handlers_.begin() + i);
132 VLOG(1) << "Start failed, socket=" << i << ", error=" << rv; 105 VLOG(1) << "Start failed, socket=" << i << ", error=" << rv;
133 } else { 106 } else {
(...skipping 26 matching lines...) Expand all
160 133
161 void MDnsConnection::OnDatagramReceived( 134 void MDnsConnection::OnDatagramReceived(
162 DnsResponse* response, 135 DnsResponse* response,
163 const IPEndPoint& recv_addr, 136 const IPEndPoint& recv_addr,
164 int bytes_read) { 137 int bytes_read) {
165 // TODO(noamsml): More sophisticated error handling. 138 // TODO(noamsml): More sophisticated error handling.
166 DCHECK_GT(bytes_read, 0); 139 DCHECK_GT(bytes_read, 0);
167 delegate_->HandlePacket(response, bytes_read); 140 delegate_->HandlePacket(response, bytes_read);
168 } 141 }
169 142
143 class SocketImpl : public MDnsConnection::Socket {
144 public:
145 explicit SocketImpl(const IPEndPoint& multicast_addr)
146 : multicast_addr_(multicast_addr),
147 socket_(NULL, NetLog::Source()) {};
148 virtual ~SocketImpl() {};
149
150 int Bind() {
151 IPAddressNumber address_any(multicast_addr_.address().size());
152 IPEndPoint bind_endpoint(address_any, multicast_addr_.port());
153
154 socket_.AllowAddressReuse();
155 int rv = socket_.Listen(bind_endpoint);
156 if (rv < OK)
157 return rv;
158
159 socket_.SetMulticastLoopbackMode(false);
160 return socket_.JoinGroup(multicast_addr_.address());
161 }
162
163 virtual int RecvFrom(IOBuffer* buf,
164 int buf_len,
165 IPEndPoint* address,
166 const CompletionCallback& callback) OVERRIDE {
167 return socket_.RecvFrom(buf, buf_len, address, callback);
168 }
169
170 virtual int SendTo(IOBuffer* buf,
171 int buf_len,
172 const CompletionCallback& callback) OVERRIDE {
173 return socket_.SendTo(buf, buf_len, multicast_addr_, callback);
174 }
175
176 private:
177 IPEndPoint multicast_addr_;
178 UDPServerSocket socket_;
179
180 DISALLOW_COPY_AND_ASSIGN(SocketImpl);
181 };
182
170 class MDnsConnectionSocketFactoryImpl 183 class MDnsConnectionSocketFactoryImpl
171 : public MDnsConnection::SocketFactory { 184 : public MDnsConnection::SocketFactory {
172 public: 185 public:
173 MDnsConnectionSocketFactoryImpl(); 186 MDnsConnectionSocketFactoryImpl() {};
174 virtual ~MDnsConnectionSocketFactoryImpl(); 187 virtual ~MDnsConnectionSocketFactoryImpl() {};
175 188
176 virtual scoped_ptr<DatagramServerSocket> CreateSocket() OVERRIDE; 189 virtual void CreateSockets(
190 ScopedVector<MDnsConnection::Socket>* sockets) OVERRIDE {
191 sockets->push_back(CreateSocket(ADDRESS_FAMILY_IPV4).release());
192 sockets->push_back(CreateSocket(ADDRESS_FAMILY_IPV6).release());
193 }
194
195 private:
196 scoped_ptr<MDnsConnection::Socket> CreateSocket(
197 AddressFamily address_family) {
198 scoped_ptr<SocketImpl> socket(
199 new SocketImpl(GetMDnsIPEndPoint(address_family)));
200 int rv = socket->Bind();
201 if (rv != OK) {
202 VLOG(1) << "Bind failed, family=" << address_family << ", error=" << rv;
203 socket.reset();
204 }
205 return socket.PassAs<MDnsConnection::Socket>();
206 }
207
208 DISALLOW_COPY_AND_ASSIGN(MDnsConnectionSocketFactoryImpl);
177 }; 209 };
178 210
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 211 // static
192 scoped_ptr<MDnsConnection::SocketFactory> 212 scoped_ptr<MDnsConnection::SocketFactory>
193 MDnsConnection::SocketFactory::CreateDefault() { 213 MDnsConnection::SocketFactory::CreateDefault() {
194 return scoped_ptr<MDnsConnection::SocketFactory>( 214 return scoped_ptr<MDnsConnection::SocketFactory>(
195 new MDnsConnectionSocketFactoryImpl); 215 new MDnsConnectionSocketFactoryImpl);
196 } 216 }
197 217
198 MDnsClientImpl::Core::Core(MDnsClientImpl* client) 218 MDnsClientImpl::Core::Core(MDnsClientImpl* client)
199 : client_(client), connection_(new MDnsConnection(this)) { 219 : client_(client), connection_(new MDnsConnection(this)) {
200 } 220 }
(...skipping 463 matching lines...) Expand 10 before | Expand all | Expand 10 after
664 684
665 void MDnsTransactionImpl::OnNsecRecord(const std::string& name, unsigned type) { 685 void MDnsTransactionImpl::OnNsecRecord(const std::string& name, unsigned type) {
666 TriggerCallback(RESULT_NSEC, NULL); 686 TriggerCallback(RESULT_NSEC, NULL);
667 } 687 }
668 688
669 void MDnsTransactionImpl::OnCachePurged() { 689 void MDnsTransactionImpl::OnCachePurged() {
670 // TODO(noamsml): Cache purge situations not yet implemented 690 // TODO(noamsml): Cache purge situations not yet implemented
671 } 691 }
672 692
673 } // namespace net 693 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698