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

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 int result = SetReceiveBufferSizeInternal(size);
489 if (rv != 0) 489 if (result != OK)
490 return MapSystemError(WSAGetLastError()); 490 return result;
491 491 }
492 // According to documentation, setsockopt may succeed, but we need to check 492 socket_options_ |= SOCKET_OPTION_RCVBUF_SIZE;
493 // the results via getsockopt to be sure it works on Windows. 493 rcvbuf_size_ = size;
494 int32 actual_size = 0; 494 return OK;
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;
502 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SocketUnchangeableReceiveBuffer",
503 actual_size, 1000, 1000000, 50);
504 return ERR_SOCKET_RECEIVE_BUFFER_SIZE_UNCHANGEABLE;
505 } 495 }
506 496
507 int UDPSocketWin::SetSendBufferSize(int32 size) { 497 int UDPSocketWin::SetSendBufferSize(int32 size) {
508 DCHECK(CalledOnValidThread()); 498 DCHECK(CalledOnValidThread());
509 int rv = setsockopt(socket_, SOL_SOCKET, SO_SNDBUF, 499 if (is_connected()) {
510 reinterpret_cast<const char*>(&size), sizeof(size)); 500 int result = SetReceiveBufferSizeInternal(size);
511 if (rv != 0) 501 if (result != OK)
512 return MapSystemError(WSAGetLastError()); 502 return result;
513 // According to documentation, setsockopt may succeed, but we need to check 503 }
jar (doing other things) 2014/11/04 22:51:09 Note that you have changed the semantics here, as
jar (doing other things) 2014/11/05 01:18:31 <doh>... My mistake... please ignore this comment.
hidehiko 2014/11/05 12:48:30 Acknowledged.
514 // the results via getsockopt to be sure it works on Windows. 504 socket_options_ |= SOCKET_OPTION_SNDBUF_SIZE;
515 int32 actual_size = 0; 505 sndbuf_size_ = size;
516 int option_size = sizeof(actual_size); 506 return OK;
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;
523 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SocketUnchangeableSendBuffer",
524 actual_size, 1000, 1000000, 50);
525 return ERR_SOCKET_SEND_BUFFER_SIZE_UNCHANGEABLE;
526 } 507 }
527 508
528 void UDPSocketWin::AllowAddressReuse() { 509 int UDPSocketWin::AllowAddressReuse() {
529 DCHECK(CalledOnValidThread()); 510 DCHECK(CalledOnValidThread());
530 DCHECK(!is_connected()); 511 if (is_connected()) {
531 512 int result = SetAddressReuseInternal(true);
513 if (result != OK)
514 return result;
515 }
532 socket_options_ |= SOCKET_OPTION_REUSE_ADDRESS; 516 socket_options_ |= SOCKET_OPTION_REUSE_ADDRESS;
517 return OK;
533 } 518 }
534 519
535 void UDPSocketWin::AllowBroadcast() { 520 int UDPSocketWin::DisallowAddressReuse() {
536 DCHECK(CalledOnValidThread()); 521 DCHECK(CalledOnValidThread());
537 DCHECK(!is_connected()); 522 if (is_connected()) {
523 int result = SetAddressReuseInternal(false);
524 if (result != OK)
525 return result;
526 }
527 socket_options_ &= ~SOCKET_OPTION_REUSE_ADDRESS;
528 return OK;
529 }
538 530
531 int UDPSocketWin::AllowBroadcast() {
532 DCHECK(CalledOnValidThread());
533 if (is_connected()) {
534 int result = SetBroadcastInternal(true);
535 if (result != OK)
536 return result;
537 }
539 socket_options_ |= SOCKET_OPTION_BROADCAST; 538 socket_options_ |= SOCKET_OPTION_BROADCAST;
539 return OK;
540 }
541
542 int UDPSocketWin::DisallowBroadcast() {
543 DCHECK(CalledOnValidThread());
544 if (is_connected()) {
545 int result = SetBroadcastInternal(false);
546 if (result != OK)
547 return result;
548 }
549 socket_options_ &= ~SOCKET_OPTION_BROADCAST;
550 return OK;
540 } 551 }
541 552
542 void UDPSocketWin::DoReadCallback(int rv) { 553 void UDPSocketWin::DoReadCallback(int rv) {
543 DCHECK_NE(rv, ERR_IO_PENDING); 554 DCHECK_NE(rv, ERR_IO_PENDING);
544 DCHECK(!read_callback_.is_null()); 555 DCHECK(!read_callback_.is_null());
545 556
546 // since Run may result in Read being called, clear read_callback_ up front. 557 // since Run may result in Read being called, clear read_callback_ up front.
547 CompletionCallback c = read_callback_; 558 CompletionCallback c = read_callback_;
548 read_callback_.Reset(); 559 read_callback_.Reset();
549 c.Run(rv); 560 c.Run(rv);
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
708 return result; 719 return result;
709 } 720 }
710 } 721 }
711 722
712 core_->WatchForWrite(); 723 core_->WatchForWrite();
713 core_->write_iobuffer_ = buf; 724 core_->write_iobuffer_ = buf;
714 return ERR_IO_PENDING; 725 return ERR_IO_PENDING;
715 } 726 }
716 727
717 int UDPSocketWin::SetSocketOptions() { 728 int UDPSocketWin::SetSocketOptions() {
718 BOOL true_value = 1; 729 DCHECK(CalledOnValidThread());
730 DCHECK(is_connected());
731
719 if (socket_options_ & SOCKET_OPTION_REUSE_ADDRESS) { 732 if (socket_options_ & SOCKET_OPTION_REUSE_ADDRESS) {
720 int rv = setsockopt(socket_, SOL_SOCKET, SO_REUSEADDR, 733 int rv = SetAddressReuseInternal(true);
721 reinterpret_cast<const char*>(&true_value), 734 if (rv != OK)
722 sizeof(true_value)); 735 return rv;
723 if (rv < 0)
724 return MapSystemError(WSAGetLastError());
725 } 736 }
726 if (socket_options_ & SOCKET_OPTION_BROADCAST) { 737 if (socket_options_ & SOCKET_OPTION_BROADCAST) {
727 int rv = setsockopt(socket_, SOL_SOCKET, SO_BROADCAST, 738 int rv = SetBroadcastInternal(true);
728 reinterpret_cast<const char*>(&true_value), 739 if (rv != OK)
729 sizeof(true_value)); 740 return rv;
730 if (rv < 0)
731 return MapSystemError(WSAGetLastError());
732 } 741 }
733 if (!(socket_options_ & SOCKET_OPTION_MULTICAST_LOOP)) { 742 if (!(socket_options_ & SOCKET_OPTION_MULTICAST_LOOP)) {
734 DWORD loop = 0; 743 DWORD loop = 0;
735 int protocol_level = 744 int protocol_level =
736 addr_family_ == AF_INET ? IPPROTO_IP : IPPROTO_IPV6; 745 addr_family_ == AF_INET ? IPPROTO_IP : IPPROTO_IPV6;
737 int option = 746 int option =
738 addr_family_ == AF_INET ? IP_MULTICAST_LOOP: IPV6_MULTICAST_LOOP; 747 addr_family_ == AF_INET ? IP_MULTICAST_LOOP: IPV6_MULTICAST_LOOP;
739 int rv = setsockopt(socket_, protocol_level, option, 748 int rv = setsockopt(socket_, protocol_level, option,
740 reinterpret_cast<const char*>(&loop), sizeof(loop)); 749 reinterpret_cast<const char*>(&loop), sizeof(loop));
741 if (rv < 0) 750 if (rv < 0)
742 return MapSystemError(WSAGetLastError()); 751 return MapSystemError(WSAGetLastError());
743 } 752 }
753 if (socket_options_ & SOCKET_OPTION_RCVBUF_SIZE) {
754 int rv = SetReceiveBufferSizeInternal(rcvbuf_size_);
755 if (rv != OK)
756 return rv;
757 }
758 if (socket_options_ & SOCKET_OPTION_SNDBUF_SIZE) {
759 int rv = SetSendBufferSizeInternal(sndbuf_size_);
760 if (rv != OK)
761 return rv;
762 }
744 if (multicast_time_to_live_ != 1) { 763 if (multicast_time_to_live_ != 1) {
745 DWORD hops = multicast_time_to_live_; 764 DWORD hops = multicast_time_to_live_;
746 int protocol_level = 765 int protocol_level =
747 addr_family_ == AF_INET ? IPPROTO_IP : IPPROTO_IPV6; 766 addr_family_ == AF_INET ? IPPROTO_IP : IPPROTO_IPV6;
748 int option = 767 int option =
749 addr_family_ == AF_INET ? IP_MULTICAST_TTL: IPV6_MULTICAST_HOPS; 768 addr_family_ == AF_INET ? IP_MULTICAST_TTL: IPV6_MULTICAST_HOPS;
750 int rv = setsockopt(socket_, protocol_level, option, 769 int rv = setsockopt(socket_, protocol_level, option,
751 reinterpret_cast<const char*>(&hops), sizeof(hops)); 770 reinterpret_cast<const char*>(&hops), sizeof(hops));
752 if (rv < 0) 771 if (rv < 0)
753 return MapSystemError(WSAGetLastError()); 772 return MapSystemError(WSAGetLastError());
(...skipping 20 matching lines...) Expand all
774 break; 793 break;
775 } 794 }
776 default: 795 default:
777 NOTREACHED() << "Invalid address family"; 796 NOTREACHED() << "Invalid address family";
778 return ERR_ADDRESS_INVALID; 797 return ERR_ADDRESS_INVALID;
779 } 798 }
780 } 799 }
781 return OK; 800 return OK;
782 } 801 }
783 802
803 int UDPSocketWin::SetAddressReuseInternal(bool value) {
804 DCHECK(CalledOnValidThread());
805 DCHECK(is_connected());
806
807 int opt_value = value ? 1 : 0;
808 int rv = setsockopt(
809 socket_, SOL_SOCKET, SO_REUSEADDR,
810 reinterpret_cast<const char*>(&opt_value), sizeof(opt_value));
811 return rv == 0 ? OK : MapSystemError(WSAGetLastError());
812 }
813
814 int UDPSocketWin::SetBroadcastInternal(bool value) {
815 DCHECK(CalledOnValidThread());
816 DCHECK(is_connected());
817
818 int opt_value = value ? 1 : 0;
819 int rv = setsockopt(
820 socket_, SOL_SOCKET, SO_BROADCAST,
821 reinterpret_cast<const char*>(&opt_value), sizeof(opt_value));
822 return rv == 0 ? OK : MapSystemError(WSAGetLastError());
823 }
824
825 int UDPSocketWin::SetReceiveBufferSizeInternal(int32 size) {
826 DCHECK(CalledOnValidThread());
827 DCHECK(is_connected());
828
829 int rv = setsockopt(socket_, SOL_SOCKET, SO_RCVBUF,
830 reinterpret_cast<const char*>(&size), sizeof(size));
831 if (rv != 0)
832 return MapSystemError(WSAGetLastError());
833
834 // According to documentation, setsockopt may succeed, but we need to check
835 // the results via getsockopt to be sure it works on Windows.
836 int32 actual_size = 0;
837 int option_size = sizeof(actual_size);
838 rv = getsockopt(socket_, SOL_SOCKET, SO_RCVBUF,
839 reinterpret_cast<char*>(&actual_size), &option_size);
840 if (rv != 0)
841 return MapSystemError(WSAGetLastError());
842 if (actual_size >= size)
843 return OK;
844 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SocketUnchangeableReceiveBuffer",
845 actual_size, 1000, 1000000, 50);
846 return ERR_SOCKET_RECEIVE_BUFFER_SIZE_UNCHANGEABLE;
847 }
848
849 int UDPSocketWin::SetSendBufferSizeInternal(int32 size) {
850 DCHECK(CalledOnValidThread());
851 DCHECK(is_connected());
852
853 int rv = setsockopt(socket_, SOL_SOCKET, SO_SNDBUF,
854 reinterpret_cast<const char*>(&size), sizeof(size));
855 if (rv != 0)
856 return MapSystemError(WSAGetLastError());
857 // According to documentation, setsockopt may succeed, but we need to check
858 // the results via getsockopt to be sure it works on Windows.
859 int32 actual_size = 0;
860 int option_size = sizeof(actual_size);
861 rv = getsockopt(socket_, SOL_SOCKET, SO_SNDBUF,
862 reinterpret_cast<char*>(&actual_size), &option_size);
863 if (rv != 0)
864 return MapSystemError(WSAGetLastError());
865 if (actual_size >= size)
866 return OK;
867 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SocketUnchangeableSendBuffer",
868 actual_size, 1000, 1000000, 50);
869 return ERR_SOCKET_SEND_BUFFER_SIZE_UNCHANGEABLE;
870 }
871
784 int UDPSocketWin::DoBind(const IPEndPoint& address) { 872 int UDPSocketWin::DoBind(const IPEndPoint& address) {
785 SockaddrStorage storage; 873 SockaddrStorage storage;
786 if (!address.ToSockAddr(storage.addr, &storage.addr_len)) 874 if (!address.ToSockAddr(storage.addr, &storage.addr_len))
787 return ERR_ADDRESS_INVALID; 875 return ERR_ADDRESS_INVALID;
788 int rv = bind(socket_, storage.addr, storage.addr_len); 876 int rv = bind(socket_, storage.addr, storage.addr_len);
789 if (rv == 0) 877 if (rv == 0)
790 return OK; 878 return OK;
791 int last_error = WSAGetLastError(); 879 int last_error = WSAGetLastError();
792 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.UdpSocketBindErrorFromWinOS", last_error); 880 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.UdpSocketBindErrorFromWinOS", last_error);
793 // Map some codes that are special to bind() separately. 881 // Map some codes that are special to bind() separately.
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
1016 NULL); 1104 NULL);
1017 1105
1018 return OK; 1106 return OK;
1019 } 1107 }
1020 1108
1021 void UDPSocketWin::DetachFromThread() { 1109 void UDPSocketWin::DetachFromThread() {
1022 base::NonThreadSafe::DetachFromThread(); 1110 base::NonThreadSafe::DetachFromThread();
1023 } 1111 }
1024 1112
1025 } // namespace net 1113 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698