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

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: Don't do address conversions on windows when we don't have to. 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) {
Sergey Ulanov 2011/10/14 20:15:47 nit: remove braces here - they are not used in thi
mmenke 2011/10/17 17:35:20 Done.
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,
Sergey Ulanov 2011/10/14 20:15:47 optional nit: This code is duplicated in DidComple
mmenke 2011/10/17 17:35:20 Done. I really like this idea. Results in a lot
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);
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 if (net_log_.IsLoggingAllEvents()) {
323 net_log_.AddEvent(
324 NetLog::TYPE_UDP_BYTES_RECEIVED,
325 make_scoped_refptr(
326 new UDPDataTransferNetLogParam(num_bytes, bytes,
327 net_log_.IsLoggingBytes(),
328 address)));
329 }
330 }
331
292 int UDPSocketLibevent::CreateSocket(const IPEndPoint& address) { 332 int UDPSocketLibevent::CreateSocket(const IPEndPoint& address) {
293 socket_ = socket(address.GetFamily(), SOCK_DGRAM, 0); 333 socket_ = socket(address.GetFamily(), SOCK_DGRAM, 0);
294 if (socket_ == kInvalidSocket) 334 if (socket_ == kInvalidSocket)
295 return MapSystemError(errno); 335 return MapSystemError(errno);
296 if (SetNonBlocking(socket_)) { 336 if (SetNonBlocking(socket_)) {
297 const int err = MapSystemError(errno); 337 const int err = MapSystemError(errno);
298 Close(); 338 Close();
299 return err; 339 return err;
300 } 340 }
301 return OK; 341 return OK;
302 } 342 }
303 343
304 void UDPSocketLibevent::DidCompleteWrite() { 344 void UDPSocketLibevent::DidCompleteWrite() {
305 int result = InternalSendTo(write_buf_, write_buf_len_, 345 int result = InternalSendTo(write_buf_, write_buf_len_,
306 send_to_address_.get()); 346 send_to_address_.get());
307 if (result >= 0) { 347 if (result >= 0) {
308 base::StatsCounter write_bytes("udp.write_bytes"); 348 ProcessSuccessfulWrite(result, write_buf_->data(), send_to_address_.get());
309 write_bytes.Add(result);
310 } else { 349 } else {
311 result = MapSystemError(errno); 350 result = MapSystemError(errno);
351 if (result != ERR_IO_PENDING)
352 net_log_.AddEventWithNetErrorCode(NetLog::TYPE_UDP_SEND_ERROR, result);
312 } 353 }
313 354
314 if (result != ERR_IO_PENDING) { 355 if (result != ERR_IO_PENDING) {
315 write_buf_ = NULL; 356 write_buf_ = NULL;
316 write_buf_len_ = 0; 357 write_buf_len_ = 0;
317 send_to_address_.reset(); 358 send_to_address_.reset();
318 write_socket_watcher_.StopWatchingFileDescriptor(); 359 write_socket_watcher_.StopWatchingFileDescriptor();
319 DoWriteCallback(result); 360 DoWriteCallback(result);
320 } 361 }
321 } 362 }
322 363
364 void UDPSocketLibevent::ProcessSuccessfulWrite(
365 int num_bytes,
366 const char* bytes,
367 const IPEndPoint* address) const {
368 base::StatsCounter write_bytes("udp.write_bytes");
369 write_bytes.Add(num_bytes);
370 if (net_log_.IsLoggingAllEvents()) {
371 net_log_.AddEvent(
372 NetLog::TYPE_UDP_BYTES_SENT,
373 make_scoped_refptr(
374 new UDPDataTransferNetLogParam(num_bytes, bytes,
375 net_log_.IsLoggingBytes(),
376 address)));
377 }
378 }
379
323 int UDPSocketLibevent::InternalRecvFrom(IOBuffer* buf, int buf_len, 380 int UDPSocketLibevent::InternalRecvFrom(IOBuffer* buf, int buf_len,
324 IPEndPoint* address) { 381 IPEndPoint* address) {
325 int bytes_transferred; 382 int bytes_transferred;
326 int flags = 0; 383 int flags = 0;
327 384
328 struct sockaddr_storage addr_storage; 385 struct sockaddr_storage addr_storage;
329 socklen_t addr_len = sizeof(addr_storage); 386 socklen_t addr_len = sizeof(addr_storage);
330 struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage); 387 struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage);
331 388
332 bytes_transferred = 389 bytes_transferred =
333 HANDLE_EINTR(recvfrom(socket_, 390 HANDLE_EINTR(recvfrom(socket_,
334 buf->data(), 391 buf->data(),
335 buf_len, 392 buf_len,
336 flags, 393 flags,
337 addr, 394 addr,
338 &addr_len)); 395 &addr_len));
339 int result; 396 int result;
340 if (bytes_transferred >= 0) { 397 if (bytes_transferred >= 0) {
341 result = bytes_transferred; 398 result = bytes_transferred;
342 base::StatsCounter read_bytes("udp.read_bytes"); 399 ProcessSuccessfulRead(bytes_transferred, buf->data(), address);
343 read_bytes.Add(bytes_transferred);
344 if (address) { 400 if (address) {
345 if (!address->FromSockAddr(addr, addr_len)) 401 if (!address->FromSockAddr(addr, addr_len))
346 result = ERR_FAILED; 402 result = ERR_FAILED;
347 } 403 }
348 } else { 404 } else {
349 result = MapSystemError(errno); 405 result = MapSystemError(errno);
350 } 406 }
351 return result; 407 return result;
352 } 408 }
353 409
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
391 447
392 for (int i = 0; i < kBindRetries; ++i) { 448 for (int i = 0; i < kBindRetries; ++i) {
393 int rv = DoBind(IPEndPoint(ip, rand_int_cb_.Run(kPortStart, kPortEnd))); 449 int rv = DoBind(IPEndPoint(ip, rand_int_cb_.Run(kPortStart, kPortEnd)));
394 if (rv == OK || rv != ERR_ADDRESS_IN_USE) 450 if (rv == OK || rv != ERR_ADDRESS_IN_USE)
395 return rv; 451 return rv;
396 } 452 }
397 return DoBind(IPEndPoint(ip, 0)); 453 return DoBind(IPEndPoint(ip, 0));
398 } 454 }
399 455
400 } // namespace net 456 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698