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

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

Issue 266243004: Clang format slam. Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 7 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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 <net/if.h> 10 #include <net/if.h>
11 #include <netinet/in.h> 11 #include <netinet/in.h>
12 #include <sys/ioctl.h> 12 #include <sys/ioctl.h>
13 #include <sys/socket.h> 13 #include <sys/socket.h>
14 14
15 #include "base/callback.h" 15 #include "base/callback.h"
16 #include "base/logging.h" 16 #include "base/logging.h"
17 #include "base/message_loop/message_loop.h" 17 #include "base/message_loop/message_loop.h"
18 #include "base/metrics/sparse_histogram.h" 18 #include "base/metrics/sparse_histogram.h"
19 #include "base/metrics/stats_counters.h" 19 #include "base/metrics/stats_counters.h"
20 #include "base/posix/eintr_wrapper.h" 20 #include "base/posix/eintr_wrapper.h"
21 #include "base/rand_util.h" 21 #include "base/rand_util.h"
22 #include "net/base/io_buffer.h" 22 #include "net/base/io_buffer.h"
23 #include "net/base/ip_endpoint.h" 23 #include "net/base/ip_endpoint.h"
24 #include "net/base/net_errors.h" 24 #include "net/base/net_errors.h"
25 #include "net/base/net_log.h" 25 #include "net/base/net_log.h"
26 #include "net/base/net_util.h" 26 #include "net/base/net_util.h"
27 #include "net/socket/socket_descriptor.h" 27 #include "net/socket/socket_descriptor.h"
28 #include "net/udp/udp_net_log_parameters.h" 28 #include "net/udp/udp_net_log_parameters.h"
29 29
30
31 namespace net { 30 namespace net {
32 31
33 namespace { 32 namespace {
34 33
35 const int kBindRetries = 10; 34 const int kBindRetries = 10;
36 const int kPortStart = 1024; 35 const int kPortStart = 1024;
37 const int kPortEnd = 65535; 36 const int kPortEnd = 65535;
38 37
39 #if defined(OS_MACOSX) 38 #if defined(OS_MACOSX)
40 39
41 // Returns IPv4 address in network order. 40 // Returns IPv4 address in network order.
42 int GetIPv4AddressFromIndex(int socket, uint32 index, uint32* address){ 41 int GetIPv4AddressFromIndex(int socket, uint32 index, uint32* address) {
43 if (!index) { 42 if (!index) {
44 *address = htonl(INADDR_ANY); 43 *address = htonl(INADDR_ANY);
45 return OK; 44 return OK;
46 } 45 }
47 ifreq ifr; 46 ifreq ifr;
48 ifr.ifr_addr.sa_family = AF_INET; 47 ifr.ifr_addr.sa_family = AF_INET;
49 if (!if_indextoname(index, ifr.ifr_name)) 48 if (!if_indextoname(index, ifr.ifr_name))
50 return MapSystemError(errno); 49 return MapSystemError(errno);
51 int rv = ioctl(socket, SIOCGIFADDR, &ifr); 50 int rv = ioctl(socket, SIOCGIFADDR, &ifr);
52 if (rv == -1) 51 if (rv == -1)
53 return MapSystemError(errno); 52 return MapSystemError(errno);
54 *address = reinterpret_cast<sockaddr_in*>(&ifr.ifr_addr)->sin_addr.s_addr; 53 *address = reinterpret_cast<sockaddr_in*>(&ifr.ifr_addr)->sin_addr.s_addr;
55 return OK; 54 return OK;
56 } 55 }
57 56
58 #endif // OS_MACOSX 57 #endif // OS_MACOSX
59 58
60 } // namespace 59 } // namespace
61 60
62 UDPSocketLibevent::UDPSocketLibevent( 61 UDPSocketLibevent::UDPSocketLibevent(DatagramSocket::BindType bind_type,
63 DatagramSocket::BindType bind_type, 62 const RandIntCallback& rand_int_cb,
64 const RandIntCallback& rand_int_cb, 63 net::NetLog* net_log,
65 net::NetLog* net_log, 64 const net::NetLog::Source& source)
66 const net::NetLog::Source& source) 65 : socket_(kInvalidSocket),
67 : socket_(kInvalidSocket), 66 addr_family_(0),
68 addr_family_(0), 67 socket_options_(SOCKET_OPTION_MULTICAST_LOOP),
69 socket_options_(SOCKET_OPTION_MULTICAST_LOOP), 68 multicast_interface_(0),
70 multicast_interface_(0), 69 multicast_time_to_live_(1),
71 multicast_time_to_live_(1), 70 bind_type_(bind_type),
72 bind_type_(bind_type), 71 rand_int_cb_(rand_int_cb),
73 rand_int_cb_(rand_int_cb), 72 read_watcher_(this),
74 read_watcher_(this), 73 write_watcher_(this),
75 write_watcher_(this), 74 read_buf_len_(0),
76 read_buf_len_(0), 75 recv_from_address_(NULL),
77 recv_from_address_(NULL), 76 write_buf_len_(0),
78 write_buf_len_(0), 77 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_UDP_SOCKET)) {
79 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_UDP_SOCKET)) {
80 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, 78 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE,
81 source.ToEventParametersCallback()); 79 source.ToEventParametersCallback());
82 if (bind_type == DatagramSocket::RANDOM_BIND) 80 if (bind_type == DatagramSocket::RANDOM_BIND)
83 DCHECK(!rand_int_cb.is_null()); 81 DCHECK(!rand_int_cb.is_null());
84 } 82 }
85 83
86 UDPSocketLibevent::~UDPSocketLibevent() { 84 UDPSocketLibevent::~UDPSocketLibevent() {
87 Close(); 85 Close();
88 net_log_.EndEvent(NetLog::TYPE_SOCKET_ALIVE); 86 net_log_.EndEvent(NetLog::TYPE_SOCKET_ALIVE);
89 } 87 }
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
173 DCHECK(read_callback_.is_null()); 171 DCHECK(read_callback_.is_null());
174 DCHECK(!recv_from_address_); 172 DCHECK(!recv_from_address_);
175 DCHECK(!callback.is_null()); // Synchronous operation not supported 173 DCHECK(!callback.is_null()); // Synchronous operation not supported
176 DCHECK_GT(buf_len, 0); 174 DCHECK_GT(buf_len, 0);
177 175
178 int nread = InternalRecvFrom(buf, buf_len, address); 176 int nread = InternalRecvFrom(buf, buf_len, address);
179 if (nread != ERR_IO_PENDING) 177 if (nread != ERR_IO_PENDING)
180 return nread; 178 return nread;
181 179
182 if (!base::MessageLoopForIO::current()->WatchFileDescriptor( 180 if (!base::MessageLoopForIO::current()->WatchFileDescriptor(
183 socket_, true, base::MessageLoopForIO::WATCH_READ, 181 socket_,
184 &read_socket_watcher_, &read_watcher_)) { 182 true,
183 base::MessageLoopForIO::WATCH_READ,
184 &read_socket_watcher_,
185 &read_watcher_)) {
185 PLOG(ERROR) << "WatchFileDescriptor failed on read"; 186 PLOG(ERROR) << "WatchFileDescriptor failed on read";
186 int result = MapSystemError(errno); 187 int result = MapSystemError(errno);
187 LogRead(result, NULL, 0, NULL); 188 LogRead(result, NULL, 0, NULL);
188 return result; 189 return result;
189 } 190 }
190 191
191 read_buf_ = buf; 192 read_buf_ = buf;
192 read_buf_len_ = buf_len; 193 read_buf_len_ = buf_len;
193 recv_from_address_ = address; 194 recv_from_address_ = address;
194 read_callback_ = callback; 195 read_callback_ = callback;
(...skipping 21 matching lines...) Expand all
216 DCHECK_NE(kInvalidSocket, socket_); 217 DCHECK_NE(kInvalidSocket, socket_);
217 DCHECK(write_callback_.is_null()); 218 DCHECK(write_callback_.is_null());
218 DCHECK(!callback.is_null()); // Synchronous operation not supported 219 DCHECK(!callback.is_null()); // Synchronous operation not supported
219 DCHECK_GT(buf_len, 0); 220 DCHECK_GT(buf_len, 0);
220 221
221 int result = InternalSendTo(buf, buf_len, address); 222 int result = InternalSendTo(buf, buf_len, address);
222 if (result != ERR_IO_PENDING) 223 if (result != ERR_IO_PENDING)
223 return result; 224 return result;
224 225
225 if (!base::MessageLoopForIO::current()->WatchFileDescriptor( 226 if (!base::MessageLoopForIO::current()->WatchFileDescriptor(
226 socket_, true, base::MessageLoopForIO::WATCH_WRITE, 227 socket_,
227 &write_socket_watcher_, &write_watcher_)) { 228 true,
229 base::MessageLoopForIO::WATCH_WRITE,
230 &write_socket_watcher_,
231 &write_watcher_)) {
228 DVLOG(1) << "WatchFileDescriptor failed on write, errno " << errno; 232 DVLOG(1) << "WatchFileDescriptor failed on write, errno " << errno;
229 int result = MapSystemError(errno); 233 int result = MapSystemError(errno);
230 LogWrite(result, NULL, NULL); 234 LogWrite(result, NULL, NULL);
231 return result; 235 return result;
232 } 236 }
233 237
234 write_buf_ = buf; 238 write_buf_ = buf;
235 write_buf_len_ = buf_len; 239 write_buf_len_ = buf_len;
236 DCHECK(!send_to_address_.get()); 240 DCHECK(!send_to_address_.get());
237 if (address) { 241 if (address) {
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 if (rv < 0) { 314 if (rv < 0) {
311 Close(); 315 Close();
312 return rv; 316 return rv;
313 } 317 }
314 local_address_.reset(); 318 local_address_.reset();
315 return rv; 319 return rv;
316 } 320 }
317 321
318 int UDPSocketLibevent::SetReceiveBufferSize(int32 size) { 322 int UDPSocketLibevent::SetReceiveBufferSize(int32 size) {
319 DCHECK(CalledOnValidThread()); 323 DCHECK(CalledOnValidThread());
320 int rv = setsockopt(socket_, SOL_SOCKET, SO_RCVBUF, 324 int rv = setsockopt(socket_,
321 reinterpret_cast<const char*>(&size), sizeof(size)); 325 SOL_SOCKET,
326 SO_RCVBUF,
327 reinterpret_cast<const char*>(&size),
328 sizeof(size));
322 int last_error = errno; 329 int last_error = errno;
323 DCHECK(!rv) << "Could not set socket receive buffer size: " << last_error; 330 DCHECK(!rv) << "Could not set socket receive buffer size: " << last_error;
324 return rv == 0 ? OK : MapSystemError(last_error); 331 return rv == 0 ? OK : MapSystemError(last_error);
325 } 332 }
326 333
327 int UDPSocketLibevent::SetSendBufferSize(int32 size) { 334 int UDPSocketLibevent::SetSendBufferSize(int32 size) {
328 DCHECK(CalledOnValidThread()); 335 DCHECK(CalledOnValidThread());
329 int rv = setsockopt(socket_, SOL_SOCKET, SO_SNDBUF, 336 int rv = setsockopt(socket_,
330 reinterpret_cast<const char*>(&size), sizeof(size)); 337 SOL_SOCKET,
338 SO_SNDBUF,
339 reinterpret_cast<const char*>(&size),
340 sizeof(size));
331 int last_error = errno; 341 int last_error = errno;
332 DCHECK(!rv) << "Could not set socket send buffer size: " << last_error; 342 DCHECK(!rv) << "Could not set socket send buffer size: " << last_error;
333 return rv == 0 ? OK : MapSystemError(last_error); 343 return rv == 0 ? OK : MapSystemError(last_error);
334 } 344 }
335 345
336 void UDPSocketLibevent::AllowAddressReuse() { 346 void UDPSocketLibevent::AllowAddressReuse() {
337 DCHECK(CalledOnValidThread()); 347 DCHECK(CalledOnValidThread());
338 DCHECK(!is_connected()); 348 DCHECK(!is_connected());
339 349
340 socket_options_ |= SOCKET_OPTION_REUSE_ADDRESS; 350 socket_options_ |= SOCKET_OPTION_REUSE_ADDRESS;
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
398 net_log_.AddEventWithNetErrorCode(NetLog::TYPE_UDP_RECEIVE_ERROR, result); 408 net_log_.AddEventWithNetErrorCode(NetLog::TYPE_UDP_RECEIVE_ERROR, result);
399 return; 409 return;
400 } 410 }
401 411
402 if (net_log_.IsLogging()) { 412 if (net_log_.IsLogging()) {
403 DCHECK(addr_len > 0); 413 DCHECK(addr_len > 0);
404 DCHECK(addr); 414 DCHECK(addr);
405 415
406 IPEndPoint address; 416 IPEndPoint address;
407 bool is_address_valid = address.FromSockAddr(addr, addr_len); 417 bool is_address_valid = address.FromSockAddr(addr, addr_len);
408 net_log_.AddEvent( 418 net_log_.AddEvent(NetLog::TYPE_UDP_BYTES_RECEIVED,
409 NetLog::TYPE_UDP_BYTES_RECEIVED, 419 CreateNetLogUDPDataTranferCallback(
410 CreateNetLogUDPDataTranferCallback( 420 result, bytes, is_address_valid ? &address : NULL));
411 result, bytes,
412 is_address_valid ? &address : NULL));
413 } 421 }
414 422
415 base::StatsCounter read_bytes("udp.read_bytes"); 423 base::StatsCounter read_bytes("udp.read_bytes");
416 read_bytes.Add(result); 424 read_bytes.Add(result);
417 } 425 }
418 426
419 int UDPSocketLibevent::CreateSocket(int addr_family) { 427 int UDPSocketLibevent::CreateSocket(int addr_family) {
420 addr_family_ = addr_family; 428 addr_family_ = addr_family;
421 socket_ = CreatePlatformSocket(addr_family_, SOCK_DGRAM, 0); 429 socket_ = CreatePlatformSocket(addr_family_, SOCK_DGRAM, 0);
422 if (socket_ == kInvalidSocket) 430 if (socket_ == kInvalidSocket)
(...skipping 30 matching lines...) Expand all
453 if (net_log_.IsLogging()) { 461 if (net_log_.IsLogging()) {
454 net_log_.AddEvent( 462 net_log_.AddEvent(
455 NetLog::TYPE_UDP_BYTES_SENT, 463 NetLog::TYPE_UDP_BYTES_SENT,
456 CreateNetLogUDPDataTranferCallback(result, bytes, address)); 464 CreateNetLogUDPDataTranferCallback(result, bytes, address));
457 } 465 }
458 466
459 base::StatsCounter write_bytes("udp.write_bytes"); 467 base::StatsCounter write_bytes("udp.write_bytes");
460 write_bytes.Add(result); 468 write_bytes.Add(result);
461 } 469 }
462 470
463 int UDPSocketLibevent::InternalRecvFrom(IOBuffer* buf, int buf_len, 471 int UDPSocketLibevent::InternalRecvFrom(IOBuffer* buf,
472 int buf_len,
464 IPEndPoint* address) { 473 IPEndPoint* address) {
465 int bytes_transferred; 474 int bytes_transferred;
466 int flags = 0; 475 int flags = 0;
467 476
468 SockaddrStorage storage; 477 SockaddrStorage storage;
469 478
470 bytes_transferred = 479 bytes_transferred = HANDLE_EINTR(recvfrom(
471 HANDLE_EINTR(recvfrom(socket_, 480 socket_, buf->data(), buf_len, flags, storage.addr, &storage.addr_len));
472 buf->data(),
473 buf_len,
474 flags,
475 storage.addr,
476 &storage.addr_len));
477 int result; 481 int result;
478 if (bytes_transferred >= 0) { 482 if (bytes_transferred >= 0) {
479 result = bytes_transferred; 483 result = bytes_transferred;
480 if (address && !address->FromSockAddr(storage.addr, storage.addr_len)) 484 if (address && !address->FromSockAddr(storage.addr, storage.addr_len))
481 result = ERR_ADDRESS_INVALID; 485 result = ERR_ADDRESS_INVALID;
482 } else { 486 } else {
483 result = MapSystemError(errno); 487 result = MapSystemError(errno);
484 } 488 }
485 if (result != ERR_IO_PENDING) 489 if (result != ERR_IO_PENDING)
486 LogRead(result, buf->data(), storage.addr_len, storage.addr); 490 LogRead(result, buf->data(), storage.addr_len, storage.addr);
487 return result; 491 return result;
488 } 492 }
489 493
490 int UDPSocketLibevent::InternalSendTo(IOBuffer* buf, int buf_len, 494 int UDPSocketLibevent::InternalSendTo(IOBuffer* buf,
495 int buf_len,
491 const IPEndPoint* address) { 496 const IPEndPoint* address) {
492 SockaddrStorage storage; 497 SockaddrStorage storage;
493 struct sockaddr* addr = storage.addr; 498 struct sockaddr* addr = storage.addr;
494 if (!address) { 499 if (!address) {
495 addr = NULL; 500 addr = NULL;
496 storage.addr_len = 0; 501 storage.addr_len = 0;
497 } else { 502 } else {
498 if (!address->ToSockAddr(storage.addr, &storage.addr_len)) { 503 if (!address->ToSockAddr(storage.addr, &storage.addr_len)) {
499 int result = ERR_ADDRESS_INVALID; 504 int result = ERR_ADDRESS_INVALID;
500 LogWrite(result, NULL, NULL); 505 LogWrite(result, NULL, NULL);
501 return result; 506 return result;
502 } 507 }
503 } 508 }
504 509
505 int result = HANDLE_EINTR(sendto(socket_, 510 int result = HANDLE_EINTR(
506 buf->data(), 511 sendto(socket_, buf->data(), buf_len, 0, addr, storage.addr_len));
507 buf_len,
508 0,
509 addr,
510 storage.addr_len));
511 if (result < 0) 512 if (result < 0)
512 result = MapSystemError(errno); 513 result = MapSystemError(errno);
513 if (result != ERR_IO_PENDING) 514 if (result != ERR_IO_PENDING)
514 LogWrite(result, buf->data(), address); 515 LogWrite(result, buf->data(), address);
515 return result; 516 return result;
516 } 517 }
517 518
518 int UDPSocketLibevent::SetSocketOptions() { 519 int UDPSocketLibevent::SetSocketOptions() {
519 int true_value = 1; 520 int true_value = 1;
520 if (socket_options_ & SOCKET_OPTION_REUSE_ADDRESS) { 521 if (socket_options_ & SOCKET_OPTION_REUSE_ADDRESS) {
521 int rv = setsockopt(socket_, SOL_SOCKET, SO_REUSEADDR, &true_value, 522 int rv = setsockopt(
522 sizeof(true_value)); 523 socket_, SOL_SOCKET, SO_REUSEADDR, &true_value, sizeof(true_value));
523 if (rv < 0) 524 if (rv < 0)
524 return MapSystemError(errno); 525 return MapSystemError(errno);
525 } 526 }
526 if (socket_options_ & SOCKET_OPTION_BROADCAST) { 527 if (socket_options_ & SOCKET_OPTION_BROADCAST) {
527 int rv; 528 int rv;
528 #if defined(OS_MACOSX) 529 #if defined(OS_MACOSX)
529 // SO_REUSEPORT on OSX permits multiple processes to each receive 530 // SO_REUSEPORT on OSX permits multiple processes to each receive
530 // UDP multicast or broadcast datagrams destined for the bound 531 // UDP multicast or broadcast datagrams destined for the bound
531 // port. 532 // port.
532 rv = setsockopt(socket_, SOL_SOCKET, SO_REUSEPORT, &true_value, 533 rv = setsockopt(
533 sizeof(true_value)); 534 socket_, SOL_SOCKET, SO_REUSEPORT, &true_value, sizeof(true_value));
534 #else 535 #else
535 rv = setsockopt(socket_, SOL_SOCKET, SO_BROADCAST, &true_value, 536 rv = setsockopt(
536 sizeof(true_value)); 537 socket_, SOL_SOCKET, SO_BROADCAST, &true_value, sizeof(true_value));
537 #endif // defined(OS_MACOSX) 538 #endif // defined(OS_MACOSX)
538 if (rv < 0) 539 if (rv < 0)
539 return MapSystemError(errno); 540 return MapSystemError(errno);
540 } 541 }
541 542
542 if (!(socket_options_ & SOCKET_OPTION_MULTICAST_LOOP)) { 543 if (!(socket_options_ & SOCKET_OPTION_MULTICAST_LOOP)) {
543 int rv; 544 int rv;
544 if (addr_family_ == AF_INET) { 545 if (addr_family_ == AF_INET) {
545 u_char loop = 0; 546 u_char loop = 0;
546 rv = setsockopt(socket_, IPPROTO_IP, IP_MULTICAST_LOOP, 547 rv = setsockopt(
547 &loop, sizeof(loop)); 548 socket_, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop));
548 } else { 549 } else {
549 u_int loop = 0; 550 u_int loop = 0;
550 rv = setsockopt(socket_, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, 551 rv = setsockopt(
551 &loop, sizeof(loop)); 552 socket_, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &loop, sizeof(loop));
552 } 553 }
553 if (rv < 0) 554 if (rv < 0)
554 return MapSystemError(errno); 555 return MapSystemError(errno);
555 } 556 }
556 if (multicast_time_to_live_ != IP_DEFAULT_MULTICAST_TTL) { 557 if (multicast_time_to_live_ != IP_DEFAULT_MULTICAST_TTL) {
557 int rv; 558 int rv;
558 if (addr_family_ == AF_INET) { 559 if (addr_family_ == AF_INET) {
559 u_char ttl = multicast_time_to_live_; 560 u_char ttl = multicast_time_to_live_;
560 rv = setsockopt(socket_, IPPROTO_IP, IP_MULTICAST_TTL, 561 rv = setsockopt(socket_, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl));
561 &ttl, sizeof(ttl));
562 } else { 562 } else {
563 // Signed integer. -1 to use route default. 563 // Signed integer. -1 to use route default.
564 int ttl = multicast_time_to_live_; 564 int ttl = multicast_time_to_live_;
565 rv = setsockopt(socket_, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, 565 rv = setsockopt(
566 &ttl, sizeof(ttl)); 566 socket_, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &ttl, sizeof(ttl));
567 } 567 }
568 if (rv < 0) 568 if (rv < 0)
569 return MapSystemError(errno); 569 return MapSystemError(errno);
570 } 570 }
571 if (multicast_interface_ != 0) { 571 if (multicast_interface_ != 0) {
572 switch (addr_family_) { 572 switch (addr_family_) {
573 case AF_INET: { 573 case AF_INET: {
574 #if !defined(OS_MACOSX) 574 #if !defined(OS_MACOSX)
575 ip_mreqn mreq; 575 ip_mreqn mreq;
576 mreq.imr_ifindex = multicast_interface_; 576 mreq.imr_ifindex = multicast_interface_;
577 mreq.imr_address.s_addr = htonl(INADDR_ANY); 577 mreq.imr_address.s_addr = htonl(INADDR_ANY);
578 #else 578 #else
579 ip_mreq mreq; 579 ip_mreq mreq;
580 int error = GetIPv4AddressFromIndex(socket_, multicast_interface_, 580 int error = GetIPv4AddressFromIndex(
581 &mreq.imr_interface.s_addr); 581 socket_, multicast_interface_, &mreq.imr_interface.s_addr);
582 if (error != OK) 582 if (error != OK)
583 return error; 583 return error;
584 #endif 584 #endif
585 int rv = setsockopt(socket_, IPPROTO_IP, IP_MULTICAST_IF, 585 int rv = setsockopt(socket_,
586 reinterpret_cast<const char*>(&mreq), sizeof(mreq)); 586 IPPROTO_IP,
587 IP_MULTICAST_IF,
588 reinterpret_cast<const char*>(&mreq),
589 sizeof(mreq));
587 if (rv) 590 if (rv)
588 return MapSystemError(errno); 591 return MapSystemError(errno);
589 break; 592 break;
590 } 593 }
591 case AF_INET6: { 594 case AF_INET6: {
592 uint32 interface_index = multicast_interface_; 595 uint32 interface_index = multicast_interface_;
593 int rv = setsockopt(socket_, IPPROTO_IPV6, IPV6_MULTICAST_IF, 596 int rv = setsockopt(socket_,
597 IPPROTO_IPV6,
598 IPV6_MULTICAST_IF,
594 reinterpret_cast<const char*>(&interface_index), 599 reinterpret_cast<const char*>(&interface_index),
595 sizeof(interface_index)); 600 sizeof(interface_index));
596 if (rv) 601 if (rv)
597 return MapSystemError(errno); 602 return MapSystemError(errno);
598 break; 603 break;
599 } 604 }
600 default: 605 default:
601 NOTREACHED() << "Invalid address family"; 606 NOTREACHED() << "Invalid address family";
602 return ERR_ADDRESS_INVALID; 607 return ERR_ADDRESS_INVALID;
603 } 608 }
(...skipping 17 matching lines...) Expand all
621 if (last_error == EADDRNOTAVAIL) 626 if (last_error == EADDRNOTAVAIL)
622 return ERR_ADDRESS_IN_USE; 627 return ERR_ADDRESS_IN_USE;
623 #endif 628 #endif
624 return MapSystemError(last_error); 629 return MapSystemError(last_error);
625 } 630 }
626 631
627 int UDPSocketLibevent::RandomBind(const IPAddressNumber& address) { 632 int UDPSocketLibevent::RandomBind(const IPAddressNumber& address) {
628 DCHECK(bind_type_ == DatagramSocket::RANDOM_BIND && !rand_int_cb_.is_null()); 633 DCHECK(bind_type_ == DatagramSocket::RANDOM_BIND && !rand_int_cb_.is_null());
629 634
630 for (int i = 0; i < kBindRetries; ++i) { 635 for (int i = 0; i < kBindRetries; ++i) {
631 int rv = DoBind(IPEndPoint(address, 636 int rv =
632 rand_int_cb_.Run(kPortStart, kPortEnd))); 637 DoBind(IPEndPoint(address, rand_int_cb_.Run(kPortStart, kPortEnd)));
633 if (rv == OK || rv != ERR_ADDRESS_IN_USE) 638 if (rv == OK || rv != ERR_ADDRESS_IN_USE)
634 return rv; 639 return rv;
635 } 640 }
636 return DoBind(IPEndPoint(address, 0)); 641 return DoBind(IPEndPoint(address, 0));
637 } 642 }
638 643
639 int UDPSocketLibevent::JoinGroup(const IPAddressNumber& group_address) const { 644 int UDPSocketLibevent::JoinGroup(const IPAddressNumber& group_address) const {
640 DCHECK(CalledOnValidThread()); 645 DCHECK(CalledOnValidThread());
641 if (!is_connected()) 646 if (!is_connected())
642 return ERR_SOCKET_NOT_CONNECTED; 647 return ERR_SOCKET_NOT_CONNECTED;
643 648
644 switch (group_address.size()) { 649 switch (group_address.size()) {
645 case kIPv4AddressSize: { 650 case kIPv4AddressSize: {
646 if (addr_family_ != AF_INET) 651 if (addr_family_ != AF_INET)
647 return ERR_ADDRESS_INVALID; 652 return ERR_ADDRESS_INVALID;
648 653
649 #if !defined(OS_MACOSX) 654 #if !defined(OS_MACOSX)
650 ip_mreqn mreq; 655 ip_mreqn mreq;
651 mreq.imr_ifindex = multicast_interface_; 656 mreq.imr_ifindex = multicast_interface_;
652 mreq.imr_address.s_addr = htonl(INADDR_ANY); 657 mreq.imr_address.s_addr = htonl(INADDR_ANY);
653 #else 658 #else
654 ip_mreq mreq; 659 ip_mreq mreq;
655 int error = GetIPv4AddressFromIndex(socket_, multicast_interface_, 660 int error = GetIPv4AddressFromIndex(
656 &mreq.imr_interface.s_addr); 661 socket_, multicast_interface_, &mreq.imr_interface.s_addr);
657 if (error != OK) 662 if (error != OK)
658 return error; 663 return error;
659 #endif 664 #endif
660 memcpy(&mreq.imr_multiaddr, &group_address[0], kIPv4AddressSize); 665 memcpy(&mreq.imr_multiaddr, &group_address[0], kIPv4AddressSize);
661 int rv = setsockopt(socket_, IPPROTO_IP, IP_ADD_MEMBERSHIP, 666 int rv = setsockopt(
662 &mreq, sizeof(mreq)); 667 socket_, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
663 if (rv < 0) 668 if (rv < 0)
664 return MapSystemError(errno); 669 return MapSystemError(errno);
665 return OK; 670 return OK;
666 } 671 }
667 case kIPv6AddressSize: { 672 case kIPv6AddressSize: {
668 if (addr_family_ != AF_INET6) 673 if (addr_family_ != AF_INET6)
669 return ERR_ADDRESS_INVALID; 674 return ERR_ADDRESS_INVALID;
670 ipv6_mreq mreq; 675 ipv6_mreq mreq;
671 mreq.ipv6mr_interface = multicast_interface_; 676 mreq.ipv6mr_interface = multicast_interface_;
672 memcpy(&mreq.ipv6mr_multiaddr, &group_address[0], kIPv6AddressSize); 677 memcpy(&mreq.ipv6mr_multiaddr, &group_address[0], kIPv6AddressSize);
673 int rv = setsockopt(socket_, IPPROTO_IPV6, IPV6_JOIN_GROUP, 678 int rv = setsockopt(
674 &mreq, sizeof(mreq)); 679 socket_, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq));
675 if (rv < 0) 680 if (rv < 0)
676 return MapSystemError(errno); 681 return MapSystemError(errno);
677 return OK; 682 return OK;
678 } 683 }
679 default: 684 default:
680 NOTREACHED() << "Invalid address family"; 685 NOTREACHED() << "Invalid address family";
681 return ERR_ADDRESS_INVALID; 686 return ERR_ADDRESS_INVALID;
682 } 687 }
683 } 688 }
684 689
685 int UDPSocketLibevent::LeaveGroup(const IPAddressNumber& group_address) const { 690 int UDPSocketLibevent::LeaveGroup(const IPAddressNumber& group_address) const {
686 DCHECK(CalledOnValidThread()); 691 DCHECK(CalledOnValidThread());
687 692
688 if (!is_connected()) 693 if (!is_connected())
689 return ERR_SOCKET_NOT_CONNECTED; 694 return ERR_SOCKET_NOT_CONNECTED;
690 695
691 switch (group_address.size()) { 696 switch (group_address.size()) {
692 case kIPv4AddressSize: { 697 case kIPv4AddressSize: {
693 if (addr_family_ != AF_INET) 698 if (addr_family_ != AF_INET)
694 return ERR_ADDRESS_INVALID; 699 return ERR_ADDRESS_INVALID;
695 ip_mreq mreq; 700 ip_mreq mreq;
696 mreq.imr_interface.s_addr = INADDR_ANY; 701 mreq.imr_interface.s_addr = INADDR_ANY;
697 memcpy(&mreq.imr_multiaddr, &group_address[0], kIPv4AddressSize); 702 memcpy(&mreq.imr_multiaddr, &group_address[0], kIPv4AddressSize);
698 int rv = setsockopt(socket_, IPPROTO_IP, IP_DROP_MEMBERSHIP, 703 int rv = setsockopt(
699 &mreq, sizeof(mreq)); 704 socket_, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq));
700 if (rv < 0) 705 if (rv < 0)
701 return MapSystemError(errno); 706 return MapSystemError(errno);
702 return OK; 707 return OK;
703 } 708 }
704 case kIPv6AddressSize: { 709 case kIPv6AddressSize: {
705 if (addr_family_ != AF_INET6) 710 if (addr_family_ != AF_INET6)
706 return ERR_ADDRESS_INVALID; 711 return ERR_ADDRESS_INVALID;
707 ipv6_mreq mreq; 712 ipv6_mreq mreq;
708 mreq.ipv6mr_interface = 0; // 0 indicates default multicast interface. 713 mreq.ipv6mr_interface = 0; // 0 indicates default multicast interface.
709 memcpy(&mreq.ipv6mr_multiaddr, &group_address[0], kIPv6AddressSize); 714 memcpy(&mreq.ipv6mr_multiaddr, &group_address[0], kIPv6AddressSize);
710 int rv = setsockopt(socket_, IPPROTO_IPV6, IPV6_LEAVE_GROUP, 715 int rv = setsockopt(
711 &mreq, sizeof(mreq)); 716 socket_, IPPROTO_IPV6, IPV6_LEAVE_GROUP, &mreq, sizeof(mreq));
712 if (rv < 0) 717 if (rv < 0)
713 return MapSystemError(errno); 718 return MapSystemError(errno);
714 return OK; 719 return OK;
715 } 720 }
716 default: 721 default:
717 NOTREACHED() << "Invalid address family"; 722 NOTREACHED() << "Invalid address family";
718 return ERR_ADDRESS_INVALID; 723 return ERR_ADDRESS_INVALID;
719 } 724 }
720 } 725 }
721 726
(...skipping 28 matching lines...) Expand all
750 return OK; 755 return OK;
751 } 756 }
752 757
753 int UDPSocketLibevent::SetDiffServCodePoint(DiffServCodePoint dscp) { 758 int UDPSocketLibevent::SetDiffServCodePoint(DiffServCodePoint dscp) {
754 if (dscp == DSCP_NO_CHANGE) { 759 if (dscp == DSCP_NO_CHANGE) {
755 return OK; 760 return OK;
756 } 761 }
757 int rv; 762 int rv;
758 int dscp_and_ecn = dscp << 2; 763 int dscp_and_ecn = dscp << 2;
759 if (addr_family_ == AF_INET) { 764 if (addr_family_ == AF_INET) {
760 rv = setsockopt(socket_, IPPROTO_IP, IP_TOS, 765 rv = setsockopt(
761 &dscp_and_ecn, sizeof(dscp_and_ecn)); 766 socket_, IPPROTO_IP, IP_TOS, &dscp_and_ecn, sizeof(dscp_and_ecn));
762 } else { 767 } else {
763 rv = setsockopt(socket_, IPPROTO_IPV6, IPV6_TCLASS, 768 rv = setsockopt(socket_,
764 &dscp_and_ecn, sizeof(dscp_and_ecn)); 769 IPPROTO_IPV6,
770 IPV6_TCLASS,
771 &dscp_and_ecn,
772 sizeof(dscp_and_ecn));
765 } 773 }
766 if (rv < 0) 774 if (rv < 0)
767 return MapSystemError(errno); 775 return MapSystemError(errno);
768 776
769 return OK; 777 return OK;
770 } 778 }
771 779
772 void UDPSocketLibevent::DetachFromThread() { 780 void UDPSocketLibevent::DetachFromThread() {
773 base::NonThreadSafe::DetachFromThread(); 781 base::NonThreadSafe::DetachFromThread();
774 } 782 }
775 783
776 } // namespace net 784 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698