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

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

Issue 581813004: Enqueue mDns requests if send on socket in progress. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Mon Sep 22 15:45:45 PDT 2014 Created 6 years, 3 months 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
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 <queue>
8
7 #include "base/bind.h" 9 #include "base/bind.h"
8 #include "base/message_loop/message_loop_proxy.h" 10 #include "base/message_loop/message_loop_proxy.h"
9 #include "base/stl_util.h" 11 #include "base/stl_util.h"
10 #include "base/time/default_clock.h" 12 #include "base/time/default_clock.h"
11 #include "base/time/time.h" 13 #include "base/time/time.h"
12 #include "net/base/dns_util.h" 14 #include "net/base/dns_util.h"
13 #include "net/base/net_errors.h" 15 #include "net/base/net_errors.h"
14 #include "net/base/net_log.h" 16 #include "net/base/net_log.h"
15 #include "net/base/rand_callback.h" 17 #include "net/base/rand_callback.h"
16 #include "net/dns/dns_protocol.h" 18 #include "net/dns/dns_protocol.h"
(...skipping 30 matching lines...) Expand all
47 if (socket) 49 if (socket)
48 sockets->push_back(socket.release()); 50 sockets->push_back(socket.release());
49 } 51 }
50 } 52 }
51 53
52 MDnsConnection::SocketHandler::SocketHandler( 54 MDnsConnection::SocketHandler::SocketHandler(
53 scoped_ptr<DatagramServerSocket> socket, 55 scoped_ptr<DatagramServerSocket> socket,
54 MDnsConnection* connection) 56 MDnsConnection* connection)
55 : socket_(socket.Pass()), 57 : socket_(socket.Pass()),
56 connection_(connection), 58 connection_(connection),
57 response_(dns_protocol::kMaxMulticastSize) { 59 response_(dns_protocol::kMaxMulticastSize),
60 send_in_progress_(false) {
58 } 61 }
59 62
60 MDnsConnection::SocketHandler::~SocketHandler() { 63 MDnsConnection::SocketHandler::~SocketHandler() {
61 } 64 }
62 65
63 int MDnsConnection::SocketHandler::Start() { 66 int MDnsConnection::SocketHandler::Start() {
64 IPEndPoint end_point; 67 IPEndPoint end_point;
65 int rv = socket_->GetLocalAddress(&end_point); 68 int rv = socket_->GetLocalAddress(&end_point);
66 if (rv != OK) 69 if (rv != OK)
67 return rv; 70 return rv;
(...skipping 20 matching lines...) Expand all
88 return rv; 91 return rv;
89 92
90 return OK; 93 return OK;
91 } 94 }
92 95
93 void MDnsConnection::SocketHandler::OnDatagramReceived(int rv) { 96 void MDnsConnection::SocketHandler::OnDatagramReceived(int rv) {
94 if (rv >= OK) 97 if (rv >= OK)
95 rv = DoLoop(rv); 98 rv = DoLoop(rv);
96 99
97 if (rv != OK) 100 if (rv != OK)
98 connection_->OnError(this, rv); 101 connection_->PostOnError(this, rv);
99 } 102 }
100 103
101 int MDnsConnection::SocketHandler::Send(IOBuffer* buffer, unsigned size) { 104 void MDnsConnection::SocketHandler::Send(const scoped_refptr<IOBuffer>& buffer,
102 return socket_->SendTo(buffer, size, multicast_addr_, 105 unsigned size) {
103 base::Bind(&MDnsConnection::SocketHandler::SendDone, 106 if (send_in_progress_) {
104 base::Unretained(this) )); 107 send_queue_.push(std::make_pair(buffer, size));
108 return;
109 }
110 int rv = socket_->SendTo(buffer.get(),
111 size,
112 multicast_addr_,
113 base::Bind(&MDnsConnection::SocketHandler::SendDone,
114 base::Unretained(this)));
115 if (rv == ERR_IO_PENDING) {
116 send_in_progress_ = true;
117 } else if (rv < OK) {
118 connection_->PostOnError(this, rv);
119 }
105 } 120 }
106 121
107 void MDnsConnection::SocketHandler::SendDone(int rv) { 122 void MDnsConnection::SocketHandler::SendDone(int rv) {
108 // TODO(noamsml): Retry logic. 123 DCHECK(send_in_progress_);
124 send_in_progress_ = false;
125 if (rv != OK)
126 connection_->PostOnError(this, rv);
127 while (!send_in_progress_ && !send_queue_.empty()) {
128 std::pair<scoped_refptr<IOBuffer>, unsigned> buffer = send_queue_.front();
129 send_queue_.pop();
130 Send(buffer.first, buffer.second);
131 }
109 } 132 }
110 133
111 MDnsConnection::MDnsConnection(MDnsConnection::Delegate* delegate) : 134 MDnsConnection::MDnsConnection(MDnsConnection::Delegate* delegate)
112 delegate_(delegate) { 135 : delegate_(delegate), weak_ptr_factory_(this) {
113 } 136 }
114 137
115 MDnsConnection::~MDnsConnection() { 138 MDnsConnection::~MDnsConnection() {
116 } 139 }
117 140
118 bool MDnsConnection::Init(MDnsSocketFactory* socket_factory) { 141 bool MDnsConnection::Init(MDnsSocketFactory* socket_factory) {
119 ScopedVector<DatagramServerSocket> sockets; 142 ScopedVector<DatagramServerSocket> sockets;
120 socket_factory->CreateSockets(&sockets); 143 socket_factory->CreateSockets(&sockets);
121 144
122 for (size_t i = 0; i < sockets.size(); ++i) { 145 for (size_t i = 0; i < sockets.size(); ++i) {
(...skipping 11 matching lines...) Expand all
134 socket_handlers_.erase(socket_handlers_.begin() + i); 157 socket_handlers_.erase(socket_handlers_.begin() + i);
135 VLOG(1) << "Start failed, socket=" << i << ", error=" << rv; 158 VLOG(1) << "Start failed, socket=" << i << ", error=" << rv;
136 } else { 159 } else {
137 ++i; 160 ++i;
138 } 161 }
139 } 162 }
140 VLOG(1) << "Sockets ready:" << socket_handlers_.size(); 163 VLOG(1) << "Sockets ready:" << socket_handlers_.size();
141 return !socket_handlers_.empty(); 164 return !socket_handlers_.empty();
142 } 165 }
143 166
144 bool MDnsConnection::Send(IOBuffer* buffer, unsigned size) { 167 void MDnsConnection::Send(const scoped_refptr<IOBuffer>& buffer,
145 bool success = false; 168 unsigned size) {
146 for (size_t i = 0; i < socket_handlers_.size(); ++i) { 169 for (size_t i = 0; i < socket_handlers_.size(); ++i)
147 int rv = socket_handlers_[i]->Send(buffer, size); 170 socket_handlers_[i]->Send(buffer, size);
148 if (rv >= OK || rv == ERR_IO_PENDING) {
149 success = true;
150 } else {
151 VLOG(1) << "Send failed, socket=" << i << ", error=" << rv;
152 }
153 }
154 return success;
155 } 171 }
156 172
157 void MDnsConnection::OnError(SocketHandler* loop, 173 void MDnsConnection::PostOnError(SocketHandler* loop, int rv) {
158 int error) { 174 VLOG(1) << "Socket error. id="
175 << std::find(socket_handlers_.begin(), socket_handlers_.end(), loop) -
176 socket_handlers_.begin() << ", error=" << rv;
177 // Post to allow deletion of this object by delegate.
178 base::MessageLoop::current()->PostTask(
179 FROM_HERE,
180 base::Bind(&MDnsConnection::OnError, weak_ptr_factory_.GetWeakPtr(), rv));
181 }
182
183 void MDnsConnection::OnError(int rv) {
159 // TODO(noamsml): Specific handling of intermittent errors that can be handled 184 // TODO(noamsml): Specific handling of intermittent errors that can be handled
160 // in the connection. 185 // in the connection.
161 delegate_->OnConnectionError(error); 186 delegate_->OnConnectionError(rv);
162 } 187 }
163 188
164 void MDnsConnection::OnDatagramReceived( 189 void MDnsConnection::OnDatagramReceived(
165 DnsResponse* response, 190 DnsResponse* response,
166 const IPEndPoint& recv_addr, 191 const IPEndPoint& recv_addr,
167 int bytes_read) { 192 int bytes_read) {
168 // TODO(noamsml): More sophisticated error handling. 193 // TODO(noamsml): More sophisticated error handling.
169 DCHECK_GT(bytes_read, 0); 194 DCHECK_GT(bytes_read, 0);
170 delegate_->HandlePacket(response, bytes_read); 195 delegate_->HandlePacket(response, bytes_read);
171 } 196 }
(...skipping 11 matching lines...) Expand all
183 } 208 }
184 209
185 bool MDnsClientImpl::Core::SendQuery(uint16 rrtype, std::string name) { 210 bool MDnsClientImpl::Core::SendQuery(uint16 rrtype, std::string name) {
186 std::string name_dns; 211 std::string name_dns;
187 if (!DNSDomainFromDot(name, &name_dns)) 212 if (!DNSDomainFromDot(name, &name_dns))
188 return false; 213 return false;
189 214
190 DnsQuery query(0, name_dns, rrtype); 215 DnsQuery query(0, name_dns, rrtype);
191 query.set_flags(0); // Remove the RD flag from the query. It is unneeded. 216 query.set_flags(0); // Remove the RD flag from the query. It is unneeded.
192 217
193 return connection_->Send(query.io_buffer(), query.io_buffer()->size()); 218 connection_->Send(query.io_buffer(), query.io_buffer()->size());
219 return true;
194 } 220 }
195 221
196 void MDnsClientImpl::Core::HandlePacket(DnsResponse* response, 222 void MDnsClientImpl::Core::HandlePacket(DnsResponse* response,
197 int bytes_read) { 223 int bytes_read) {
198 unsigned offset; 224 unsigned offset;
199 // Note: We store cache keys rather than record pointers to avoid 225 // Note: We store cache keys rather than record pointers to avoid
200 // erroneous behavior in case a packet contains multiple exclusive 226 // erroneous behavior in case a packet contains multiple exclusive
201 // records with the same type and name. 227 // records with the same type and name.
202 std::map<MDnsCache::Key, MDnsCache::UpdateType> update_keys; 228 std::map<MDnsCache::Key, MDnsCache::UpdateType> update_keys;
203 229
(...skipping 497 matching lines...) Expand 10 before | Expand all | Expand 10 after
701 727
702 void MDnsTransactionImpl::OnNsecRecord(const std::string& name, unsigned type) { 728 void MDnsTransactionImpl::OnNsecRecord(const std::string& name, unsigned type) {
703 TriggerCallback(RESULT_NSEC, NULL); 729 TriggerCallback(RESULT_NSEC, NULL);
704 } 730 }
705 731
706 void MDnsTransactionImpl::OnCachePurged() { 732 void MDnsTransactionImpl::OnCachePurged() {
707 // TODO(noamsml): Cache purge situations not yet implemented 733 // TODO(noamsml): Cache purge situations not yet implemented
708 } 734 }
709 735
710 } // namespace net 736 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698