| 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 21 matching lines...) Expand all Loading... |
| 656 const IPAddressNumber& group_address) const { | 683 const IPAddressNumber& group_address) const { |
| 657 DCHECK(CalledOnValidThread()); | 684 DCHECK(CalledOnValidThread()); |
| 658 if (!is_connected()) | 685 if (!is_connected()) |
| 659 return ERR_SOCKET_NOT_CONNECTED; | 686 return ERR_SOCKET_NOT_CONNECTED; |
| 660 | 687 |
| 661 switch (group_address.size()) { | 688 switch (group_address.size()) { |
| 662 case kIPv4AddressSize: { | 689 case kIPv4AddressSize: { |
| 663 if (addr_family_ != AF_INET) | 690 if (addr_family_ != AF_INET) |
| 664 return ERR_ADDRESS_INVALID; | 691 return ERR_ADDRESS_INVALID; |
| 665 ip_mreq mreq; | 692 ip_mreq mreq; |
| 666 mreq.imr_interface.s_addr = INADDR_ANY; | 693 mreq.imr_interface.s_addr = htonl(multicast_interface_); |
| 667 memcpy(&mreq.imr_multiaddr, &group_address[0], kIPv4AddressSize); | 694 memcpy(&mreq.imr_multiaddr, &group_address[0], kIPv4AddressSize); |
| 668 int rv = setsockopt(socket_, IPPROTO_IP, IP_ADD_MEMBERSHIP, | 695 int rv = setsockopt(socket_, IPPROTO_IP, IP_ADD_MEMBERSHIP, |
| 669 reinterpret_cast<const char*>(&mreq), | 696 reinterpret_cast<const char*>(&mreq), |
| 670 sizeof(mreq)); | 697 sizeof(mreq)); |
| 671 if (rv) | 698 if (rv) |
| 672 return MapSystemError(WSAGetLastError()); | 699 return MapSystemError(WSAGetLastError()); |
| 673 return OK; | 700 return OK; |
| 674 } | 701 } |
| 675 case kIPv6AddressSize: { | 702 case kIPv6AddressSize: { |
| 676 if (addr_family_ != AF_INET6) | 703 if (addr_family_ != AF_INET6) |
| 677 return ERR_ADDRESS_INVALID; | 704 return ERR_ADDRESS_INVALID; |
| 678 ipv6_mreq mreq; | 705 ipv6_mreq mreq; |
| 679 mreq.ipv6mr_interface = 0; // 0 indicates default multicast interface. | 706 mreq.ipv6mr_interface = multicast_interface_; |
| 680 memcpy(&mreq.ipv6mr_multiaddr, &group_address[0], kIPv6AddressSize); | 707 memcpy(&mreq.ipv6mr_multiaddr, &group_address[0], kIPv6AddressSize); |
| 681 int rv = setsockopt(socket_, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, | 708 int rv = setsockopt(socket_, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, |
| 682 reinterpret_cast<const char*>(&mreq), | 709 reinterpret_cast<const char*>(&mreq), |
| 683 sizeof(mreq)); | 710 sizeof(mreq)); |
| 684 if (rv) | 711 if (rv) |
| 685 return MapSystemError(WSAGetLastError()); | 712 return MapSystemError(WSAGetLastError()); |
| 686 return OK; | 713 return OK; |
| 687 } | 714 } |
| 688 default: | 715 default: |
| 689 NOTREACHED() << "Invalid address family"; | 716 NOTREACHED() << "Invalid address family"; |
| 690 return ERR_ADDRESS_INVALID; | 717 return ERR_ADDRESS_INVALID; |
| 691 } | 718 } |
| 692 } | 719 } |
| 693 | 720 |
| 694 int UDPSocketWin::LeaveGroup( | 721 int UDPSocketWin::LeaveGroup( |
| 695 const IPAddressNumber& group_address) const { | 722 const IPAddressNumber& group_address) const { |
| 696 DCHECK(CalledOnValidThread()); | 723 DCHECK(CalledOnValidThread()); |
| 697 if (!is_connected()) | 724 if (!is_connected()) |
| 698 return ERR_SOCKET_NOT_CONNECTED; | 725 return ERR_SOCKET_NOT_CONNECTED; |
| 699 | 726 |
| 700 switch (group_address.size()) { | 727 switch (group_address.size()) { |
| 701 case kIPv4AddressSize: { | 728 case kIPv4AddressSize: { |
| 702 if (addr_family_ != AF_INET) | 729 if (addr_family_ != AF_INET) |
| 703 return ERR_ADDRESS_INVALID; | 730 return ERR_ADDRESS_INVALID; |
| 704 ip_mreq mreq; | 731 ip_mreq mreq; |
| 705 mreq.imr_interface.s_addr = INADDR_ANY; | 732 mreq.imr_interface.s_addr = htonl(multicast_interface_); |
| 706 memcpy(&mreq.imr_multiaddr, &group_address[0], kIPv4AddressSize); | 733 memcpy(&mreq.imr_multiaddr, &group_address[0], kIPv4AddressSize); |
| 707 int rv = setsockopt(socket_, IPPROTO_IP, IP_DROP_MEMBERSHIP, | 734 int rv = setsockopt(socket_, IPPROTO_IP, IP_DROP_MEMBERSHIP, |
| 708 reinterpret_cast<const char*>(&mreq), | 735 reinterpret_cast<const char*>(&mreq), sizeof(mreq)); |
| 709 sizeof(mreq)); | |
| 710 if (rv) | 736 if (rv) |
| 711 return MapSystemError(WSAGetLastError()); | 737 return MapSystemError(WSAGetLastError()); |
| 712 return OK; | 738 return OK; |
| 713 } | 739 } |
| 714 case kIPv6AddressSize: { | 740 case kIPv6AddressSize: { |
| 715 if (addr_family_ != AF_INET6) | 741 if (addr_family_ != AF_INET6) |
| 716 return ERR_ADDRESS_INVALID; | 742 return ERR_ADDRESS_INVALID; |
| 717 ipv6_mreq mreq; | 743 ipv6_mreq mreq; |
| 718 mreq.ipv6mr_interface = 0; // 0 indicates default multicast interface. | 744 mreq.ipv6mr_interface = multicast_interface_; |
| 719 memcpy(&mreq.ipv6mr_multiaddr, &group_address[0], kIPv6AddressSize); | 745 memcpy(&mreq.ipv6mr_multiaddr, &group_address[0], kIPv6AddressSize); |
| 720 int rv = setsockopt(socket_, IPPROTO_IPV6, IP_DROP_MEMBERSHIP, | 746 int rv = setsockopt(socket_, IPPROTO_IPV6, IP_DROP_MEMBERSHIP, |
| 721 reinterpret_cast<const char*>(&mreq), | 747 reinterpret_cast<const char*>(&mreq), sizeof(mreq)); |
| 722 sizeof(mreq)); | |
| 723 if (rv) | 748 if (rv) |
| 724 return MapSystemError(WSAGetLastError()); | 749 return MapSystemError(WSAGetLastError()); |
| 725 return OK; | 750 return OK; |
| 726 } | 751 } |
| 727 default: | 752 default: |
| 728 NOTREACHED() << "Invalid address family"; | 753 NOTREACHED() << "Invalid address family"; |
| 729 return ERR_ADDRESS_INVALID; | 754 return ERR_ADDRESS_INVALID; |
| 730 } | 755 } |
| 731 } | 756 } |
| 732 | 757 |
| 758 int UDPSocketWin::SetMulticastInterface(uint32 interface_index) { |
| 759 DCHECK(CalledOnValidThread()); |
| 760 if (is_connected()) |
| 761 return ERR_SOCKET_IS_CONNECTED; |
| 762 multicast_interface_ = interface_index; |
| 763 return OK; |
| 764 } |
| 765 |
| 733 int UDPSocketWin::SetMulticastTimeToLive(int time_to_live) { | 766 int UDPSocketWin::SetMulticastTimeToLive(int time_to_live) { |
| 734 DCHECK(CalledOnValidThread()); | 767 DCHECK(CalledOnValidThread()); |
| 735 if (is_connected()) | 768 if (is_connected()) |
| 736 return ERR_SOCKET_IS_CONNECTED; | 769 return ERR_SOCKET_IS_CONNECTED; |
| 737 | 770 |
| 738 if (time_to_live < 0 || time_to_live > 255) | 771 if (time_to_live < 0 || time_to_live > 255) |
| 739 return ERR_INVALID_ARGUMENT; | 772 return ERR_INVALID_ARGUMENT; |
| 740 multicast_time_to_live_ = time_to_live; | 773 multicast_time_to_live_ = time_to_live; |
| 741 return OK; | 774 return OK; |
| 742 } | 775 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 753 return OK; | 786 return OK; |
| 754 } | 787 } |
| 755 | 788 |
| 756 // TODO(hubbe): Implement differentiated services for windows. | 789 // TODO(hubbe): Implement differentiated services for windows. |
| 757 // Note: setsockopt(IP_TOS) does not work on windows XP and later. | 790 // Note: setsockopt(IP_TOS) does not work on windows XP and later. |
| 758 int UDPSocketWin::SetDiffServCodePoint(DiffServCodePoint dscp) { | 791 int UDPSocketWin::SetDiffServCodePoint(DiffServCodePoint dscp) { |
| 759 return ERR_NOT_IMPLEMENTED; | 792 return ERR_NOT_IMPLEMENTED; |
| 760 } | 793 } |
| 761 | 794 |
| 762 } // namespace net | 795 } // namespace net |
| OLD | NEW |