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

Side by Side Diff: net/udp/udp_socket_win.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
« no previous file with comments | « net/udp/udp_socket_win.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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()) {
rvargas (doing something else) 2014/11/14 02:44:43 As I mentioned on the other review, I don't really
hidehiko 2014/11/19 06:11:24 This is to address mmenke@'s comment https://coder
rvargas (doing something else) 2014/11/19 22:18:56 Both? I Agree with Matt in that rebinding is a wei
hidehiko 2014/12/01 16:06:24 Ok, Done both. Note: along the change, now UDPServ
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 = SetSendBufferSizeInternal(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 }
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 void UDPSocketWin::AllowAddressReuse() {
529 DCHECK(CalledOnValidThread()); 510 DCHECK(CalledOnValidThread());
530 DCHECK(!is_connected()); 511 DCHECK(!is_connected());
531 512
532 socket_options_ |= SOCKET_OPTION_REUSE_ADDRESS; 513 socket_options_ |= SOCKET_OPTION_REUSE_ADDRESS;
533 } 514 }
534 515
535 void UDPSocketWin::AllowBroadcast() { 516 int UDPSocketWin::SetBroadcast(bool broadcast) {
536 DCHECK(CalledOnValidThread()); 517 DCHECK(CalledOnValidThread());
537 DCHECK(!is_connected()); 518 if (is_connected()) {
538 519 int result = SetBroadcastInternal(broadcast);
539 socket_options_ |= SOCKET_OPTION_BROADCAST; 520 if (result != OK)
521 return result;
522 }
523 if (broadcast)
524 socket_options_ |= SOCKET_OPTION_BROADCAST;
525 else
526 socket_options_ &= ~SOCKET_OPTION_BROADCAST;
527 return OK;
540 } 528 }
541 529
542 void UDPSocketWin::DoReadCallback(int rv) { 530 void UDPSocketWin::DoReadCallback(int rv) {
543 DCHECK_NE(rv, ERR_IO_PENDING); 531 DCHECK_NE(rv, ERR_IO_PENDING);
544 DCHECK(!read_callback_.is_null()); 532 DCHECK(!read_callback_.is_null());
545 533
546 // since Run may result in Read being called, clear read_callback_ up front. 534 // since Run may result in Read being called, clear read_callback_ up front.
547 CompletionCallback c = read_callback_; 535 CompletionCallback c = read_callback_;
548 read_callback_.Reset(); 536 read_callback_.Reset();
549 c.Run(rv); 537 c.Run(rv);
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
710 } 698 }
711 699
712 core_->WatchForWrite(); 700 core_->WatchForWrite();
713 core_->write_iobuffer_ = buf; 701 core_->write_iobuffer_ = buf;
714 return ERR_IO_PENDING; 702 return ERR_IO_PENDING;
715 } 703 }
716 704
717 int UDPSocketWin::SetSocketOptions() { 705 int UDPSocketWin::SetSocketOptions() {
718 BOOL true_value = 1; 706 BOOL true_value = 1;
719 if (socket_options_ & SOCKET_OPTION_REUSE_ADDRESS) { 707 if (socket_options_ & SOCKET_OPTION_REUSE_ADDRESS) {
720 int rv = setsockopt(socket_, SOL_SOCKET, SO_REUSEADDR, 708 int rv = AllowAddressReuseInternal();
721 reinterpret_cast<const char*>(&true_value), 709 if (rv != OK)
722 sizeof(true_value)); 710 return rv;
723 if (rv < 0)
724 return MapSystemError(WSAGetLastError());
725 } 711 }
726 if (socket_options_ & SOCKET_OPTION_BROADCAST) { 712 if (socket_options_ & SOCKET_OPTION_BROADCAST) {
727 int rv = setsockopt(socket_, SOL_SOCKET, SO_BROADCAST, 713 int rv = SetBroadcastInternal(true);
728 reinterpret_cast<const char*>(&true_value), 714 if (rv != OK)
729 sizeof(true_value)); 715 return rv;
730 if (rv < 0)
731 return MapSystemError(WSAGetLastError());
732 } 716 }
733 if (!(socket_options_ & SOCKET_OPTION_MULTICAST_LOOP)) { 717 if (!(socket_options_ & SOCKET_OPTION_MULTICAST_LOOP)) {
734 DWORD loop = 0; 718 DWORD loop = 0;
735 int protocol_level = 719 int protocol_level =
736 addr_family_ == AF_INET ? IPPROTO_IP : IPPROTO_IPV6; 720 addr_family_ == AF_INET ? IPPROTO_IP : IPPROTO_IPV6;
737 int option = 721 int option =
738 addr_family_ == AF_INET ? IP_MULTICAST_LOOP: IPV6_MULTICAST_LOOP; 722 addr_family_ == AF_INET ? IP_MULTICAST_LOOP: IPV6_MULTICAST_LOOP;
739 int rv = setsockopt(socket_, protocol_level, option, 723 int rv = setsockopt(socket_, protocol_level, option,
740 reinterpret_cast<const char*>(&loop), sizeof(loop)); 724 reinterpret_cast<const char*>(&loop), sizeof(loop));
741 if (rv < 0) 725 if (rv < 0)
742 return MapSystemError(WSAGetLastError()); 726 return MapSystemError(WSAGetLastError());
743 } 727 }
728 if (socket_options_ & SOCKET_OPTION_RCVBUF_SIZE) {
729 int rv = SetReceiveBufferSizeInternal(rcvbuf_size_);
730 if (rv != OK)
731 return rv;
732 }
733 if (socket_options_ & SOCKET_OPTION_SNDBUF_SIZE) {
734 int rv = SetSendBufferSizeInternal(sndbuf_size_);
735 if (rv != OK)
736 return rv;
737 }
738
744 if (multicast_time_to_live_ != 1) { 739 if (multicast_time_to_live_ != 1) {
745 DWORD hops = multicast_time_to_live_; 740 DWORD hops = multicast_time_to_live_;
746 int protocol_level = 741 int protocol_level =
747 addr_family_ == AF_INET ? IPPROTO_IP : IPPROTO_IPV6; 742 addr_family_ == AF_INET ? IPPROTO_IP : IPPROTO_IPV6;
748 int option = 743 int option =
749 addr_family_ == AF_INET ? IP_MULTICAST_TTL: IPV6_MULTICAST_HOPS; 744 addr_family_ == AF_INET ? IP_MULTICAST_TTL: IPV6_MULTICAST_HOPS;
750 int rv = setsockopt(socket_, protocol_level, option, 745 int rv = setsockopt(socket_, protocol_level, option,
751 reinterpret_cast<const char*>(&hops), sizeof(hops)); 746 reinterpret_cast<const char*>(&hops), sizeof(hops));
752 if (rv < 0) 747 if (rv < 0)
753 return MapSystemError(WSAGetLastError()); 748 return MapSystemError(WSAGetLastError());
(...skipping 20 matching lines...) Expand all
774 break; 769 break;
775 } 770 }
776 default: 771 default:
777 NOTREACHED() << "Invalid address family"; 772 NOTREACHED() << "Invalid address family";
778 return ERR_ADDRESS_INVALID; 773 return ERR_ADDRESS_INVALID;
779 } 774 }
780 } 775 }
781 return OK; 776 return OK;
782 } 777 }
783 778
779 int UDPSocketWin::AllowAddressReuseInternal() {
780 DCHECK(CalledOnValidThread());
781 DCHECK(is_connected());
782
783 BOOL opt_value = TRUE;
784 int rv = setsockopt(
785 socket_, SOL_SOCKET, SO_REUSEADDR,
786 reinterpret_cast<const char*>(&opt_value), sizeof(opt_value));
787 return rv == 0 ? OK : MapSystemError(WSAGetLastError());
788 }
789
790 int UDPSocketWin::SetBroadcastInternal(bool broadcast) {
791 DCHECK(CalledOnValidThread());
792 DCHECK(is_connected());
793
794 BOOL opt_value = broadcast ? TRUE : FALSE;
795 int rv = setsockopt(
796 socket_, SOL_SOCKET, SO_BROADCAST,
797 reinterpret_cast<const char*>(&opt_value), sizeof(opt_value));
798 return rv == 0 ? OK : MapSystemError(WSAGetLastError());
799 }
800
801 int UDPSocketWin::SetReceiveBufferSizeInternal(int32 size) {
802 DCHECK(CalledOnValidThread());
803 DCHECK(is_connected());
804
805 int rv = setsockopt(socket_, SOL_SOCKET, SO_RCVBUF,
806 reinterpret_cast<const char*>(&size), sizeof(size));
807 if (rv != 0)
808 return MapSystemError(WSAGetLastError());
809
810 // According to documentation, setsockopt may succeed, but we need to check
811 // the results via getsockopt to be sure it works on Windows.
812 int32 actual_size = 0;
813 int option_size = sizeof(actual_size);
814 rv = getsockopt(socket_, SOL_SOCKET, SO_RCVBUF,
815 reinterpret_cast<char*>(&actual_size), &option_size);
816 if (rv != 0)
817 return MapSystemError(WSAGetLastError());
818 if (actual_size >= size)
819 return OK;
820 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SocketUnchangeableReceiveBuffer",
821 actual_size, 1000, 1000000, 50);
822 return ERR_SOCKET_RECEIVE_BUFFER_SIZE_UNCHANGEABLE;
823 }
824
825 int UDPSocketWin::SetSendBufferSizeInternal(int32 size) {
826 DCHECK(CalledOnValidThread());
827 DCHECK(is_connected());
828
829 int rv = setsockopt(socket_, SOL_SOCKET, SO_SNDBUF,
830 reinterpret_cast<const char*>(&size), sizeof(size));
831 if (rv != 0)
832 return MapSystemError(WSAGetLastError());
833 // According to documentation, setsockopt may succeed, but we need to check
834 // the results via getsockopt to be sure it works on Windows.
835 int32 actual_size = 0;
836 int option_size = sizeof(actual_size);
837 rv = getsockopt(socket_, SOL_SOCKET, SO_SNDBUF,
838 reinterpret_cast<char*>(&actual_size), &option_size);
839 if (rv != 0)
840 return MapSystemError(WSAGetLastError());
841 if (actual_size >= size)
842 return OK;
843 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SocketUnchangeableSendBuffer",
844 actual_size, 1000, 1000000, 50);
845 return ERR_SOCKET_SEND_BUFFER_SIZE_UNCHANGEABLE;
846 }
847
784 int UDPSocketWin::DoBind(const IPEndPoint& address) { 848 int UDPSocketWin::DoBind(const IPEndPoint& address) {
785 SockaddrStorage storage; 849 SockaddrStorage storage;
786 if (!address.ToSockAddr(storage.addr, &storage.addr_len)) 850 if (!address.ToSockAddr(storage.addr, &storage.addr_len))
787 return ERR_ADDRESS_INVALID; 851 return ERR_ADDRESS_INVALID;
788 int rv = bind(socket_, storage.addr, storage.addr_len); 852 int rv = bind(socket_, storage.addr, storage.addr_len);
789 if (rv == 0) 853 if (rv == 0)
790 return OK; 854 return OK;
791 int last_error = WSAGetLastError(); 855 int last_error = WSAGetLastError();
792 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.UdpSocketBindErrorFromWinOS", last_error); 856 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.UdpSocketBindErrorFromWinOS", last_error);
793 // Map some codes that are special to bind() separately. 857 // Map some codes that are special to bind() separately.
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
1016 NULL); 1080 NULL);
1017 1081
1018 return OK; 1082 return OK;
1019 } 1083 }
1020 1084
1021 void UDPSocketWin::DetachFromThread() { 1085 void UDPSocketWin::DetachFromThread() {
1022 base::NonThreadSafe::DetachFromThread(); 1086 base::NonThreadSafe::DetachFromThread();
1023 } 1087 }
1024 1088
1025 } // namespace net 1089 } // namespace net
OLDNEW
« no previous file with comments | « net/udp/udp_socket_win.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698