New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 899310 link

Starred by 1 user

Issue metadata

Status: Assigned
Owner:
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: ----
Pri: 3
Type: Bug

Blocking:
issue 905422



Sign in to add a comment

multicast messages not always shared

Project Member Reported by ericorth@chromium.org, Oct 26

Issue description

Reported by qingsi@chromium.org while working on MDNS responder support:
"mDNS packets are not received by all sockets joined the group. I found the packets are always received by the mDNS sockets of the service discovery client, not the ones of the mDNS client created by the mDNS task. I had to comment out the service discovery client to allow the mDNS task to receive a packet. It looks like we have some issue in the existing mDNS socket infra to configure reusable address, or there may be a platform problem."

Later confirmed his test environment to be Linux.  From the description, determined that the MDNS packets were not being sent to all the sockets attempting to listen for them.  This is the typical behavior for sockets where there's a single handler processing some particular endpoint and anybody else listening in is a security issue.  But in multicast, where packets are sent to any machine that wants them, it naturally makes more sense for multiple sockets and processes on the machine to listen for and get the same messages.

Summary of conclusion after research:
We should set SO_REUSEPORT for multicast sockets whenever able, and non-Windows multicast sockets should bind to the multicast group address.

Research notes:
Windows documentation on the topic is pretty clear (https://docs.microsoft.com/en-us/windows/desktop/winsock/using-so-reuseaddr-and-so-exclusiveaddruse): Sockets can bind for the same endpoint if they set SO_REUSEADDR, and while that doesn't normally let them get all messages, they do if they have joined the same multicast group.  This matched the current implementation.

Non-windows had no good singular, citable documentation on the topic.  Other platforms sometimes (but not always) have an SO_REUSEPORT option that generally allows messages to be sent to all the sockets (not a multicast specific feature).  Some documentation/tutorials/stackoverflows (nothing really definitive that I could find) says this should be set for multicast sockets, others conflictingly say SO_REUSEADDR implies SO_REUSEPORT for multicast.  The definition of what makes the socket "for multicast" to get the behavior also varies by reference, sometimes saying messages arriving on the machine via multicast get shared thusly, sometimes sockets joining multicast groups (similar to the Windows behavior), sometimes saying sockets bound to multicast addresses.  Lots of confusion and variation between platforms.  Since SO_REUSEPORT will either do what we want, be unnecessary but not bad, or not exist at all, setting it for multicast sockets whenever it exists seems to be strictly better than our current implementation and give us the highest chance on any platform of multicast messages being shared.

A similar researched topic is what address should be used for the socket bind: a wildcard (0.0.0.0) as was the current implementation, or the multicast address (e.g. 224.0.0.251 for MDNS).  Lots of documentation/tutorials/stackoverflows (again, nothing really definitive or singularly citable), especially referring to non-Windows platforms, indicate that joining multicast groups is more of a system-wide thing and that any sockets could then get multicast messages for any group joined by any socket on the system rather than just messages for the group that specific socket joined.  The way to filter for just the specific group is to bind the socket to that group address.  So, combined with the potential that binding to a multicast address may make the platform more likely to share multicast messages (see paragraph above), we should be binding to the specific multicast group address rather than the wildcard.

But Windows does not allow binding a socket to multicast addresses (experimentally confirmed it always returns WSAEADDRNOTAVAIL), and no references clearly in the context of Windows mention this system-wide behavior of multicast group joining, especially not Microsoft's documentation.  Everything I see implies that it works as one would expect: only sending multicast messages to sockets that have joined the relevant group.  So, for Windows, we should keep binding to the 0.0.0.0 wildcard address.
 
Project Member

Comment 1 by bugdroid1@chromium.org, Oct 26

The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/7141dbc7873981fe3a62054da50030afaefc05aa

commit 7141dbc7873981fe3a62054da50030afaefc05aa
Author: Eric Orth <ericorth@chromium.org>
Date: Fri Oct 26 20:10:24 2018

Better setup for non-windows multicast sockets.

In addition to SO_REUSEADDR, that we were setting before, via
AllowAddressReuse(), for sockets for use with multicast, now also set
SO_REUSEPORT whenever that option is defined. On some non-Windows
platforms, this is needed for multicast messages to be received by all
sockets listening for them. This option is only set in a new
AllowAddressSharingForMulticast() method as the SO_REUSEADDR and
AllowAddressReuse() have other non-multicast uses where SO_REUSEPORT
would not be appropriate.

Also, for non-Windows platforms, bind the multicast sockets to the
multicast group address rather than to a wildcard. This will make us
more likely to only get messages from the relevant multicast group as
some platforms will otherwise give the socket any multicast messages
from groups joined by any sockets in the system. No change on Windows
where binding to a multicast group is not allowed.

TBR=thestig@chromium.org

Change-Id: I24d9d4a0d85134074b2deb14914a41109d7f724a
Bug: 899310
Reviewed-on: https://chromium-review.googlesource.com/c/1298298
Commit-Queue: Eric Orth <ericorth@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
Reviewed-by: Matt Menke <mmenke@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Cr-Commit-Position: refs/heads/master@{#603180}
[modify] https://crrev.com/7141dbc7873981fe3a62054da50030afaefc05aa/chrome/browser/printing/cloud_print/privet_traffic_detector.cc
[modify] https://crrev.com/7141dbc7873981fe3a62054da50030afaefc05aa/net/dns/mdns_client.cc
[modify] https://crrev.com/7141dbc7873981fe3a62054da50030afaefc05aa/net/dns/mdns_client.h
[modify] https://crrev.com/7141dbc7873981fe3a62054da50030afaefc05aa/net/dns/mdns_client_impl.cc
[modify] https://crrev.com/7141dbc7873981fe3a62054da50030afaefc05aa/net/dns/mock_mdns_socket_factory.cc
[modify] https://crrev.com/7141dbc7873981fe3a62054da50030afaefc05aa/net/dns/mock_mdns_socket_factory.h
[modify] https://crrev.com/7141dbc7873981fe3a62054da50030afaefc05aa/net/socket/datagram_server_socket.h
[modify] https://crrev.com/7141dbc7873981fe3a62054da50030afaefc05aa/net/socket/udp_server_socket.cc
[modify] https://crrev.com/7141dbc7873981fe3a62054da50030afaefc05aa/net/socket/udp_server_socket.h
[modify] https://crrev.com/7141dbc7873981fe3a62054da50030afaefc05aa/net/socket/udp_socket_posix.cc
[modify] https://crrev.com/7141dbc7873981fe3a62054da50030afaefc05aa/net/socket/udp_socket_posix.h
[modify] https://crrev.com/7141dbc7873981fe3a62054da50030afaefc05aa/net/socket/udp_socket_unittest.cc
[modify] https://crrev.com/7141dbc7873981fe3a62054da50030afaefc05aa/net/socket/udp_socket_win.cc
[modify] https://crrev.com/7141dbc7873981fe3a62054da50030afaefc05aa/net/socket/udp_socket_win.h
[modify] https://crrev.com/7141dbc7873981fe3a62054da50030afaefc05aa/services/network/p2p/socket_udp_unittest.cc
[modify] https://crrev.com/7141dbc7873981fe3a62054da50030afaefc05aa/services/network/public/mojom/udp_socket.mojom
[modify] https://crrev.com/7141dbc7873981fe3a62054da50030afaefc05aa/services/network/udp_socket.cc
[modify] https://crrev.com/7141dbc7873981fe3a62054da50030afaefc05aa/services/network/udp_socket_unittest.cc

Status: Fixed (was: Started)
Cc: zstein@chromium.org emadomara@chromium.org jeroendb@chromium.org
Status: Assigned (was: Fixed)
Reopening.  qingsi@ reported some issues on OSX with *sending* multicast messages through a socket bound to the multicast address (vs things working fine if the socket is bound to the wildcard address).  Theories are that the OS is getting too smart with filtering out messages sent to an address the socket is also listening on, or something is up with the multicast loop functionality (that should be enabled by default).

We're experimenting with it.  Worst-case, I think our MDNS code could use a separate socket for sending that could just be a simple unbound UDPClientSocket.  Quite reasonable in MDNS where queries and responses are deliberately not tightly coupled.  Prefer not to just change the bound address to improve sending since we changed that to improve receiving.
Blocking: 905422
Project Member

Comment 6 by bugdroid1@chromium.org, Jan 11

The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/eb994032b05b9c3093c681e0d13b74739b552001

commit eb994032b05b9c3093c681e0d13b74739b552001
Author: Qingsi Wang <qingsi@google.com>
Date: Fri Jan 11 02:36:14 2019

Add SetMulticastInterface to DatagramClientSocket.

Bug: 899310
Change-Id: Ia3290e2d2506907704ea0d8cac3cd2674eccd812
Reviewed-on: https://chromium-review.googlesource.com/c/1392601
Reviewed-by: Eric Orth <ericorth@chromium.org>
Commit-Queue: Qingsi Wang <qingsi@google.com>
Cr-Commit-Position: refs/heads/master@{#621876}
[modify] https://crrev.com/eb994032b05b9c3093c681e0d13b74739b552001/net/dns/address_sorter_posix_unittest.cc
[modify] https://crrev.com/eb994032b05b9c3093c681e0d13b74739b552001/net/proxy_resolution/pac_library_unittest.cc
[modify] https://crrev.com/eb994032b05b9c3093c681e0d13b74739b552001/net/socket/datagram_client_socket.h
[modify] https://crrev.com/eb994032b05b9c3093c681e0d13b74739b552001/net/socket/fuzzed_datagram_client_socket.cc
[modify] https://crrev.com/eb994032b05b9c3093c681e0d13b74739b552001/net/socket/fuzzed_datagram_client_socket.h
[modify] https://crrev.com/eb994032b05b9c3093c681e0d13b74739b552001/net/socket/socket_test_util.cc
[modify] https://crrev.com/eb994032b05b9c3093c681e0d13b74739b552001/net/socket/socket_test_util.h
[modify] https://crrev.com/eb994032b05b9c3093c681e0d13b74739b552001/net/socket/udp_client_socket.cc
[modify] https://crrev.com/eb994032b05b9c3093c681e0d13b74739b552001/net/socket/udp_client_socket.h
[modify] https://crrev.com/eb994032b05b9c3093c681e0d13b74739b552001/net/socket/udp_socket_posix.cc
[modify] https://crrev.com/eb994032b05b9c3093c681e0d13b74739b552001/net/socket/udp_socket_win.cc

Sign in to add a comment