| Index: net/udp/udp_socket_win.cc
|
| diff --git a/net/udp/udp_socket_win.cc b/net/udp/udp_socket_win.cc
|
| index c9f30a704d5527cb1da07af0e6b64ef5cf70c601..4dfdb50c162e9ce18688118aaf6d838ba77a46d6 100644
|
| --- a/net/udp/udp_socket_win.cc
|
| +++ b/net/udp/udp_socket_win.cc
|
| @@ -166,6 +166,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),
|
| @@ -622,6 +623,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;
|
| }
|
|
|
| @@ -652,8 +679,7 @@ bool UDPSocketWin::ReceiveAddressToIPEndpoint(IPEndPoint* address) const {
|
| return address->FromSockAddr(storage.addr, storage.addr_len);
|
| }
|
|
|
| -int UDPSocketWin::JoinGroup(
|
| - const IPAddressNumber& group_address) const {
|
| +int UDPSocketWin::JoinGroup(const IPAddressNumber& group_address) {
|
| DCHECK(CalledOnValidThread());
|
| if (!is_connected())
|
| return ERR_SOCKET_NOT_CONNECTED;
|
| @@ -663,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),
|
| @@ -676,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),
|
| @@ -691,8 +717,7 @@ int UDPSocketWin::JoinGroup(
|
| }
|
| }
|
|
|
| -int UDPSocketWin::LeaveGroup(
|
| - const IPAddressNumber& group_address) const {
|
| +int UDPSocketWin::LeaveGroup(const IPAddressNumber& group_address) {
|
| DCHECK(CalledOnValidThread());
|
| if (!is_connected())
|
| return ERR_SOCKET_NOT_CONNECTED;
|
| @@ -702,11 +727,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;
|
| @@ -715,11 +739,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;
|
| @@ -730,6 +753,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())
|
|
|