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

Side by Side Diff: net/udp/udp_socket_libevent.cc

Issue 8200011: Add NetLog support to UDP sockets. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Hex encode bytes Created 9 years, 2 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/udp/udp_socket_libevent.h" 5 #include "net/udp/udp_socket_libevent.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <fcntl.h> 8 #include <fcntl.h>
9 #include <netdb.h> 9 #include <netdb.h>
10 #include <sys/socket.h> 10 #include <sys/socket.h>
11 11
12 #include "base/eintr_wrapper.h" 12 #include "base/eintr_wrapper.h"
13 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "base/message_loop.h" 14 #include "base/message_loop.h"
15 #include "base/metrics/stats_counters.h" 15 #include "base/metrics/stats_counters.h"
16 #include "base/rand_util.h" 16 #include "base/rand_util.h"
17 #include "net/base/io_buffer.h" 17 #include "net/base/io_buffer.h"
18 #include "net/base/ip_endpoint.h" 18 #include "net/base/ip_endpoint.h"
19 #include "net/base/net_errors.h" 19 #include "net/base/net_errors.h"
20 #include "net/base/net_log.h" 20 #include "net/base/net_log.h"
21 #include "net/base/net_util.h" 21 #include "net/base/net_util.h"
22 #include "net/udp/udp_data_transfer_param.h"
22 #if defined(OS_POSIX) 23 #if defined(OS_POSIX)
23 #include <netinet/in.h> 24 #include <netinet/in.h>
24 #endif 25 #endif
25 26
26 namespace { 27 namespace {
27 28
28 static const int kBindRetries = 10; 29 static const int kBindRetries = 10;
29 static const int kPortStart = 1024; 30 static const int kPortStart = 1024;
30 static const int kPortEnd = 65535; 31 static const int kPortEnd = 65535;
31 32
32 } // namespace net 33 } // namespace net
33 34
34 namespace net { 35 namespace net {
35 36
36 UDPSocketLibevent::UDPSocketLibevent( 37 UDPSocketLibevent::UDPSocketLibevent(
37 DatagramSocket::BindType bind_type, 38 DatagramSocket::BindType bind_type,
38 const RandIntCallback& rand_int_cb, 39 const RandIntCallback& rand_int_cb,
39 net::NetLog* net_log, 40 net::NetLog* net_log,
40 const net::NetLog::Source& source) 41 const net::NetLog::Source& source)
41 : socket_(kInvalidSocket), 42 : socket_(kInvalidSocket),
42 bind_type_(bind_type), 43 bind_type_(bind_type),
43 rand_int_cb_(rand_int_cb), 44 rand_int_cb_(rand_int_cb),
44 read_watcher_(this), 45 read_watcher_(this),
45 write_watcher_(this), 46 write_watcher_(this),
46 read_buf_len_(0), 47 read_buf_len_(0),
47 recv_from_address_(NULL), 48 recv_from_address_(NULL),
48 write_buf_len_(0), 49 write_buf_len_(0),
49 read_callback_(NULL), 50 read_callback_(NULL),
50 write_callback_(NULL), 51 write_callback_(NULL),
51 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)) { 52 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_UDP_SOCKET)) {
52 scoped_refptr<NetLog::EventParameters> params; 53 scoped_refptr<NetLog::EventParameters> params;
53 if (source.is_valid()) 54 if (source.is_valid())
54 params = new NetLogSourceParameter("source_dependency", source); 55 params = new NetLogSourceParameter("source_dependency", source);
55 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, params); 56 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, params);
56 if (bind_type == DatagramSocket::RANDOM_BIND) 57 if (bind_type == DatagramSocket::RANDOM_BIND)
57 DCHECK(!rand_int_cb.is_null()); 58 DCHECK(!rand_int_cb.is_null());
58 } 59 }
59 60
60 UDPSocketLibevent::~UDPSocketLibevent() { 61 UDPSocketLibevent::~UDPSocketLibevent() {
61 Close(); 62 Close();
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 IPEndPoint* address, 145 IPEndPoint* address,
145 OldCompletionCallback* callback) { 146 OldCompletionCallback* callback) {
146 DCHECK(CalledOnValidThread()); 147 DCHECK(CalledOnValidThread());
147 DCHECK_NE(kInvalidSocket, socket_); 148 DCHECK_NE(kInvalidSocket, socket_);
148 DCHECK(!read_callback_); 149 DCHECK(!read_callback_);
149 DCHECK(!recv_from_address_); 150 DCHECK(!recv_from_address_);
150 DCHECK(callback); // Synchronous operation not supported 151 DCHECK(callback); // Synchronous operation not supported
151 DCHECK_GT(buf_len, 0); 152 DCHECK_GT(buf_len, 0);
152 153
153 int nread = InternalRecvFrom(buf, buf_len, address); 154 int nread = InternalRecvFrom(buf, buf_len, address);
154 if (nread != ERR_IO_PENDING) 155 if (nread != ERR_IO_PENDING) {
156 if (nread < 0) {
157 net_log_.AddEventWithNetErrorCode(NetLog::TYPE_UDP_RECEIVE_ERROR, nread);
158 }
155 return nread; 159 return nread;
160 }
156 161
157 if (!MessageLoopForIO::current()->WatchFileDescriptor( 162 if (!MessageLoopForIO::current()->WatchFileDescriptor(
158 socket_, true, MessageLoopForIO::WATCH_READ, 163 socket_, true, MessageLoopForIO::WATCH_READ,
159 &read_socket_watcher_, &read_watcher_)) { 164 &read_socket_watcher_, &read_watcher_)) {
160 PLOG(ERROR) << "WatchFileDescriptor failed on read"; 165 PLOG(ERROR) << "WatchFileDescriptor failed on read";
161 return MapSystemError(errno); 166 int net_error = MapSystemError(errno);
167 net_log_.AddEventWithNetErrorCode(NetLog::TYPE_UDP_RECEIVE_ERROR,
168 net_error);
169 return net_error;
162 } 170 }
163 171
164 read_buf_ = buf; 172 read_buf_ = buf;
165 read_buf_len_ = buf_len; 173 read_buf_len_ = buf_len;
166 recv_from_address_ = address; 174 recv_from_address_ = address;
167 read_callback_ = callback; 175 read_callback_ = callback;
168 return ERR_IO_PENDING; 176 return ERR_IO_PENDING;
169 } 177 }
170 178
171 int UDPSocketLibevent::Write(IOBuffer* buf, 179 int UDPSocketLibevent::Write(IOBuffer* buf,
(...skipping 14 matching lines...) Expand all
186 const IPEndPoint* address, 194 const IPEndPoint* address,
187 OldCompletionCallback* callback) { 195 OldCompletionCallback* callback) {
188 DCHECK(CalledOnValidThread()); 196 DCHECK(CalledOnValidThread());
189 DCHECK_NE(kInvalidSocket, socket_); 197 DCHECK_NE(kInvalidSocket, socket_);
190 DCHECK(!write_callback_); 198 DCHECK(!write_callback_);
191 DCHECK(callback); // Synchronous operation not supported 199 DCHECK(callback); // Synchronous operation not supported
192 DCHECK_GT(buf_len, 0); 200 DCHECK_GT(buf_len, 0);
193 201
194 int nwrite = InternalSendTo(buf, buf_len, address); 202 int nwrite = InternalSendTo(buf, buf_len, address);
195 if (nwrite >= 0) { 203 if (nwrite >= 0) {
196 base::StatsCounter write_bytes("udp.write_bytes"); 204 ProcessSuccessfulWrite(nwrite, buf->data(), address);
197 write_bytes.Add(nwrite);
198 return nwrite; 205 return nwrite;
199 } 206 }
200 if (errno != EAGAIN && errno != EWOULDBLOCK) 207 if (errno != EAGAIN && errno != EWOULDBLOCK) {
201 return MapSystemError(errno); 208 int net_error = MapSystemError(errno);
209 net_log_.AddEventWithNetErrorCode(NetLog::TYPE_UDP_SEND_ERROR,
210 net_error);
211 return net_error;
212 }
202 213
203 if (!MessageLoopForIO::current()->WatchFileDescriptor( 214 if (!MessageLoopForIO::current()->WatchFileDescriptor(
204 socket_, true, MessageLoopForIO::WATCH_WRITE, 215 socket_, true, MessageLoopForIO::WATCH_WRITE,
205 &write_socket_watcher_, &write_watcher_)) { 216 &write_socket_watcher_, &write_watcher_)) {
206 DVLOG(1) << "WatchFileDescriptor failed on write, errno " << errno; 217 DVLOG(1) << "WatchFileDescriptor failed on write, errno " << errno;
207 return MapSystemError(errno); 218 int net_error = MapSystemError(errno);
219 net_log_.AddEventWithNetErrorCode(NetLog::TYPE_UDP_SEND_ERROR,
220 net_error);
221 return net_error;
208 } 222 }
209 223
210 write_buf_ = buf; 224 write_buf_ = buf;
211 write_buf_len_ = buf_len; 225 write_buf_len_ = buf_len;
212 DCHECK(!send_to_address_.get()); 226 DCHECK(!send_to_address_.get());
213 if (address) { 227 if (address) {
214 send_to_address_.reset(new IPEndPoint(*address)); 228 send_to_address_.reset(new IPEndPoint(*address));
215 } 229 }
216 write_callback_ = callback; 230 write_callback_ = callback;
217 return ERR_IO_PENDING; 231 return ERR_IO_PENDING;
218 } 232 }
219 233
220 int UDPSocketLibevent::Connect(const IPEndPoint& address) { 234 int UDPSocketLibevent::Connect(const IPEndPoint& address) {
235 net_log_.BeginEvent(
236 NetLog::TYPE_UDP_CONNECT,
237 make_scoped_refptr(new NetLogStringParameter("address",
238 address.ToString())));
239 int rv = InternalConnect(address);
eroman 2011/10/11 20:50:07 So this can only complete synchronously?
mmenke 2011/10/11 21:06:27 Apparently not. I wondered that, too, but there's
240 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_UDP_CONNECT, rv);
241 return rv;
242 }
243
244 int UDPSocketLibevent::InternalConnect(const IPEndPoint& address) {
221 DCHECK(!is_connected()); 245 DCHECK(!is_connected());
222 DCHECK(!remote_address_.get()); 246 DCHECK(!remote_address_.get());
223 int rv = CreateSocket(address); 247 int rv = CreateSocket(address);
224 if (rv < 0) 248 if (rv < 0)
225 return rv; 249 return rv;
226 250
227 if (bind_type_ == DatagramSocket::RANDOM_BIND) 251 if (bind_type_ == DatagramSocket::RANDOM_BIND)
228 rv = RandomBind(address); 252 rv = RandomBind(address);
229 // else connect() does the DatagramSocket::DEFAULT_BIND 253 // else connect() does the DatagramSocket::DEFAULT_BIND
230 254
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 if (result != ERR_IO_PENDING) { 306 if (result != ERR_IO_PENDING) {
283 read_buf_ = NULL; 307 read_buf_ = NULL;
284 read_buf_len_ = 0; 308 read_buf_len_ = 0;
285 recv_from_address_ = NULL; 309 recv_from_address_ = NULL;
286 bool ok = read_socket_watcher_.StopWatchingFileDescriptor(); 310 bool ok = read_socket_watcher_.StopWatchingFileDescriptor();
287 DCHECK(ok); 311 DCHECK(ok);
288 DoReadCallback(result); 312 DoReadCallback(result);
289 } 313 }
290 } 314 }
291 315
316 void UDPSocketLibevent::ProcessSuccessfulRead(int num_bytes,
317 const char* bytes,
318 const IPEndPoint* address) const {
319 base::StatsCounter read_bytes("udp.read_bytes");
320 read_bytes.Add(num_bytes);
321
322 net_log_.AddEvent(
323 NetLog::TYPE_UDP_BYTES_RECEIVED,
324 make_scoped_refptr(
325 new UDPDataTransferNetLogParam(num_bytes, bytes,
326 net_log_.IsLoggingBytes(),
327 address)));
328 }
329
292 int UDPSocketLibevent::CreateSocket(const IPEndPoint& address) { 330 int UDPSocketLibevent::CreateSocket(const IPEndPoint& address) {
293 socket_ = socket(address.GetFamily(), SOCK_DGRAM, 0); 331 socket_ = socket(address.GetFamily(), SOCK_DGRAM, 0);
294 if (socket_ == kInvalidSocket) 332 if (socket_ == kInvalidSocket)
295 return MapSystemError(errno); 333 return MapSystemError(errno);
296 if (SetNonBlocking(socket_)) { 334 if (SetNonBlocking(socket_)) {
297 const int err = MapSystemError(errno); 335 const int err = MapSystemError(errno);
298 Close(); 336 Close();
299 return err; 337 return err;
300 } 338 }
301 return OK; 339 return OK;
302 } 340 }
303 341
304 void UDPSocketLibevent::DidCompleteWrite() { 342 void UDPSocketLibevent::DidCompleteWrite() {
305 int result = InternalSendTo(write_buf_, write_buf_len_, 343 int result = InternalSendTo(write_buf_, write_buf_len_,
306 send_to_address_.get()); 344 send_to_address_.get());
307 if (result >= 0) { 345 if (result >= 0) {
308 base::StatsCounter write_bytes("udp.write_bytes"); 346 ProcessSuccessfulWrite(result, write_buf_->data(), send_to_address_.get());
309 write_bytes.Add(result);
310 } else { 347 } else {
311 result = MapSystemError(errno); 348 result = MapSystemError(errno);
349 if (result != ERR_IO_PENDING)
350 net_log_.AddEventWithNetErrorCode(NetLog::TYPE_UDP_SEND_ERROR, result);
312 } 351 }
313 352
314 if (result != ERR_IO_PENDING) { 353 if (result != ERR_IO_PENDING) {
315 write_buf_ = NULL; 354 write_buf_ = NULL;
316 write_buf_len_ = 0; 355 write_buf_len_ = 0;
317 send_to_address_.reset(); 356 send_to_address_.reset();
318 write_socket_watcher_.StopWatchingFileDescriptor(); 357 write_socket_watcher_.StopWatchingFileDescriptor();
319 DoWriteCallback(result); 358 DoWriteCallback(result);
320 } 359 }
321 } 360 }
322 361
362 void UDPSocketLibevent::ProcessSuccessfulWrite(
363 int num_bytes,
364 const char* bytes,
365 const IPEndPoint* address) const {
366 base::StatsCounter write_bytes("udp.write_bytes");
367 write_bytes.Add(num_bytes);
368 net_log_.AddEvent(
369 NetLog::TYPE_UDP_BYTES_SENT,
370 make_scoped_refptr(
371 new UDPDataTransferNetLogParam(num_bytes, bytes,
372 net_log_.IsLoggingBytes(),
373 address)));
374 }
375
323 int UDPSocketLibevent::InternalRecvFrom(IOBuffer* buf, int buf_len, 376 int UDPSocketLibevent::InternalRecvFrom(IOBuffer* buf, int buf_len,
324 IPEndPoint* address) { 377 IPEndPoint* address) {
325 int bytes_transferred; 378 int bytes_transferred;
326 int flags = 0; 379 int flags = 0;
327 380
328 struct sockaddr_storage addr_storage; 381 struct sockaddr_storage addr_storage;
329 socklen_t addr_len = sizeof(addr_storage); 382 socklen_t addr_len = sizeof(addr_storage);
330 struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage); 383 struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage);
331 384
332 bytes_transferred = 385 bytes_transferred =
333 HANDLE_EINTR(recvfrom(socket_, 386 HANDLE_EINTR(recvfrom(socket_,
334 buf->data(), 387 buf->data(),
335 buf_len, 388 buf_len,
336 flags, 389 flags,
337 addr, 390 addr,
338 &addr_len)); 391 &addr_len));
339 int result; 392 int result;
340 if (bytes_transferred >= 0) { 393 if (bytes_transferred >= 0) {
341 result = bytes_transferred; 394 result = bytes_transferred;
342 base::StatsCounter read_bytes("udp.read_bytes"); 395 ProcessSuccessfulRead(bytes_transferred, buf->data(), address);
343 read_bytes.Add(bytes_transferred);
344 if (address) { 396 if (address) {
345 if (!address->FromSockAddr(addr, addr_len)) 397 if (!address->FromSockAddr(addr, addr_len))
346 result = ERR_FAILED; 398 result = ERR_FAILED;
347 } 399 }
348 } else { 400 } else {
349 result = MapSystemError(errno); 401 result = MapSystemError(errno);
350 } 402 }
351 return result; 403 return result;
352 } 404 }
353 405
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
391 443
392 for (int i = 0; i < kBindRetries; ++i) { 444 for (int i = 0; i < kBindRetries; ++i) {
393 int rv = DoBind(IPEndPoint(ip, rand_int_cb_.Run(kPortStart, kPortEnd))); 445 int rv = DoBind(IPEndPoint(ip, rand_int_cb_.Run(kPortStart, kPortEnd)));
394 if (rv == OK || rv != ERR_ADDRESS_IN_USE) 446 if (rv == OK || rv != ERR_ADDRESS_IN_USE)
395 return rv; 447 return rv;
396 } 448 }
397 return DoBind(IPEndPoint(ip, 0)); 449 return DoBind(IPEndPoint(ip, 0));
398 } 450 }
399 451
400 } // namespace net 452 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698