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

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

Issue 690903002: Remove timing limitation of SetOption invocation for PPAPI sockets. (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_win.h" 5 #include "net/udp/udp_socket_win.h"
6 6
7 #include <mstcpip.h> 7 #include <mstcpip.h>
8 8
9 #include "base/callback.h" 9 #include "base/callback.h"
10 #include "base/lazy_instance.h" 10 #include "base/lazy_instance.h"
(...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after
477 addr_family_ = addr_family; 477 addr_family_ = addr_family;
478 socket_ = CreatePlatformSocket(addr_family_, SOCK_DGRAM, IPPROTO_UDP); 478 socket_ = CreatePlatformSocket(addr_family_, SOCK_DGRAM, IPPROTO_UDP);
479 if (socket_ == INVALID_SOCKET) 479 if (socket_ == INVALID_SOCKET)
480 return MapSystemError(WSAGetLastError()); 480 return MapSystemError(WSAGetLastError());
481 core_ = new Core(this); 481 core_ = new Core(this);
482 return OK; 482 return OK;
483 } 483 }
484 484
485 int UDPSocketWin::SetReceiveBufferSize(int32 size) { 485 int UDPSocketWin::SetReceiveBufferSize(int32 size) {
486 DCHECK(CalledOnValidThread()); 486 DCHECK(CalledOnValidThread());
487 int rv = setsockopt(socket_, SOL_SOCKET, SO_RCVBUF, 487 if (!is_connected()) {
488 reinterpret_cast<const char*>(&size), sizeof(size)); 488 socket_options_ |= SOCKET_OPTION_RCVBUF_SIZE;
489 if (rv != 0) 489 rcvbuf_size_ = size;
490 return MapSystemError(WSAGetLastError());
491
492 // According to documentation, setsockopt may succeed, but we need to check
493 // the results via getsockopt to be sure it works on Windows.
494 int32 actual_size = 0;
495 int option_size = sizeof(actual_size);
496 rv = getsockopt(socket_, SOL_SOCKET, SO_RCVBUF,
497 reinterpret_cast<char*>(&actual_size), &option_size);
498 if (rv != 0)
499 return MapSystemError(WSAGetLastError());
500 if (actual_size >= size)
501 return OK; 490 return OK;
502 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SocketUnchangeableReceiveBuffer", 491 }
503 actual_size, 1000, 1000000, 50); 492 return SetReceiveBufferSizeInternal(size);
504 return ERR_SOCKET_RECEIVE_BUFFER_SIZE_UNCHANGEABLE;
505 } 493 }
506 494
507 int UDPSocketWin::SetSendBufferSize(int32 size) { 495 int UDPSocketWin::SetSendBufferSize(int32 size) {
508 DCHECK(CalledOnValidThread()); 496 DCHECK(CalledOnValidThread());
509 int rv = setsockopt(socket_, SOL_SOCKET, SO_SNDBUF, 497 if (!is_connected()) {
510 reinterpret_cast<const char*>(&size), sizeof(size)); 498 socket_options_ |= SOCKET_OPTION_SNDBUF_SIZE;
511 if (rv != 0) 499 sndbuf_size_ = size;
512 return MapSystemError(WSAGetLastError());
513 // According to documentation, setsockopt may succeed, but we need to check
514 // the results via getsockopt to be sure it works on Windows.
515 int32 actual_size = 0;
516 int option_size = sizeof(actual_size);
517 rv = getsockopt(socket_, SOL_SOCKET, SO_SNDBUF,
518 reinterpret_cast<char*>(&actual_size), &option_size);
519 if (rv != 0)
520 return MapSystemError(WSAGetLastError());
521 if (actual_size >= size)
522 return OK; 500 return OK;
523 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SocketUnchangeableSendBuffer", 501 }
524 actual_size, 1000, 1000000, 50); 502 return SetReceiveBufferSizeInternal(size);
525 return ERR_SOCKET_SEND_BUFFER_SIZE_UNCHANGEABLE;
526 } 503 }
527 504
528 void UDPSocketWin::AllowAddressReuse() { 505 int UDPSocketWin::AllowAddressReuse() {
529 DCHECK(CalledOnValidThread()); 506 DCHECK(CalledOnValidThread());
530 DCHECK(!is_connected()); 507 if (!is_connected()) {
531 508 socket_options_ |= SOCKET_OPTION_REUSE_ADDRESS;
532 socket_options_ |= SOCKET_OPTION_REUSE_ADDRESS; 509 return OK;
510 }
511 return SetAddressReuseInternal(true);
533 } 512 }
534 513
535 void UDPSocketWin::AllowBroadcast() { 514 int UDPSocketWin::DisallowAddressReuse() {
536 DCHECK(CalledOnValidThread()); 515 DCHECK(CalledOnValidThread());
537 DCHECK(!is_connected()); 516 if (!is_connected()) {
517 socket_options_ &= ~SOCKET_OPTION_REUSE_ADDRESS;
518 return OK;
519 }
520 return SetAddressReuseInternal(false);
521 }
538 522
539 socket_options_ |= SOCKET_OPTION_BROADCAST; 523 int UDPSocketWin::AllowBroadcast() {
524 DCHECK(CalledOnValidThread());
525 if (!is_connected()) {
526 socket_options_ |= SOCKET_OPTION_BROADCAST;
527 return OK;
528 }
529 return SetBroadcastInternal(true);
530 }
531
532 int UDPSocketWin::DisallowBroadcast() {
533 DCHECK(CalledOnValidThread());
534 if (!is_connected()) {
535 socket_options_ &= ~SOCKET_OPTION_BROADCAST;
536 return OK;
537 }
538 return SetBroadcastInternal(false);
540 } 539 }
541 540
542 void UDPSocketWin::DoReadCallback(int rv) { 541 void UDPSocketWin::DoReadCallback(int rv) {
543 DCHECK_NE(rv, ERR_IO_PENDING); 542 DCHECK_NE(rv, ERR_IO_PENDING);
544 DCHECK(!read_callback_.is_null()); 543 DCHECK(!read_callback_.is_null());
545 544
546 // since Run may result in Read being called, clear read_callback_ up front. 545 // since Run may result in Read being called, clear read_callback_ up front.
547 CompletionCallback c = read_callback_; 546 CompletionCallback c = read_callback_;
548 read_callback_.Reset(); 547 read_callback_.Reset();
549 c.Run(rv); 548 c.Run(rv);
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
708 return result; 707 return result;
709 } 708 }
710 } 709 }
711 710
712 core_->WatchForWrite(); 711 core_->WatchForWrite();
713 core_->write_iobuffer_ = buf; 712 core_->write_iobuffer_ = buf;
714 return ERR_IO_PENDING; 713 return ERR_IO_PENDING;
715 } 714 }
716 715
717 int UDPSocketWin::SetSocketOptions() { 716 int UDPSocketWin::SetSocketOptions() {
718 BOOL true_value = 1; 717 DCHECK(CalledOnValidThread());
718 DCHECK(is_connected());
719
719 if (socket_options_ & SOCKET_OPTION_REUSE_ADDRESS) { 720 if (socket_options_ & SOCKET_OPTION_REUSE_ADDRESS) {
720 int rv = setsockopt(socket_, SOL_SOCKET, SO_REUSEADDR, 721 int rv = SetAddressReuseInternal(true);
721 reinterpret_cast<const char*>(&true_value), 722 if (rv != OK)
722 sizeof(true_value)); 723 return rv;
723 if (rv < 0)
724 return MapSystemError(WSAGetLastError());
725 } 724 }
726 if (socket_options_ & SOCKET_OPTION_BROADCAST) { 725 if (socket_options_ & SOCKET_OPTION_BROADCAST) {
727 int rv = setsockopt(socket_, SOL_SOCKET, SO_BROADCAST, 726 int rv = SetBroadcastInternal(true);
728 reinterpret_cast<const char*>(&true_value), 727 if (rv != OK)
729 sizeof(true_value)); 728 return rv;
730 if (rv < 0)
731 return MapSystemError(WSAGetLastError());
732 } 729 }
733 if (!(socket_options_ & SOCKET_OPTION_MULTICAST_LOOP)) { 730 if (!(socket_options_ & SOCKET_OPTION_MULTICAST_LOOP)) {
734 DWORD loop = 0; 731 DWORD loop = 0;
735 int protocol_level = 732 int protocol_level =
736 addr_family_ == AF_INET ? IPPROTO_IP : IPPROTO_IPV6; 733 addr_family_ == AF_INET ? IPPROTO_IP : IPPROTO_IPV6;
737 int option = 734 int option =
738 addr_family_ == AF_INET ? IP_MULTICAST_LOOP: IPV6_MULTICAST_LOOP; 735 addr_family_ == AF_INET ? IP_MULTICAST_LOOP: IPV6_MULTICAST_LOOP;
739 int rv = setsockopt(socket_, protocol_level, option, 736 int rv = setsockopt(socket_, protocol_level, option,
740 reinterpret_cast<const char*>(&loop), sizeof(loop)); 737 reinterpret_cast<const char*>(&loop), sizeof(loop));
741 if (rv < 0) 738 if (rv < 0)
742 return MapSystemError(WSAGetLastError()); 739 return MapSystemError(WSAGetLastError());
743 } 740 }
741 if (socket_options_ & SOCKET_OPTION_RCVBUF_SIZE) {
742 int rv = SetReceiveBufferSizeInternal(rcvbuf_size_);
743 if (rv != OK)
744 return rv;
745 }
746 if (socket_options_ & SOCKET_OPTION_SNDBUF_SIZE) {
747 int rv = SetSendBufferSizeInternal(sndbuf_size_);
748 if (rv != OK)
749 return rv;
750 }
744 if (multicast_time_to_live_ != 1) { 751 if (multicast_time_to_live_ != 1) {
745 DWORD hops = multicast_time_to_live_; 752 DWORD hops = multicast_time_to_live_;
746 int protocol_level = 753 int protocol_level =
747 addr_family_ == AF_INET ? IPPROTO_IP : IPPROTO_IPV6; 754 addr_family_ == AF_INET ? IPPROTO_IP : IPPROTO_IPV6;
748 int option = 755 int option =
749 addr_family_ == AF_INET ? IP_MULTICAST_TTL: IPV6_MULTICAST_HOPS; 756 addr_family_ == AF_INET ? IP_MULTICAST_TTL: IPV6_MULTICAST_HOPS;
750 int rv = setsockopt(socket_, protocol_level, option, 757 int rv = setsockopt(socket_, protocol_level, option,
751 reinterpret_cast<const char*>(&hops), sizeof(hops)); 758 reinterpret_cast<const char*>(&hops), sizeof(hops));
752 if (rv < 0) 759 if (rv < 0)
753 return MapSystemError(WSAGetLastError()); 760 return MapSystemError(WSAGetLastError());
(...skipping 20 matching lines...) Expand all
774 break; 781 break;
775 } 782 }
776 default: 783 default:
777 NOTREACHED() << "Invalid address family"; 784 NOTREACHED() << "Invalid address family";
778 return ERR_ADDRESS_INVALID; 785 return ERR_ADDRESS_INVALID;
779 } 786 }
780 } 787 }
781 return OK; 788 return OK;
782 } 789 }
783 790
791 int UDPSocketWin::SetAddressReuseInternal(bool value) {
792 DCHECK(CalledOnValidThread());
793 DCHECK(is_connected());
794
795 int opt_value = value ? 1 : 0;
796 int rv = setsockopt(
797 socket_, SOL_SOCKET, SO_REUSEADDR,
798 reinterpret_cast<const char*>(&opt_value), sizeof(opt_value));
799 return rv == 0 ? OK : MapSystemError(WSAGetLastError());
800 }
801
802 int UDPSocketWin::SetBroadcastInternal(bool value) {
803 DCHECK(CalledOnValidThread());
804 DCHECK(is_connected());
805
806 int opt_value = value ? 1 : 0;
807 int rv = setsockopt(
808 socket_, SOL_SOCKET, SO_BROADCAST,
809 reinterpret_cast<const char*>(&opt_value), sizeof(opt_value));
810 return rv == 0 ? OK : MapSystemError(WSAGetLastError());
811 }
812
813 int UDPSocketWin::SetReceiveBufferSizeInternal(int32 size) {
814 DCHECK(CalledOnValidThread());
815 DCHECK(is_connected());
816
817 int rv = setsockopt(socket_, SOL_SOCKET, SO_RCVBUF,
818 reinterpret_cast<const char*>(&size), sizeof(size));
819 if (rv != 0)
820 return MapSystemError(WSAGetLastError());
821
822 // According to documentation, setsockopt may succeed, but we need to check
823 // the results via getsockopt to be sure it works on Windows.
824 int32 actual_size = 0;
825 int option_size = sizeof(actual_size);
826 rv = getsockopt(socket_, SOL_SOCKET, SO_RCVBUF,
827 reinterpret_cast<char*>(&actual_size), &option_size);
828 if (rv != 0)
829 return MapSystemError(WSAGetLastError());
830 if (actual_size >= size)
831 return OK;
832 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SocketUnchangeableReceiveBuffer",
833 actual_size, 1000, 1000000, 50);
834 return ERR_SOCKET_RECEIVE_BUFFER_SIZE_UNCHANGEABLE;
835 }
836
837 int UDPSocketWin::SetSendBufferSizeInternal(int32 size) {
838 DCHECK(CalledOnValidThread());
839 DCHECK(is_connected());
840
841 int rv = setsockopt(socket_, SOL_SOCKET, SO_SNDBUF,
842 reinterpret_cast<const char*>(&size), sizeof(size));
843 if (rv != 0)
844 return MapSystemError(WSAGetLastError());
845 // According to documentation, setsockopt may succeed, but we need to check
846 // the results via getsockopt to be sure it works on Windows.
847 int32 actual_size = 0;
848 int option_size = sizeof(actual_size);
849 rv = getsockopt(socket_, SOL_SOCKET, SO_SNDBUF,
850 reinterpret_cast<char*>(&actual_size), &option_size);
851 if (rv != 0)
852 return MapSystemError(WSAGetLastError());
853 if (actual_size >= size)
854 return OK;
855 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SocketUnchangeableSendBuffer",
856 actual_size, 1000, 1000000, 50);
857 return ERR_SOCKET_SEND_BUFFER_SIZE_UNCHANGEABLE;
858 }
859
784 int UDPSocketWin::DoBind(const IPEndPoint& address) { 860 int UDPSocketWin::DoBind(const IPEndPoint& address) {
785 SockaddrStorage storage; 861 SockaddrStorage storage;
786 if (!address.ToSockAddr(storage.addr, &storage.addr_len)) 862 if (!address.ToSockAddr(storage.addr, &storage.addr_len))
787 return ERR_ADDRESS_INVALID; 863 return ERR_ADDRESS_INVALID;
788 int rv = bind(socket_, storage.addr, storage.addr_len); 864 int rv = bind(socket_, storage.addr, storage.addr_len);
789 if (rv == 0) 865 if (rv == 0)
790 return OK; 866 return OK;
791 int last_error = WSAGetLastError(); 867 int last_error = WSAGetLastError();
792 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.UdpSocketBindErrorFromWinOS", last_error); 868 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.UdpSocketBindErrorFromWinOS", last_error);
793 // Map some codes that are special to bind() separately. 869 // Map some codes that are special to bind() separately.
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
1016 NULL); 1092 NULL);
1017 1093
1018 return OK; 1094 return OK;
1019 } 1095 }
1020 1096
1021 void UDPSocketWin::DetachFromThread() { 1097 void UDPSocketWin::DetachFromThread() {
1022 base::NonThreadSafe::DetachFromThread(); 1098 base::NonThreadSafe::DetachFromThread();
1023 } 1099 }
1024 1100
1025 } // namespace net 1101 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698