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

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: Fri Sep 19 13:57:38 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
« 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 <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 23 matching lines...) Expand all
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_->OnError(this, rv);
99 } 102 }
100 103
101 int MDnsConnection::SocketHandler::Send(IOBuffer* buffer, unsigned size) { 104 void MDnsConnection::SocketHandler::Send(
102 return socket_->SendTo(buffer, size, multicast_addr_, 105 const scoped_refptr<IOBufferWithSize>& buffer) {
103 base::Bind(&MDnsConnection::SocketHandler::SendDone, 106 if (send_in_progress_) {
104 base::Unretained(this) )); 107 send_queue_.push(buffer);
108 return;
109 }
110 int rv = socket_->SendTo(buffer.get(),
111 buffer->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 return;
Sergey Ulanov 2014/09/19 21:11:27 Maybe remove return and use else below.
Vitaly Buka (NO REVIEWS) 2014/09/19 21:33:27 Done.
118 }
119 if (rv < OK)
120 connection_->OnError(this, rv);
105 } 121 }
106 122
107 void MDnsConnection::SocketHandler::SendDone(int rv) { 123 void MDnsConnection::SocketHandler::SendDone(int rv) {
108 // TODO(noamsml): Retry logic. 124 DCHECK(send_in_progress_);
125 if (rv == ERR_IO_PENDING)
Vitaly Buka (NO REVIEWS) 2014/09/19 21:04:46 Looks like in both implementations ERR_IO_PENDING
126 return;
127 send_in_progress_ = false;
128 if (rv < OK)
129 connection_->OnError(this, rv);
Sergey Ulanov 2014/09/19 21:11:27 Is OnConnectionError() handler allowed to delete M
Vitaly Buka (NO REVIEWS) 2014/09/19 21:33:27 Done.
130 while (!send_in_progress_ && !send_queue_.empty()) {
131 scoped_refptr<IOBufferWithSize> buffer = send_queue_.front();
132 send_queue_.pop();
133 Send(buffer);
134 }
109 } 135 }
110 136
111 MDnsConnection::MDnsConnection(MDnsConnection::Delegate* delegate) : 137 MDnsConnection::MDnsConnection(MDnsConnection::Delegate* delegate) :
112 delegate_(delegate) { 138 delegate_(delegate) {
113 } 139 }
114 140
115 MDnsConnection::~MDnsConnection() { 141 MDnsConnection::~MDnsConnection() {
116 } 142 }
117 143
118 bool MDnsConnection::Init(MDnsSocketFactory* socket_factory) { 144 bool MDnsConnection::Init(MDnsSocketFactory* socket_factory) {
(...skipping 15 matching lines...) Expand all
134 socket_handlers_.erase(socket_handlers_.begin() + i); 160 socket_handlers_.erase(socket_handlers_.begin() + i);
135 VLOG(1) << "Start failed, socket=" << i << ", error=" << rv; 161 VLOG(1) << "Start failed, socket=" << i << ", error=" << rv;
136 } else { 162 } else {
137 ++i; 163 ++i;
138 } 164 }
139 } 165 }
140 VLOG(1) << "Sockets ready:" << socket_handlers_.size(); 166 VLOG(1) << "Sockets ready:" << socket_handlers_.size();
141 return !socket_handlers_.empty(); 167 return !socket_handlers_.empty();
142 } 168 }
143 169
144 bool MDnsConnection::Send(IOBuffer* buffer, unsigned size) { 170 void MDnsConnection::Send(const scoped_refptr<IOBufferWithSize>& buffer) {
145 bool success = false; 171 for (size_t i = 0; i < socket_handlers_.size(); ++i)
146 for (size_t i = 0; i < socket_handlers_.size(); ++i) { 172 socket_handlers_[i]->Send(buffer);
147 int rv = 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 } 173 }
156 174
157 void MDnsConnection::OnError(SocketHandler* loop, 175 void MDnsConnection::OnError(SocketHandler* loop, int rv) {
158 int error) { 176 int socket =
177 std::find(socket_handlers_.begin(), socket_handlers_.end(), loop) -
178 socket_handlers_.begin();
179 VLOG(1) << "Socket error. id=" << socket << ", error=" << rv;
159 // TODO(noamsml): Specific handling of intermittent errors that can be handled 180 // TODO(noamsml): Specific handling of intermittent errors that can be handled
160 // in the connection. 181 // in the connection.
161 delegate_->OnConnectionError(error); 182 delegate_->OnConnectionError(rv);
162 } 183 }
163 184
164 void MDnsConnection::OnDatagramReceived( 185 void MDnsConnection::OnDatagramReceived(
165 DnsResponse* response, 186 DnsResponse* response,
166 const IPEndPoint& recv_addr, 187 const IPEndPoint& recv_addr,
167 int bytes_read) { 188 int bytes_read) {
168 // TODO(noamsml): More sophisticated error handling. 189 // TODO(noamsml): More sophisticated error handling.
169 DCHECK_GT(bytes_read, 0); 190 DCHECK_GT(bytes_read, 0);
170 delegate_->HandlePacket(response, bytes_read); 191 delegate_->HandlePacket(response, bytes_read);
171 } 192 }
(...skipping 11 matching lines...) Expand all
183 } 204 }
184 205
185 bool MDnsClientImpl::Core::SendQuery(uint16 rrtype, std::string name) { 206 bool MDnsClientImpl::Core::SendQuery(uint16 rrtype, std::string name) {
186 std::string name_dns; 207 std::string name_dns;
187 if (!DNSDomainFromDot(name, &name_dns)) 208 if (!DNSDomainFromDot(name, &name_dns))
188 return false; 209 return false;
189 210
190 DnsQuery query(0, name_dns, rrtype); 211 DnsQuery query(0, name_dns, rrtype);
191 query.set_flags(0); // Remove the RD flag from the query. It is unneeded. 212 query.set_flags(0); // Remove the RD flag from the query. It is unneeded.
192 213
193 return connection_->Send(query.io_buffer(), query.io_buffer()->size()); 214 connection_->Send(query.io_buffer());
215 return true;
194 } 216 }
195 217
196 void MDnsClientImpl::Core::HandlePacket(DnsResponse* response, 218 void MDnsClientImpl::Core::HandlePacket(DnsResponse* response,
197 int bytes_read) { 219 int bytes_read) {
198 unsigned offset; 220 unsigned offset;
199 // Note: We store cache keys rather than record pointers to avoid 221 // Note: We store cache keys rather than record pointers to avoid
200 // erroneous behavior in case a packet contains multiple exclusive 222 // erroneous behavior in case a packet contains multiple exclusive
201 // records with the same type and name. 223 // records with the same type and name.
202 std::map<MDnsCache::Key, MDnsCache::UpdateType> update_keys; 224 std::map<MDnsCache::Key, MDnsCache::UpdateType> update_keys;
203 225
(...skipping 497 matching lines...) Expand 10 before | Expand all | Expand 10 after
701 723
702 void MDnsTransactionImpl::OnNsecRecord(const std::string& name, unsigned type) { 724 void MDnsTransactionImpl::OnNsecRecord(const std::string& name, unsigned type) {
703 TriggerCallback(RESULT_NSEC, NULL); 725 TriggerCallback(RESULT_NSEC, NULL);
704 } 726 }
705 727
706 void MDnsTransactionImpl::OnCachePurged() { 728 void MDnsTransactionImpl::OnCachePurged() {
707 // TODO(noamsml): Cache purge situations not yet implemented 729 // TODO(noamsml): Cache purge situations not yet implemented
708 } 730 }
709 731
710 } // namespace net 732 } // 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