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

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

Issue 721273002: Remove timing limitation to set Broadcast, ReceiveBuffer, and SendBuffer options from UDPSocket. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 1 month 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
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>
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 if (rv < 0) { 310 if (rv < 0) {
311 Close(); 311 Close();
312 return rv; 312 return rv;
313 } 313 }
314 local_address_.reset(); 314 local_address_.reset();
315 return rv; 315 return rv;
316 } 316 }
317 317
318 int UDPSocketLibevent::SetReceiveBufferSize(int32 size) { 318 int UDPSocketLibevent::SetReceiveBufferSize(int32 size) {
319 DCHECK(CalledOnValidThread()); 319 DCHECK(CalledOnValidThread());
320 int rv = setsockopt(socket_, SOL_SOCKET, SO_RCVBUF, 320 if (is_connected()) {
321 reinterpret_cast<const char*>(&size), sizeof(size)); 321 int result = SetReceiveBufferSizeInternal(size);
322 int last_error = errno; 322 if (result != OK)
323 DCHECK(!rv) << "Could not set socket receive buffer size: " << last_error; 323 return result;
324 return rv == 0 ? OK : MapSystemError(last_error); 324 }
325 socket_options_ |= SOCKET_OPTION_RCVBUF_SIZE;
326 rcvbuf_size_ = size;
327 return OK;
325 } 328 }
326 329
327 int UDPSocketLibevent::SetSendBufferSize(int32 size) { 330 int UDPSocketLibevent::SetSendBufferSize(int32 size) {
328 DCHECK(CalledOnValidThread()); 331 DCHECK(CalledOnValidThread());
329 int rv = setsockopt(socket_, SOL_SOCKET, SO_SNDBUF, 332 if (is_connected()) {
330 reinterpret_cast<const char*>(&size), sizeof(size)); 333 int result = SetSendBufferSizeInternal(size);
331 int last_error = errno; 334 if (result != OK)
332 DCHECK(!rv) << "Could not set socket send buffer size: " << last_error; 335 return result;
333 return rv == 0 ? OK : MapSystemError(last_error); 336 }
337 socket_options_ |= SOCKET_OPTION_SNDBUF_SIZE;
338 sndbuf_size_ = size;
339 return OK;
334 } 340 }
335 341
336 void UDPSocketLibevent::AllowAddressReuse() { 342 void UDPSocketLibevent::AllowAddressReuse() {
337 DCHECK(CalledOnValidThread()); 343 DCHECK(CalledOnValidThread());
338 DCHECK(!is_connected()); 344 DCHECK(!is_connected());
339 345
340 socket_options_ |= SOCKET_OPTION_REUSE_ADDRESS; 346 socket_options_ |= SOCKET_OPTION_REUSE_ADDRESS;
341 } 347 }
342 348
343 void UDPSocketLibevent::AllowBroadcast() { 349 int UDPSocketLibevent::SetBroadcast(bool broadcast) {
344 DCHECK(CalledOnValidThread()); 350 DCHECK(CalledOnValidThread());
345 DCHECK(!is_connected()); 351 if (is_connected()) {
346 352 int result = SetBroadcastInternal(broadcast);
347 socket_options_ |= SOCKET_OPTION_BROADCAST; 353 if (result != OK)
354 return result;
355 }
356 if (broadcast)
357 socket_options_ |= SOCKET_OPTION_BROADCAST;
358 else
359 socket_options_ &= ~SOCKET_OPTION_BROADCAST;
360 return OK;
348 } 361 }
349 362
350 void UDPSocketLibevent::ReadWatcher::OnFileCanReadWithoutBlocking(int) { 363 void UDPSocketLibevent::ReadWatcher::OnFileCanReadWithoutBlocking(int) {
351 if (!socket_->read_callback_.is_null()) 364 if (!socket_->read_callback_.is_null())
352 socket_->DidCompleteRead(); 365 socket_->DidCompleteRead();
353 } 366 }
354 367
355 void UDPSocketLibevent::WriteWatcher::OnFileCanWriteWithoutBlocking(int) { 368 void UDPSocketLibevent::WriteWatcher::OnFileCanWriteWithoutBlocking(int) {
356 if (!socket_->write_callback_.is_null()) 369 if (!socket_->write_callback_.is_null())
357 socket_->DidCompleteWrite(); 370 socket_->DidCompleteWrite();
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
509 addr, 522 addr,
510 storage.addr_len)); 523 storage.addr_len));
511 if (result < 0) 524 if (result < 0)
512 result = MapSystemError(errno); 525 result = MapSystemError(errno);
513 if (result != ERR_IO_PENDING) 526 if (result != ERR_IO_PENDING)
514 LogWrite(result, buf->data(), address); 527 LogWrite(result, buf->data(), address);
515 return result; 528 return result;
516 } 529 }
517 530
518 int UDPSocketLibevent::SetSocketOptions() { 531 int UDPSocketLibevent::SetSocketOptions() {
519 int true_value = 1; 532 DCHECK(CalledOnValidThread());
520 if (socket_options_ & SOCKET_OPTION_REUSE_ADDRESS) { 533 if (socket_options_ & SOCKET_OPTION_REUSE_ADDRESS) {
521 int rv = setsockopt(socket_, SOL_SOCKET, SO_REUSEADDR, &true_value, 534 int rv = AllowAddressReuseInternal();
522 sizeof(true_value)); 535 if (rv != OK)
523 if (rv < 0) 536 return rv;
524 return MapSystemError(errno);
525 } 537 }
526 if (socket_options_ & SOCKET_OPTION_BROADCAST) { 538 if (socket_options_ & SOCKET_OPTION_BROADCAST) {
527 int rv; 539 int rv = SetBroadcastInternal(true);
528 #if defined(OS_MACOSX) 540 if (rv != OK)
529 // SO_REUSEPORT on OSX permits multiple processes to each receive 541 return rv;
530 // UDP multicast or broadcast datagrams destined for the bound
531 // port.
532 rv = setsockopt(socket_, SOL_SOCKET, SO_REUSEPORT, &true_value,
533 sizeof(true_value));
534 #else
535 rv = setsockopt(socket_, SOL_SOCKET, SO_BROADCAST, &true_value,
536 sizeof(true_value));
537 #endif // defined(OS_MACOSX)
538 if (rv < 0)
539 return MapSystemError(errno);
540 } 542 }
541
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(socket_, IPPROTO_IP, IP_MULTICAST_LOOP,
547 &loop, sizeof(loop)); 548 &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(socket_, IPPROTO_IPV6, IPV6_MULTICAST_LOOP,
551 &loop, sizeof(loop)); 552 &loop, sizeof(loop));
552 } 553 }
553 if (rv < 0) 554 if (rv < 0)
554 return MapSystemError(errno); 555 return MapSystemError(errno);
555 } 556 }
557 if (socket_options_ & SOCKET_OPTION_RCVBUF_SIZE) {
558 int rv = SetReceiveBufferSizeInternal(rcvbuf_size_);
559 if (rv != OK)
560 return rv;
561 }
562 if (socket_options_ & SOCKET_OPTION_SNDBUF_SIZE) {
563 int rv = SetSendBufferSizeInternal(sndbuf_size_);
564 if (rv != OK)
565 return rv;
566 }
567
556 if (multicast_time_to_live_ != IP_DEFAULT_MULTICAST_TTL) { 568 if (multicast_time_to_live_ != IP_DEFAULT_MULTICAST_TTL) {
557 int rv; 569 int rv;
558 if (addr_family_ == AF_INET) { 570 if (addr_family_ == AF_INET) {
559 u_char ttl = multicast_time_to_live_; 571 u_char ttl = multicast_time_to_live_;
560 rv = setsockopt(socket_, IPPROTO_IP, IP_MULTICAST_TTL, 572 rv = setsockopt(socket_, IPPROTO_IP, IP_MULTICAST_TTL,
561 &ttl, sizeof(ttl)); 573 &ttl, sizeof(ttl));
562 } else { 574 } else {
563 // Signed integer. -1 to use route default. 575 // Signed integer. -1 to use route default.
564 int ttl = multicast_time_to_live_; 576 int ttl = multicast_time_to_live_;
565 rv = setsockopt(socket_, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, 577 rv = setsockopt(socket_, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
598 break; 610 break;
599 } 611 }
600 default: 612 default:
601 NOTREACHED() << "Invalid address family"; 613 NOTREACHED() << "Invalid address family";
602 return ERR_ADDRESS_INVALID; 614 return ERR_ADDRESS_INVALID;
603 } 615 }
604 } 616 }
605 return OK; 617 return OK;
606 } 618 }
607 619
620 int UDPSocketLibevent::AllowAddressReuseInternal() {
621 DCHECK(CalledOnValidThread());
622 DCHECK(is_connected());
623 int opt_value = 1;
624 int rv = setsockopt(
625 socket_, SOL_SOCKET, SO_REUSEADDR, &opt_value, sizeof(opt_value));
626 return rv == 0 ? OK : MapSystemError(errno);
627 }
628
629 int UDPSocketLibevent::SetBroadcastInternal(bool broadcast) {
630 DCHECK(CalledOnValidThread());
631 DCHECK(is_connected());
632 int opt_value = broadcast ? 1 : 0;
633 #if defined(OS_MACOSX)
634 // SO_REUSEPORT on OSX permits multiple processes to each receive
635 // UDP multicast or broadcast datagrams destined for the bound port.
636 const int kOptName = SO_REUSEPORT;
637 #else
638 const int kOptName = SO_BROADCAST;
639 #endif
640 int rv = setsockopt(
641 socket_, SOL_SOCKET, kOptName, &opt_value, sizeof(opt_value));
642 return rv == 0 ? OK : MapSystemError(errno);
643 }
644
645 int UDPSocketLibevent::SetReceiveBufferSizeInternal(int32 size) {
646 DCHECK(CalledOnValidThread());
647 DCHECK(is_connected());
648 int rv = setsockopt(
649 socket_, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));
650 int last_error = errno;
651 DCHECK(!rv) << "Could not set socket receive buffer size: " << last_error;
652 return rv == 0 ? OK : MapSystemError(last_error);
653 }
654
655 int UDPSocketLibevent::SetSendBufferSizeInternal(int32 size) {
656 DCHECK(CalledOnValidThread());
657 DCHECK(is_connected());
658 int rv = setsockopt(
659 socket_, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size));
660 int last_error = errno;
661 DCHECK(!rv) << "Could not set socket send buffer size: " << last_error;
662 return rv == 0 ? OK : MapSystemError(last_error);
663 }
664
608 int UDPSocketLibevent::DoBind(const IPEndPoint& address) { 665 int UDPSocketLibevent::DoBind(const IPEndPoint& address) {
609 SockaddrStorage storage; 666 SockaddrStorage storage;
610 if (!address.ToSockAddr(storage.addr, &storage.addr_len)) 667 if (!address.ToSockAddr(storage.addr, &storage.addr_len))
611 return ERR_ADDRESS_INVALID; 668 return ERR_ADDRESS_INVALID;
612 int rv = bind(socket_, storage.addr, storage.addr_len); 669 int rv = bind(socket_, storage.addr, storage.addr_len);
613 if (rv == 0) 670 if (rv == 0)
614 return OK; 671 return OK;
615 int last_error = errno; 672 int last_error = errno;
616 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.UdpSocketBindErrorFromPosix", last_error); 673 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.UdpSocketBindErrorFromPosix", last_error);
617 #if defined(OS_CHROMEOS) 674 #if defined(OS_CHROMEOS)
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
767 return MapSystemError(errno); 824 return MapSystemError(errno);
768 825
769 return OK; 826 return OK;
770 } 827 }
771 828
772 void UDPSocketLibevent::DetachFromThread() { 829 void UDPSocketLibevent::DetachFromThread() {
773 base::NonThreadSafe::DetachFromThread(); 830 base::NonThreadSafe::DetachFromThread();
774 } 831 }
775 832
776 } // namespace net 833 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698