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

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

Issue 99923004: Add support of IP_MULTICAST_IF in UDP sockets. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years 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 | Annotate | Revision Log
« net/udp/udp_socket_libevent.cc ('K') | « 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/logging.h" 10 #include "base/logging.h"
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
OLDNEW
« net/udp/udp_socket_libevent.cc ('K') | « net/udp/udp_socket_win.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698