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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/udp/udp_socket_win.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/udp/udp_socket_win.cc
diff --git a/net/udp/udp_socket_win.cc b/net/udp/udp_socket_win.cc
index d2745b920c7406d747a784ba1b3a6a1a32c800cd..b4e4a4b76ed871b6dd30ee17ed0c7fe7eff02d61 100644
--- a/net/udp/udp_socket_win.cc
+++ b/net/udp/udp_socket_win.cc
@@ -165,6 +165,7 @@ UDPSocketWin::UDPSocketWin(DatagramSocket::BindType bind_type,
: socket_(INVALID_SOCKET),
addr_family_(0),
socket_options_(SOCKET_OPTION_MULTICAST_LOOP),
+ multicast_interface_(0),
multicast_time_to_live_(1),
bind_type_(bind_type),
rand_int_cb_(rand_int_cb),
@@ -621,6 +622,32 @@ int UDPSocketWin::SetSocketOptions() {
if (rv < 0)
return MapSystemError(WSAGetLastError());
}
+ if (multicast_interface_ != 0) {
+ switch (addr_family_) {
+ case AF_INET: {
+ in_addr address;
+ address.s_addr = htonl(multicast_interface_);
+ int rv = setsockopt(socket_, IPPROTO_IP, IP_MULTICAST_IF,
+ reinterpret_cast<const char*>(&address),
+ sizeof(address));
+ if (rv)
+ return MapSystemError(WSAGetLastError());
+ break;
+ }
+ case AF_INET6: {
+ uint32 interface_index = multicast_interface_;
+ int rv = setsockopt(socket_, IPPROTO_IPV6, IPV6_MULTICAST_IF,
+ reinterpret_cast<const char*>(&interface_index),
+ sizeof(interface_index));
+ if (rv)
+ return MapSystemError(WSAGetLastError());
+ break;
+ }
+ default:
+ NOTREACHED() << "Invalid address family";
+ return ERR_ADDRESS_INVALID;
+ }
+ }
return OK;
}
@@ -662,7 +689,7 @@ int UDPSocketWin::JoinGroup(
if (addr_family_ != AF_INET)
return ERR_ADDRESS_INVALID;
ip_mreq mreq;
- mreq.imr_interface.s_addr = INADDR_ANY;
+ mreq.imr_interface.s_addr = htonl(multicast_interface_);
memcpy(&mreq.imr_multiaddr, &group_address[0], kIPv4AddressSize);
int rv = setsockopt(socket_, IPPROTO_IP, IP_ADD_MEMBERSHIP,
reinterpret_cast<const char*>(&mreq),
@@ -675,7 +702,7 @@ int UDPSocketWin::JoinGroup(
if (addr_family_ != AF_INET6)
return ERR_ADDRESS_INVALID;
ipv6_mreq mreq;
- mreq.ipv6mr_interface = 0; // 0 indicates default multicast interface.
+ mreq.ipv6mr_interface = multicast_interface_;
memcpy(&mreq.ipv6mr_multiaddr, &group_address[0], kIPv6AddressSize);
int rv = setsockopt(socket_, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP,
reinterpret_cast<const char*>(&mreq),
@@ -701,11 +728,10 @@ int UDPSocketWin::LeaveGroup(
if (addr_family_ != AF_INET)
return ERR_ADDRESS_INVALID;
ip_mreq mreq;
- mreq.imr_interface.s_addr = INADDR_ANY;
+ mreq.imr_interface.s_addr = htonl(multicast_interface_);
memcpy(&mreq.imr_multiaddr, &group_address[0], kIPv4AddressSize);
int rv = setsockopt(socket_, IPPROTO_IP, IP_DROP_MEMBERSHIP,
- reinterpret_cast<const char*>(&mreq),
- sizeof(mreq));
+ reinterpret_cast<const char*>(&mreq), sizeof(mreq));
if (rv)
return MapSystemError(WSAGetLastError());
return OK;
@@ -714,11 +740,10 @@ int UDPSocketWin::LeaveGroup(
if (addr_family_ != AF_INET6)
return ERR_ADDRESS_INVALID;
ipv6_mreq mreq;
- mreq.ipv6mr_interface = 0; // 0 indicates default multicast interface.
+ mreq.ipv6mr_interface = multicast_interface_;
memcpy(&mreq.ipv6mr_multiaddr, &group_address[0], kIPv6AddressSize);
int rv = setsockopt(socket_, IPPROTO_IPV6, IP_DROP_MEMBERSHIP,
- reinterpret_cast<const char*>(&mreq),
- sizeof(mreq));
+ reinterpret_cast<const char*>(&mreq), sizeof(mreq));
if (rv)
return MapSystemError(WSAGetLastError());
return OK;
@@ -729,6 +754,14 @@ int UDPSocketWin::LeaveGroup(
}
}
+int UDPSocketWin::SetMulticastInterface(uint32 interface_index) {
+ DCHECK(CalledOnValidThread());
+ if (is_connected())
+ return ERR_SOCKET_IS_CONNECTED;
+ multicast_interface_ = interface_index;
+ return OK;
+}
+
int UDPSocketWin::SetMulticastTimeToLive(int time_to_live) {
DCHECK(CalledOnValidThread());
if (is_connected())
« 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