Chromium Code Reviews| Index: net/udp/udp_socket_libevent.cc |
| diff --git a/net/udp/udp_socket_libevent.cc b/net/udp/udp_socket_libevent.cc |
| index 990aa5758cca8f463ec0caf615432091a2847ac1..0ae12ebbe472e28222214b8458815c2d8a532bb9 100644 |
| --- a/net/udp/udp_socket_libevent.cc |
| +++ b/net/udp/udp_socket_libevent.cc |
| @@ -42,6 +42,7 @@ UDPSocketLibevent::UDPSocketLibevent( |
| : socket_(kInvalidSocket), |
| 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), |
| @@ -532,6 +533,32 @@ int UDPSocketLibevent::SetSocketOptions() { |
| if (rv < 0) |
| return MapSystemError(errno); |
| } |
| + if (multicast_interface_ != 0) { |
| + switch (addr_family_) { |
| + case AF_INET: { |
| + in_addr address; |
| + address.s_addr = htonl(multicast_interface_); |
|
Noam Samuel
2013/12/02 22:05:54
I know that the 0.x.x.x address convention for num
szym
2013/12/03 07:42:11
In Linux, IP_MULTICAST_IF option has to be one of:
|
| + int rv = setsockopt(socket_, IPPROTO_IP, IP_MULTICAST_IF, |
| + reinterpret_cast<const char*>(&address), |
| + sizeof(address)); |
| + if (rv) |
| + return MapSystemError(errno); |
| + 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(errno); |
| + break; |
| + } |
| + default: |
| + NOTREACHED() << "Invalid address family"; |
| + return ERR_ADDRESS_INVALID; |
| + } |
| + } |
| return OK; |
| } |
| @@ -557,7 +584,7 @@ int UDPSocketLibevent::RandomBind(const IPEndPoint& address) { |
| return DoBind(IPEndPoint(ip, 0)); |
| } |
| -int UDPSocketLibevent::JoinGroup(const IPAddressNumber& group_address) const { |
| +int UDPSocketLibevent::JoinGroup(const IPAddressNumber& group_address) { |
| DCHECK(CalledOnValidThread()); |
| if (!is_connected()) |
| return ERR_SOCKET_NOT_CONNECTED; |
| @@ -567,7 +594,7 @@ int UDPSocketLibevent::JoinGroup(const IPAddressNumber& group_address) const { |
| 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_); |
|
Noam Samuel
2013/12/02 22:05:54
Same question
|
| memcpy(&mreq.imr_multiaddr, &group_address[0], kIPv4AddressSize); |
| int rv = setsockopt(socket_, IPPROTO_IP, IP_ADD_MEMBERSHIP, |
| &mreq, sizeof(mreq)); |
| @@ -579,7 +606,7 @@ int UDPSocketLibevent::JoinGroup(const IPAddressNumber& group_address) const { |
| 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_JOIN_GROUP, |
| &mreq, sizeof(mreq)); |
| @@ -593,7 +620,7 @@ int UDPSocketLibevent::JoinGroup(const IPAddressNumber& group_address) const { |
| } |
| } |
| -int UDPSocketLibevent::LeaveGroup(const IPAddressNumber& group_address) const { |
| +int UDPSocketLibevent::LeaveGroup(const IPAddressNumber& group_address) { |
| DCHECK(CalledOnValidThread()); |
| if (!is_connected()) |
| @@ -630,6 +657,14 @@ int UDPSocketLibevent::LeaveGroup(const IPAddressNumber& group_address) const { |
| } |
| } |
| +int UDPSocketLibevent::SetMulticastInterface(uint32 interface_index) { |
| + DCHECK(CalledOnValidThread()); |
| + if (is_connected()) |
| + return ERR_SOCKET_IS_CONNECTED; |
| + multicast_interface_ = interface_index; |
| + return OK; |
| +} |
| + |
| int UDPSocketLibevent::SetMulticastTimeToLive(int time_to_live) { |
| DCHECK(CalledOnValidThread()); |
| if (is_connected()) |