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

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: Fix linux yet again 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 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
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)
155 return nread; 156 return nread;
156 157
157 if (!MessageLoopForIO::current()->WatchFileDescriptor( 158 if (!MessageLoopForIO::current()->WatchFileDescriptor(
158 socket_, true, MessageLoopForIO::WATCH_READ, 159 socket_, true, MessageLoopForIO::WATCH_READ,
159 &read_socket_watcher_, &read_watcher_)) { 160 &read_socket_watcher_, &read_watcher_)) {
160 PLOG(ERROR) << "WatchFileDescriptor failed on read"; 161 PLOG(ERROR) << "WatchFileDescriptor failed on read";
161 return MapSystemError(errno); 162 return LogRead(MapSystemError(errno), NULL, 0, NULL, NULL);
162 } 163 }
163 164
164 read_buf_ = buf; 165 read_buf_ = buf;
165 read_buf_len_ = buf_len; 166 read_buf_len_ = buf_len;
166 recv_from_address_ = address; 167 recv_from_address_ = address;
167 read_callback_ = callback; 168 read_callback_ = callback;
168 return ERR_IO_PENDING; 169 return ERR_IO_PENDING;
169 } 170 }
170 171
171 int UDPSocketLibevent::Write(IOBuffer* buf, 172 int UDPSocketLibevent::Write(IOBuffer* buf,
(...skipping 13 matching lines...) Expand all
185 int buf_len, 186 int buf_len,
186 const IPEndPoint* address, 187 const IPEndPoint* address,
187 OldCompletionCallback* callback) { 188 OldCompletionCallback* callback) {
188 DCHECK(CalledOnValidThread()); 189 DCHECK(CalledOnValidThread());
189 DCHECK_NE(kInvalidSocket, socket_); 190 DCHECK_NE(kInvalidSocket, socket_);
190 DCHECK(!write_callback_); 191 DCHECK(!write_callback_);
191 DCHECK(callback); // Synchronous operation not supported 192 DCHECK(callback); // Synchronous operation not supported
192 DCHECK_GT(buf_len, 0); 193 DCHECK_GT(buf_len, 0);
193 194
194 int nwrite = InternalSendTo(buf, buf_len, address); 195 int nwrite = InternalSendTo(buf, buf_len, address);
195 if (nwrite >= 0) { 196 if (nwrite >= 0)
196 base::StatsCounter write_bytes("udp.write_bytes"); 197 return LogWrite(nwrite, buf->data(), address);
Sergey Ulanov 2011/10/17 17:48:13 Can we move this to InternalSendTo() so that it is
mmenke 2011/10/17 19:41:38 Done.
197 write_bytes.Add(nwrite);
198 return nwrite;
199 }
200 if (errno != EAGAIN && errno != EWOULDBLOCK) 198 if (errno != EAGAIN && errno != EWOULDBLOCK)
201 return MapSystemError(errno); 199 return LogWrite(MapSystemError(errno), NULL, NULL);
202 200
203 if (!MessageLoopForIO::current()->WatchFileDescriptor( 201 if (!MessageLoopForIO::current()->WatchFileDescriptor(
204 socket_, true, MessageLoopForIO::WATCH_WRITE, 202 socket_, true, MessageLoopForIO::WATCH_WRITE,
205 &write_socket_watcher_, &write_watcher_)) { 203 &write_socket_watcher_, &write_watcher_)) {
206 DVLOG(1) << "WatchFileDescriptor failed on write, errno " << errno; 204 DVLOG(1) << "WatchFileDescriptor failed on write, errno " << errno;
207 return MapSystemError(errno); 205 return LogWrite(MapSystemError(errno), NULL, NULL);
208 } 206 }
209 207
210 write_buf_ = buf; 208 write_buf_ = buf;
211 write_buf_len_ = buf_len; 209 write_buf_len_ = buf_len;
212 DCHECK(!send_to_address_.get()); 210 DCHECK(!send_to_address_.get());
213 if (address) { 211 if (address) {
214 send_to_address_.reset(new IPEndPoint(*address)); 212 send_to_address_.reset(new IPEndPoint(*address));
215 } 213 }
216 write_callback_ = callback; 214 write_callback_ = callback;
217 return ERR_IO_PENDING; 215 return ERR_IO_PENDING;
218 } 216 }
219 217
220 int UDPSocketLibevent::Connect(const IPEndPoint& address) { 218 int UDPSocketLibevent::Connect(const IPEndPoint& address) {
219 net_log_.BeginEvent(
220 NetLog::TYPE_UDP_CONNECT,
221 make_scoped_refptr(new NetLogStringParameter("address",
222 address.ToString())));
223 int rv = InternalConnect(address);
224 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_UDP_CONNECT, rv);
225 return rv;
226 }
227
228 int UDPSocketLibevent::InternalConnect(const IPEndPoint& address) {
221 DCHECK(!is_connected()); 229 DCHECK(!is_connected());
222 DCHECK(!remote_address_.get()); 230 DCHECK(!remote_address_.get());
223 int rv = CreateSocket(address); 231 int rv = CreateSocket(address);
224 if (rv < 0) 232 if (rv < 0)
225 return rv; 233 return rv;
226 234
227 if (bind_type_ == DatagramSocket::RANDOM_BIND) 235 if (bind_type_ == DatagramSocket::RANDOM_BIND)
228 rv = RandomBind(address); 236 rv = RandomBind(address);
229 // else connect() does the DatagramSocket::DEFAULT_BIND 237 // else connect() does the DatagramSocket::DEFAULT_BIND
230 238
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 if (result != ERR_IO_PENDING) { 290 if (result != ERR_IO_PENDING) {
283 read_buf_ = NULL; 291 read_buf_ = NULL;
284 read_buf_len_ = 0; 292 read_buf_len_ = 0;
285 recv_from_address_ = NULL; 293 recv_from_address_ = NULL;
286 bool ok = read_socket_watcher_.StopWatchingFileDescriptor(); 294 bool ok = read_socket_watcher_.StopWatchingFileDescriptor();
287 DCHECK(ok); 295 DCHECK(ok);
288 DoReadCallback(result); 296 DoReadCallback(result);
289 } 297 }
290 } 298 }
291 299
300 int UDPSocketLibevent::LogRead(int result,
301 const char* bytes,
302 socklen_t addr_len,
303 const sockaddr* addr,
304 IPEndPoint* address) const {
305 DCHECK(result < 0 || addr_len > 0);
306 DCHECK(result < 0 || addr != NULL);
307
308 if (result >= 0 && address) {
309 if (!address->FromSockAddr(addr, addr_len))
Sergey Ulanov 2011/10/17 17:48:13 I think that conversion of the address should stay
mmenke 2011/10/17 19:41:38 Done. If address is NULL and we're logging, I sti
310 result = ERR_FAILED;
311 }
312
313 if (result < 0) {
314 net_log_.AddEventWithNetErrorCode(NetLog::TYPE_UDP_RECEIVE_ERROR, result);
315 return result;
316 }
317
318 if (net_log_.IsLoggingAllEvents()) {
319 // Get address for logging, if |address| is NULL.
320 IPEndPoint address_on_stack;
321 if (!address) {
322 if (address_on_stack.FromSockAddr(addr, addr_len))
323 address = &address_on_stack;
324 }
325 net_log_.AddEvent(
326 NetLog::TYPE_UDP_BYTES_RECEIVED,
327 make_scoped_refptr(
328 new UDPDataTransferNetLogParam(result, bytes,
329 net_log_.IsLoggingBytes(),
330 address)));
331 }
332
333 base::StatsCounter read_bytes("udp.read_bytes");
334 read_bytes.Add(result);
335 return result;
336 }
337
292 int UDPSocketLibevent::CreateSocket(const IPEndPoint& address) { 338 int UDPSocketLibevent::CreateSocket(const IPEndPoint& address) {
293 socket_ = socket(address.GetFamily(), SOCK_DGRAM, 0); 339 socket_ = socket(address.GetFamily(), SOCK_DGRAM, 0);
294 if (socket_ == kInvalidSocket) 340 if (socket_ == kInvalidSocket)
295 return MapSystemError(errno); 341 return MapSystemError(errno);
296 if (SetNonBlocking(socket_)) { 342 if (SetNonBlocking(socket_)) {
297 const int err = MapSystemError(errno); 343 const int err = MapSystemError(errno);
298 Close(); 344 Close();
299 return err; 345 return err;
300 } 346 }
301 return OK; 347 return OK;
302 } 348 }
303 349
304 void UDPSocketLibevent::DidCompleteWrite() { 350 void UDPSocketLibevent::DidCompleteWrite() {
305 int result = InternalSendTo(write_buf_, write_buf_len_, 351 int result = InternalSendTo(write_buf_, write_buf_len_,
306 send_to_address_.get()); 352 send_to_address_.get());
307 if (result >= 0) { 353 if (result < 0)
308 base::StatsCounter write_bytes("udp.write_bytes");
309 write_bytes.Add(result);
310 } else {
311 result = MapSystemError(errno); 354 result = MapSystemError(errno);
312 } 355
356 if (result != ERR_IO_PENDING)
357 result = LogWrite(result, write_buf_->data(), send_to_address_.get());
313 358
314 if (result != ERR_IO_PENDING) { 359 if (result != ERR_IO_PENDING) {
315 write_buf_ = NULL; 360 write_buf_ = NULL;
316 write_buf_len_ = 0; 361 write_buf_len_ = 0;
317 send_to_address_.reset(); 362 send_to_address_.reset();
318 write_socket_watcher_.StopWatchingFileDescriptor(); 363 write_socket_watcher_.StopWatchingFileDescriptor();
319 DoWriteCallback(result); 364 DoWriteCallback(result);
320 } 365 }
321 } 366 }
322 367
368 int UDPSocketLibevent::LogWrite(int result,
369 const char* bytes,
370 const IPEndPoint* address) const {
371 if (result < 0) {
372 net_log_.AddEventWithNetErrorCode(NetLog::TYPE_UDP_SEND_ERROR, result);
373 return result;
374 }
375
376 if (net_log_.IsLoggingAllEvents()) {
377 net_log_.AddEvent(
378 NetLog::TYPE_UDP_BYTES_SENT,
379 make_scoped_refptr(
380 new UDPDataTransferNetLogParam(result, bytes,
381 net_log_.IsLoggingBytes(),
382 address)));
383 }
384
385 base::StatsCounter write_bytes("udp.write_bytes");
386 write_bytes.Add(result);
387 return result;
388 }
389
323 int UDPSocketLibevent::InternalRecvFrom(IOBuffer* buf, int buf_len, 390 int UDPSocketLibevent::InternalRecvFrom(IOBuffer* buf, int buf_len,
324 IPEndPoint* address) { 391 IPEndPoint* address) {
325 int bytes_transferred; 392 int bytes_transferred;
326 int flags = 0; 393 int flags = 0;
327 394
328 struct sockaddr_storage addr_storage; 395 struct sockaddr_storage addr_storage;
329 socklen_t addr_len = sizeof(addr_storage); 396 socklen_t addr_len = sizeof(addr_storage);
330 struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage); 397 struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage);
331 398
332 bytes_transferred = 399 bytes_transferred =
333 HANDLE_EINTR(recvfrom(socket_, 400 HANDLE_EINTR(recvfrom(socket_,
334 buf->data(), 401 buf->data(),
335 buf_len, 402 buf_len,
336 flags, 403 flags,
337 addr, 404 addr,
338 &addr_len)); 405 &addr_len));
339 int result; 406 int result;
340 if (bytes_transferred >= 0) { 407 if (bytes_transferred >= 0) {
341 result = bytes_transferred; 408 result = bytes_transferred;
342 base::StatsCounter read_bytes("udp.read_bytes");
343 read_bytes.Add(bytes_transferred);
344 if (address) {
345 if (!address->FromSockAddr(addr, addr_len))
346 result = ERR_FAILED;
347 }
348 } else { 409 } else {
349 result = MapSystemError(errno); 410 result = MapSystemError(errno);
350 } 411 }
412 if (result != ERR_IO_PENDING)
413 LogRead(result, buf->data(), addr_len, addr, address);
351 return result; 414 return result;
352 } 415 }
353 416
354 int UDPSocketLibevent::InternalSendTo(IOBuffer* buf, int buf_len, 417 int UDPSocketLibevent::InternalSendTo(IOBuffer* buf, int buf_len,
355 const IPEndPoint* address) { 418 const IPEndPoint* address) {
356 struct sockaddr_storage addr_storage; 419 struct sockaddr_storage addr_storage;
357 size_t addr_len = sizeof(addr_storage); 420 size_t addr_len = sizeof(addr_storage);
358 struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage); 421 struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage);
359 422
360 if (!address) { 423 if (!address) {
(...skipping 30 matching lines...) Expand all
391 454
392 for (int i = 0; i < kBindRetries; ++i) { 455 for (int i = 0; i < kBindRetries; ++i) {
393 int rv = DoBind(IPEndPoint(ip, rand_int_cb_.Run(kPortStart, kPortEnd))); 456 int rv = DoBind(IPEndPoint(ip, rand_int_cb_.Run(kPortStart, kPortEnd)));
394 if (rv == OK || rv != ERR_ADDRESS_IN_USE) 457 if (rv == OK || rv != ERR_ADDRESS_IN_USE)
395 return rv; 458 return rv;
396 } 459 }
397 return DoBind(IPEndPoint(ip, 0)); 460 return DoBind(IPEndPoint(ip, 0));
398 } 461 }
399 462
400 } // namespace net 463 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698