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

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