-
Notifications
You must be signed in to change notification settings - Fork 3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[multicast_dns] Optimized Socket Binding: Always bind to 0.0.0.0 for simplicity and efficiency - #79772 #6700
Conversation
…r Simplicity and Efficiency
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apologies for the delay reviewing this.
@vashworth kindly tested this out against the flutter
CLI and confirmed it didn't break wireless debugging for flutter run
or flutter attach
.
This change generally LGTM, though I would like a second opinion from @cbracken who might remember more about why the original code was written that way.
- This needs a pubspec version bump and CHANGELOG update. See https://github.com/flutter/flutter/blob/master/docs/ecosystem/contributing/README.md#version-and-changelog-updates
- Can you add a test to https://github.com/flutter/packages/blob/main/packages/multicast_dns/test/client_test.dart?
Taking a look! |
I did a bit of exploratory The existing code was derived from the (long-dead, now) Dartino code and was added in It's derived from older Dartino code from the Dart SDK. The most recent version of that can be viewed here: The Dartino mdns package was originally added in this commit: Looking at the actual logic in the context of the rest of the code now. |
Thanks for sending the patch. Thinking about this a bit, I agree that setting up a single socket on 0.0.0.0 should be sufficient for listening on all network interfaces. As you note, for sending, we'll rely on the operating system's routing to determine which network interface is used for sending. That all seems fine. The current package doesn't really allow for interface-specific tuning/filtering so I don't think we're losing anything here and the code and resource management is significantly simpler. @sgjesse wrote the original code and while he's moved on to other projects, may have thoughts. :) The existing tests should cover the majority of the behaviour here, but as @jmagman says, please add a test that verifies the change in behaviour. If you check the existing tests, you can see how to use the You could probably write a test where the
then verify that the counter is == 1 and that the only targetAddress passed in was |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks good modulo comments + as @jmagman says, please add a test (suggestion above).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall this looks great for IPv4. We'll want to either document the removal of IPv6 support (if the previous code didn't exist) or add it back (if it did).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a drive by comment; thanks for looking into this problem! First observation: In the wireshark captures:
Are there any other clients listening on your system (e.g. avahi)? For direct-unicode messages, I believe it is OK to use a random listening port. Your first attempt looked fine. I believe this falls under 5.1 for one-shot multicast DNS queries and specifically called out:
Let me dig a little deeper? |
OK, yes: In the class description:
Which that section specifically states:
We are not in compliance with this and the port should be random. |
Thanks for looking into it @jtmcdole. The class states that it's "one shot" but it has never been so since the port is always 5353. I don't feel this should be changed in this PR (I would rather add the option to be "one shot" mode and keep as default what we have now 🤷♂️ ). Note: could you please point me to the comment where I state that 0.0.0.0 is a multicast address? It's an old PR 😅 |
caveat emptor: I'm not an mdns expert.
I missed the What's interesting and might just be a quirk of the mdns server - we get non-multicast responses back in your wireshark logs. Or maybe wireshark is just not showing the destination multicast address on received packets (I'm also not a wireshark expert)?
Sounds good to me. the rest of the PR is LGTM.
A misreading of your description and our documentation. |
…0.0 for simplicity and efficiency - flutter#79772 (flutter/packages#6700)
flutter/packages@711b4ac...03f5f6d 2024-06-24 stuartmorgan@google.com [interactive_media_ads] Fix README badge image URL (flutter/packages#6979) 2024-06-24 36191829+biagiopietro@users.noreply.github.com [multicast_dns] Optimized Socket Binding: Always bind to 0.0.0.0 for simplicity and efficiency - #79772 (flutter/packages#6700) 2024-06-24 92950982+oravecz-jpmc@users.noreply.github.com [flutter_adaptive_scaffold] Allows for the animation duration to be adjusted using SlotLayout.from() (flutter/packages#6510) 2024-06-22 louisehsu@google.com [in_app_purchase_storekit] Remove OCMock (flutter/packages#6862) 2024-06-22 stuartmorgan@google.com [google_maps_flutter] Add iOS SDK 9.x support (flutter/packages#6902) 2024-06-21 stuartmorgan@google.com [google_maps_flutter] Partial Android host API Pigeon conversion (flutter/packages#6967) 2024-06-21 github@alexv525.com Revert "Migrate `camera/android` from `SurfaceTexture`->`SurfaceProducer`." (flutter/packages#6964) 2024-06-21 stuartmorgan@google.com [quick_actions] Update to Pigeon 20 (flutter/packages#6961) 2024-06-20 stuartmorgan@google.com [google_maps_flutter] Move Android inspector to Pigeon (flutter/packages#6958) 2024-06-20 engine-flutter-autoroll@skia.org Manual roll Flutter from ccf3abe to 6c06abb (21 revisions) (flutter/packages#6954) 2024-06-20 34871572+gmackall@users.noreply.github.com [many] More v1 embedding deletion that was missed in flutter/packages#6494 (flutter/packages#6923) 2024-06-20 joonas.kerttula@codemate.com [google_maps_flutter] deprecate old BitmapDescriptor methods (flutter/packages#6905) 2024-06-18 magder@google.com [pigeon] Fully-qualify types in Equatable extension test (flutter/packages#6946) 2024-06-18 jimmyxx@gmail.com [flutter_markdown] fixes null check operator used on null value if onSelectionChanged is� (flutter/packages#6883) 2024-06-17 engine-flutter-autoroll@skia.org Roll Flutter from 5187cab to ccf3abe (6 revisions) (flutter/packages#6940) 2024-06-17 50375243+Jerinji2016@users.noreply.github.com [google_sign_in_web] README.md typo (flutter/packages#6642) 2024-06-17 49699333+dependabot[bot]@users.noreply.github.com [camera]: Bump com.google.guava:guava from 32.0.1-android to 33.2.1-android and CameraX version to 1.3.4 in /packages/camera/camera_android_camerax/android (flutter/packages#6847) 2024-06-17 49699333+dependabot[bot]@users.noreply.github.com [sign_in]: Bump com.google.guava:guava from 32.0.1-android to 33.2.1-android in /packages/google_sign_in/google_sign_in_android/android (flutter/packages#6846) 2024-06-17 49699333+dependabot[bot]@users.noreply.github.com [quick_actions]: Bump com.android.tools.build:gradle from 7.2.1 to 8.4.1 in /packages/quick_actions/quick_actions_android/android (flutter/packages#6799) 2024-06-17 49699333+dependabot[bot]@users.noreply.github.com [path_provider]: Bump androidx.annotation:annotation from 1.7.1 to 1.8.0 in /packages/path_provider/path_provider_android/android (flutter/packages#6773) 2024-06-17 49699333+dependabot[bot]@users.noreply.github.com [camera]: Bump androidx.annotation:annotation from 1.7.1 to 1.8.0 in /packages/camera/camera_android/android (flutter/packages#6766) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-packages-flutter-autoroll Please CC flutter-ecosystem@google.com,rmistry@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
I encountered this package long time ago (see linked issue below) and there were cases where it wasn't working.
After 3 years (yeah it's more time than expected) I managed to find the time to dust off
wireshark
and have look again.Preamble
Considering the following setup
Where Raspberry pi runs a
mDNS
service using the followinggo
:main.go
Considering the following client (which I got from here):
client.dart
What happens
When running the client script (
dart run client.dart
so with the latest package ofmulticast_dns
package) as is, a list of sockets is created which are bind to port5353
andIP
s:0.0.0.0
;127.0.0.1
;192.168.2.16
;172.17.0.1
;a list of interfaces (see list below) are joined to the multicast socket which is bound to
0.0.0.0:5353
:lo
(with address127.0.0.1
);wlan0
(with address192.168.2.16
);docker0
(with address172.17.0.1
).and eventually when
lookup
function is being calledQM
queries are being sent fromALL
the sockets in the list; which means that for0.0.0.0
theIP
address chosen by the operating system will depend on various factors such as the routing table, the default network interface, and the specific configuration of the network interfaces on the machine. It could be sent from any of theIP
addresses associated with the machine's network interfaces, includingIP
addresses assigned to physical network adapters or virtual interfaces.Using
Wireshark
, I can see that 2QM
packets are being sent and I can see thatmDNS
service is responding to the client with proper packet but it seems that the socket opened at0.0.0.0:5353
is not reading them at all even though the socket is still open.First approach (not sure if it's RFC 6762 friendly)
I had the "feeling" that sending
QM
packets to0.0.0.0:5353
and other interfaces on the same port would generate some sort of unexpected behavior due to the nature of0.0.0.0
whichIP
selections depends on multiple factors.Therefore I tried initially to change the
incoming
socket (the one bound to0.0.0.0
) from:to
which essentially delegates to
OS
to choose a random port (instead of forcing5353
).In this case the client managed to process correctly all the packages for discovering the
mDNS
service, indeed inWireshark
I could see:and on the client I could see the message:
RFC 6762
friendly, I checked some packages which implementmDNS
clients and I saw some of them doing what I proposed. I would like to hear comments about it.Second approach (which it's what is presented in this PR)
After trying the first approach I realized that maybe there is no need to open sockets on more interfaces (and therefore send
QM
messages) it maybe be enough to send and listen only on a socket bound to0.0.0.0
since, again, listen on ANYIP
and send packets from a selectedIP
address chosen by theOS
.Also in this case the client managed to process correctly all the packages for discovering the
mDNS
service, indeed inWireshark
I could see:and on the client I could see the message:
Third approach (It did not work but mentioning for completeness)
The idea here is to don't send
QM
packets via0.0.0.0
but just listen on possible response/s since packets would be send via the followingIP
s and0.0.0.0
should represent ANYIP
.127.0.0.1
;192.168.2.16
;172.17.0.1
.Fourth approach (It did not work but mentioning for completeness)
Another solution that I tried but unfortunately it did not work, was to put
0.0.0.0
as last item in the socket list soQM
packets would be sent according to the following order:127.0.0.1
;192.168.2.16
;172.17.0.1
;0.0.0.0
.multicast_dns.start() function
The idea is indeed to let the first 3
IP
s to send theQM
packets which response should be hopefully captured by theincoming
socket before the socket on0.0.0.0
would send theQM
packet too.Wireshark filter
Related Issue
Disclaimers
flutter
/dart
, I pulled the code and I tried to debug it with help of unclegoogle
andprint()
;Wireshark
, inspect the networks and craft packets.Pre-launch Checklist
dart format
.)[shared_preferences]
pubspec.yaml
with an appropriate new version according to the pub versioning philosophy, or this PR is exempt from version changes.CHANGELOG.md
to add a description of the change, following repository CHANGELOG style.///
).If you need help, consider asking for advice on the #hackers-new channel on Discord.