OLD | NEW |
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/logging.h" | 10 #include "base/logging.h" |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
159 | 159 |
160 //----------------------------------------------------------------------------- | 160 //----------------------------------------------------------------------------- |
161 | 161 |
162 UDPSocketWin::UDPSocketWin(DatagramSocket::BindType bind_type, | 162 UDPSocketWin::UDPSocketWin(DatagramSocket::BindType bind_type, |
163 const RandIntCallback& rand_int_cb, | 163 const RandIntCallback& rand_int_cb, |
164 net::NetLog* net_log, | 164 net::NetLog* net_log, |
165 const net::NetLog::Source& source) | 165 const net::NetLog::Source& source) |
166 : socket_(INVALID_SOCKET), | 166 : socket_(INVALID_SOCKET), |
167 addr_family_(0), | 167 addr_family_(0), |
168 socket_options_(SOCKET_OPTION_MULTICAST_LOOP), | 168 socket_options_(SOCKET_OPTION_MULTICAST_LOOP), |
| 169 multicast_interface_(0), |
169 multicast_time_to_live_(1), | 170 multicast_time_to_live_(1), |
170 bind_type_(bind_type), | 171 bind_type_(bind_type), |
171 rand_int_cb_(rand_int_cb), | 172 rand_int_cb_(rand_int_cb), |
172 recv_from_address_(NULL), | 173 recv_from_address_(NULL), |
173 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_UDP_SOCKET)) { | 174 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_UDP_SOCKET)) { |
174 EnsureWinsockInit(); | 175 EnsureWinsockInit(); |
175 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, | 176 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, |
176 source.ToEventParametersCallback()); | 177 source.ToEventParametersCallback()); |
177 if (bind_type == DatagramSocket::RANDOM_BIND) | 178 if (bind_type == DatagramSocket::RANDOM_BIND) |
178 DCHECK(!rand_int_cb.is_null()); | 179 DCHECK(!rand_int_cb.is_null()); |
(...skipping 436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
615 DWORD hops = multicast_time_to_live_; | 616 DWORD hops = multicast_time_to_live_; |
616 int protocol_level = | 617 int protocol_level = |
617 addr_family_ == AF_INET ? IPPROTO_IP : IPPROTO_IPV6; | 618 addr_family_ == AF_INET ? IPPROTO_IP : IPPROTO_IPV6; |
618 int option = | 619 int option = |
619 addr_family_ == AF_INET ? IP_MULTICAST_TTL: IPV6_MULTICAST_HOPS; | 620 addr_family_ == AF_INET ? IP_MULTICAST_TTL: IPV6_MULTICAST_HOPS; |
620 int rv = setsockopt(socket_, protocol_level, option, | 621 int rv = setsockopt(socket_, protocol_level, option, |
621 reinterpret_cast<const char*>(&hops), sizeof(hops)); | 622 reinterpret_cast<const char*>(&hops), sizeof(hops)); |
622 if (rv < 0) | 623 if (rv < 0) |
623 return MapSystemError(WSAGetLastError()); | 624 return MapSystemError(WSAGetLastError()); |
624 } | 625 } |
| 626 if (multicast_interface_ != 0) { |
| 627 switch (addr_family_) { |
| 628 case AF_INET: { |
| 629 in_addr address; |
| 630 address.s_addr = htonl(multicast_interface_); |
| 631 int rv = setsockopt(socket_, IPPROTO_IP, IP_MULTICAST_IF, |
| 632 reinterpret_cast<const char*>(&address), |
| 633 sizeof(address)); |
| 634 if (rv) |
| 635 return MapSystemError(WSAGetLastError()); |
| 636 break; |
| 637 } |
| 638 case AF_INET6: { |
| 639 uint32 interface_index = multicast_interface_; |
| 640 int rv = setsockopt(socket_, IPPROTO_IPV6, IPV6_MULTICAST_IF, |
| 641 reinterpret_cast<const char*>(&interface_index), |
| 642 sizeof(interface_index)); |
| 643 if (rv) |
| 644 return MapSystemError(WSAGetLastError()); |
| 645 break; |
| 646 } |
| 647 default: |
| 648 NOTREACHED() << "Invalid address family"; |
| 649 return ERR_ADDRESS_INVALID; |
| 650 } |
| 651 } |
625 return OK; | 652 return OK; |
626 } | 653 } |
627 | 654 |
628 int UDPSocketWin::DoBind(const IPEndPoint& address) { | 655 int UDPSocketWin::DoBind(const IPEndPoint& address) { |
629 SockaddrStorage storage; | 656 SockaddrStorage storage; |
630 if (!address.ToSockAddr(storage.addr, &storage.addr_len)) | 657 if (!address.ToSockAddr(storage.addr, &storage.addr_len)) |
631 return ERR_ADDRESS_INVALID; | 658 return ERR_ADDRESS_INVALID; |
632 int rv = bind(socket_, storage.addr, storage.addr_len); | 659 int rv = bind(socket_, storage.addr, storage.addr_len); |
633 return rv < 0 ? MapSystemError(WSAGetLastError()) : rv; | 660 return rv < 0 ? MapSystemError(WSAGetLastError()) : rv; |
634 } | 661 } |
(...skipping 10 matching lines...) Expand all Loading... |
645 return rv; | 672 return rv; |
646 } | 673 } |
647 return DoBind(IPEndPoint(ip, 0)); | 674 return DoBind(IPEndPoint(ip, 0)); |
648 } | 675 } |
649 | 676 |
650 bool UDPSocketWin::ReceiveAddressToIPEndpoint(IPEndPoint* address) const { | 677 bool UDPSocketWin::ReceiveAddressToIPEndpoint(IPEndPoint* address) const { |
651 SockaddrStorage& storage = core_->recv_addr_storage_; | 678 SockaddrStorage& storage = core_->recv_addr_storage_; |
652 return address->FromSockAddr(storage.addr, storage.addr_len); | 679 return address->FromSockAddr(storage.addr, storage.addr_len); |
653 } | 680 } |
654 | 681 |
655 int UDPSocketWin::JoinGroup( | 682 int UDPSocketWin::JoinGroup(const IPAddressNumber& group_address) { |
656 const IPAddressNumber& group_address) const { | |
657 DCHECK(CalledOnValidThread()); | 683 DCHECK(CalledOnValidThread()); |
658 if (!is_connected()) | 684 if (!is_connected()) |
659 return ERR_SOCKET_NOT_CONNECTED; | 685 return ERR_SOCKET_NOT_CONNECTED; |
660 | 686 |
661 switch (group_address.size()) { | 687 switch (group_address.size()) { |
662 case kIPv4AddressSize: { | 688 case kIPv4AddressSize: { |
663 if (addr_family_ != AF_INET) | 689 if (addr_family_ != AF_INET) |
664 return ERR_ADDRESS_INVALID; | 690 return ERR_ADDRESS_INVALID; |
665 ip_mreq mreq; | 691 ip_mreq mreq; |
666 mreq.imr_interface.s_addr = INADDR_ANY; | 692 mreq.imr_interface.s_addr = htonl(multicast_interface_); |
667 memcpy(&mreq.imr_multiaddr, &group_address[0], kIPv4AddressSize); | 693 memcpy(&mreq.imr_multiaddr, &group_address[0], kIPv4AddressSize); |
668 int rv = setsockopt(socket_, IPPROTO_IP, IP_ADD_MEMBERSHIP, | 694 int rv = setsockopt(socket_, IPPROTO_IP, IP_ADD_MEMBERSHIP, |
669 reinterpret_cast<const char*>(&mreq), | 695 reinterpret_cast<const char*>(&mreq), |
670 sizeof(mreq)); | 696 sizeof(mreq)); |
671 if (rv) | 697 if (rv) |
672 return MapSystemError(WSAGetLastError()); | 698 return MapSystemError(WSAGetLastError()); |
673 return OK; | 699 return OK; |
674 } | 700 } |
675 case kIPv6AddressSize: { | 701 case kIPv6AddressSize: { |
676 if (addr_family_ != AF_INET6) | 702 if (addr_family_ != AF_INET6) |
677 return ERR_ADDRESS_INVALID; | 703 return ERR_ADDRESS_INVALID; |
678 ipv6_mreq mreq; | 704 ipv6_mreq mreq; |
679 mreq.ipv6mr_interface = 0; // 0 indicates default multicast interface. | 705 mreq.ipv6mr_interface = multicast_interface_; |
680 memcpy(&mreq.ipv6mr_multiaddr, &group_address[0], kIPv6AddressSize); | 706 memcpy(&mreq.ipv6mr_multiaddr, &group_address[0], kIPv6AddressSize); |
681 int rv = setsockopt(socket_, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, | 707 int rv = setsockopt(socket_, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, |
682 reinterpret_cast<const char*>(&mreq), | 708 reinterpret_cast<const char*>(&mreq), |
683 sizeof(mreq)); | 709 sizeof(mreq)); |
684 if (rv) | 710 if (rv) |
685 return MapSystemError(WSAGetLastError()); | 711 return MapSystemError(WSAGetLastError()); |
686 return OK; | 712 return OK; |
687 } | 713 } |
688 default: | 714 default: |
689 NOTREACHED() << "Invalid address family"; | 715 NOTREACHED() << "Invalid address family"; |
690 return ERR_ADDRESS_INVALID; | 716 return ERR_ADDRESS_INVALID; |
691 } | 717 } |
692 } | 718 } |
693 | 719 |
694 int UDPSocketWin::LeaveGroup( | 720 int UDPSocketWin::LeaveGroup(const IPAddressNumber& group_address) { |
695 const IPAddressNumber& group_address) const { | |
696 DCHECK(CalledOnValidThread()); | 721 DCHECK(CalledOnValidThread()); |
697 if (!is_connected()) | 722 if (!is_connected()) |
698 return ERR_SOCKET_NOT_CONNECTED; | 723 return ERR_SOCKET_NOT_CONNECTED; |
699 | 724 |
700 switch (group_address.size()) { | 725 switch (group_address.size()) { |
701 case kIPv4AddressSize: { | 726 case kIPv4AddressSize: { |
702 if (addr_family_ != AF_INET) | 727 if (addr_family_ != AF_INET) |
703 return ERR_ADDRESS_INVALID; | 728 return ERR_ADDRESS_INVALID; |
704 ip_mreq mreq; | 729 ip_mreq mreq; |
705 mreq.imr_interface.s_addr = INADDR_ANY; | 730 mreq.imr_interface.s_addr = htonl(multicast_interface_); |
706 memcpy(&mreq.imr_multiaddr, &group_address[0], kIPv4AddressSize); | 731 memcpy(&mreq.imr_multiaddr, &group_address[0], kIPv4AddressSize); |
707 int rv = setsockopt(socket_, IPPROTO_IP, IP_DROP_MEMBERSHIP, | 732 int rv = setsockopt(socket_, IPPROTO_IP, IP_DROP_MEMBERSHIP, |
708 reinterpret_cast<const char*>(&mreq), | 733 reinterpret_cast<const char*>(&mreq), sizeof(mreq)); |
709 sizeof(mreq)); | |
710 if (rv) | 734 if (rv) |
711 return MapSystemError(WSAGetLastError()); | 735 return MapSystemError(WSAGetLastError()); |
712 return OK; | 736 return OK; |
713 } | 737 } |
714 case kIPv6AddressSize: { | 738 case kIPv6AddressSize: { |
715 if (addr_family_ != AF_INET6) | 739 if (addr_family_ != AF_INET6) |
716 return ERR_ADDRESS_INVALID; | 740 return ERR_ADDRESS_INVALID; |
717 ipv6_mreq mreq; | 741 ipv6_mreq mreq; |
718 mreq.ipv6mr_interface = 0; // 0 indicates default multicast interface. | 742 mreq.ipv6mr_interface = multicast_interface_; |
719 memcpy(&mreq.ipv6mr_multiaddr, &group_address[0], kIPv6AddressSize); | 743 memcpy(&mreq.ipv6mr_multiaddr, &group_address[0], kIPv6AddressSize); |
720 int rv = setsockopt(socket_, IPPROTO_IPV6, IP_DROP_MEMBERSHIP, | 744 int rv = setsockopt(socket_, IPPROTO_IPV6, IP_DROP_MEMBERSHIP, |
721 reinterpret_cast<const char*>(&mreq), | 745 reinterpret_cast<const char*>(&mreq), sizeof(mreq)); |
722 sizeof(mreq)); | |
723 if (rv) | 746 if (rv) |
724 return MapSystemError(WSAGetLastError()); | 747 return MapSystemError(WSAGetLastError()); |
725 return OK; | 748 return OK; |
726 } | 749 } |
727 default: | 750 default: |
728 NOTREACHED() << "Invalid address family"; | 751 NOTREACHED() << "Invalid address family"; |
729 return ERR_ADDRESS_INVALID; | 752 return ERR_ADDRESS_INVALID; |
730 } | 753 } |
731 } | 754 } |
732 | 755 |
| 756 int UDPSocketWin::SetMulticastInterface(uint32 interface_index) { |
| 757 DCHECK(CalledOnValidThread()); |
| 758 if (is_connected()) |
| 759 return ERR_SOCKET_IS_CONNECTED; |
| 760 multicast_interface_ = interface_index; |
| 761 return OK; |
| 762 } |
| 763 |
733 int UDPSocketWin::SetMulticastTimeToLive(int time_to_live) { | 764 int UDPSocketWin::SetMulticastTimeToLive(int time_to_live) { |
734 DCHECK(CalledOnValidThread()); | 765 DCHECK(CalledOnValidThread()); |
735 if (is_connected()) | 766 if (is_connected()) |
736 return ERR_SOCKET_IS_CONNECTED; | 767 return ERR_SOCKET_IS_CONNECTED; |
737 | 768 |
738 if (time_to_live < 0 || time_to_live > 255) | 769 if (time_to_live < 0 || time_to_live > 255) |
739 return ERR_INVALID_ARGUMENT; | 770 return ERR_INVALID_ARGUMENT; |
740 multicast_time_to_live_ = time_to_live; | 771 multicast_time_to_live_ = time_to_live; |
741 return OK; | 772 return OK; |
742 } | 773 } |
(...skipping 10 matching lines...) Expand all Loading... |
753 return OK; | 784 return OK; |
754 } | 785 } |
755 | 786 |
756 // TODO(hubbe): Implement differentiated services for windows. | 787 // TODO(hubbe): Implement differentiated services for windows. |
757 // Note: setsockopt(IP_TOS) does not work on windows XP and later. | 788 // Note: setsockopt(IP_TOS) does not work on windows XP and later. |
758 int UDPSocketWin::SetDiffServCodePoint(DiffServCodePoint dscp) { | 789 int UDPSocketWin::SetDiffServCodePoint(DiffServCodePoint dscp) { |
759 return ERR_NOT_IMPLEMENTED; | 790 return ERR_NOT_IMPLEMENTED; |
760 } | 791 } |
761 | 792 |
762 } // namespace net | 793 } // namespace net |
OLD | NEW |