Skip to content
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

Merged
merged 49 commits into from
Jun 24, 2024
Merged
Show file tree
Hide file tree
Changes from 38 commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
e3a5c16
[multicast_mdns] Optimized Socket Binding: Consolidated to 0.0.0.0 fo…
biagiopietro May 5, 2024
e2bccfd
Merge branch 'main' into fix-issue-79772
biagiopietro May 9, 2024
852a12d
Updated CHANGELOG.md and README.md
biagiopietro May 9, 2024
f5bbe17
Removed unused variable
biagiopietro May 9, 2024
a14f499
Merge branch 'main' into fix-issue-79772
biagiopietro May 9, 2024
f5b0c20
Merge branch 'main' into fix-issue-79772
biagiopietro May 10, 2024
df9d229
Merge branch 'main' into fix-issue-79772
biagiopietro May 11, 2024
2b41f9c
Merge branch 'main' into fix-issue-79772
biagiopietro May 12, 2024
b685e5b
Merge branch 'main' into fix-issue-79772
biagiopietro May 13, 2024
b3d76a4
Merge branch 'main' into fix-issue-79772
biagiopietro May 14, 2024
7ff9e1c
Merge branch 'main' into fix-issue-79772
biagiopietro May 15, 2024
5c22f0e
Merge branch 'main' into fix-issue-79772
biagiopietro May 15, 2024
267a64a
Merge branch 'main' into fix-issue-79772
biagiopietro May 18, 2024
e9e41e0
Merge branch 'main' into fix-issue-79772
biagiopietro May 20, 2024
462bc23
Merge branch 'main' into fix-issue-79772
biagiopietro May 22, 2024
9fe010a
Merge branch 'main' into fix-issue-79772
biagiopietro May 24, 2024
5654760
Applied feedback from review pt.1 : CHANGELOG.md updated
biagiopietro May 24, 2024
2f693bc
Applied feedback from review pt.1 : removed socket list and updated a…
biagiopietro May 24, 2024
93a5fbc
Merge branch 'main' into fix-issue-79772
biagiopietro May 24, 2024
23ae0ae
Removed not needed comment in tests
biagiopietro May 24, 2024
3efedad
Applied feedback from review pt.2: set _incomingIPv4 and _incomingIPv…
biagiopietro May 24, 2024
1feeb9e
Updated client_test.dart
biagiopietro May 25, 2024
671fe2e
Merge branch 'main' into fix-issue-79772
biagiopietro May 25, 2024
35a4890
Merge branch 'main' into fix-issue-79772
biagiopietro May 26, 2024
fa0a12a
Merge branch 'main' into fix-issue-79772
biagiopietro May 28, 2024
0baf961
Merge branch 'main' into fix-issue-79772
biagiopietro May 28, 2024
67d6cc9
Run fluttter_flugin_tools
biagiopietro May 28, 2024
96eb7b5
Merge branch 'main' into fix-issue-79772
biagiopietro May 28, 2024
3375a29
Updated client_test.dart because some checks are failing
biagiopietro May 28, 2024
a97962e
Make checks again green
biagiopietro May 28, 2024
f26409a
Merge branch 'main' into fix-issue-79772
biagiopietro May 29, 2024
7bfdba0
Removed unnecessary check
biagiopietro May 29, 2024
6d5ccff
Merge branch 'main' into fix-issue-79772
biagiopietro May 30, 2024
745ec4c
Merge branch 'main' into fix-issue-79772
biagiopietro Jun 2, 2024
1e2af46
Merge branch 'main' into fix-issue-79772
biagiopietro Jun 4, 2024
650b3f3
Merge branch 'main' into fix-issue-79772
biagiopietro Jun 4, 2024
a620c52
Merge branch 'main' into fix-issue-79772
biagiopietro Jun 5, 2024
c095cad
Merge branch 'main' into fix-issue-79772
biagiopietro Jun 5, 2024
9ffd63a
Merge branch 'main' into fix-issue-79772
biagiopietro Jun 5, 2024
c7da559
Merge branch 'main' into fix-issue-79772
biagiopietro Jun 9, 2024
349b5c7
Put back IPv6 logic
biagiopietro Jun 15, 2024
76fddaf
Merge branch 'main' into fix-issue-79772
biagiopietro Jun 15, 2024
892826a
Merge branch 'main' into fix-issue-79772
biagiopietro Jun 16, 2024
bc87c4a
Updates
biagiopietro Jun 16, 2024
3abdded
Merge branch 'main' into fix-issue-79772
biagiopietro Jun 18, 2024
ada5166
Merge branch 'main' into fix-issue-79772
biagiopietro Jun 18, 2024
ccd35c4
Merge branch 'main' into fix-issue-79772
biagiopietro Jun 19, 2024
8c6ec72
Merge branch 'main' into fix-issue-79772
biagiopietro Jun 21, 2024
c3e1698
Merge branch 'main' into fix-issue-79772
biagiopietro Jun 23, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion packages/multicast_dns/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
## NEXT
## 0.3.2+7

* Optimized Socket Binding: Always bind to 0.0.0.0 for simplicity and efficiency.
* Updates minimum supported SDK version to Flutter 3.16/Dart 3.2.

## 0.3.2+6
Expand Down
2 changes: 2 additions & 0 deletions packages/multicast_dns/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Multicast DNS package

Based on [RFC 6762 Multicast DNS](https://datatracker.ietf.org/doc/html/rfc6762).

[![pub package](https://img.shields.io/pub/v/multicast_dns.svg)](
https://pub.dartlang.org/packages/multicast_dns)

Expand Down
52 changes: 10 additions & 42 deletions packages/multicast_dns/lib/multicast_dns.dart
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ class MDnsClient {

bool _starting = false;
bool _started = false;
final List<RawDatagramSocket> _sockets = <RawDatagramSocket>[];
final List<RawDatagramSocket> _toBeClosed = <RawDatagramSocket>[];
RawDatagramSocket? _incomingIPv4;
RawDatagramSocket? _incomingIPv6;
final LookupResolver _resolver = LookupResolver();
final ResourceRecordCache _cache = ResourceRecordCache();
final RawDatagramSocketFactory _rawDatagramSocketFactory;
Expand Down Expand Up @@ -117,9 +117,9 @@ class MDnsClient {

// Can't send to IPv6 any address.
if (incoming.address != InternetAddress.anyIPv6) {
_sockets.add(incoming);
_incomingIPv4 = incoming;
} else {
_toBeClosed.add(incoming);
_incomingIPv6 = incoming;
}

_mDnsAddress ??= incoming.address.type == InternetAddressType.IPv4
Expand All @@ -130,30 +130,6 @@ class MDnsClient {
(await interfacesFactory(listenAddress.type)).toList();

for (final NetworkInterface interface in interfaces) {
// Create a socket for sending on each adapter.
final InternetAddress targetAddress = interface.addresses[0];
final RawDatagramSocket socket = await _rawDatagramSocketFactory(
targetAddress,
selectedMDnsPort,
reuseAddress: true,
reusePort: true,
ttl: 255,
);
_sockets.add(socket);
cbracken marked this conversation as resolved.
Show resolved Hide resolved
// Ensure that we're using this address/interface for multicast.
if (targetAddress.type == InternetAddressType.IPv4) {
socket.setRawOption(RawSocketOption(
RawSocketOption.levelIPv4,
RawSocketOption.IPv4MulticastInterface,
targetAddress.rawAddress,
));
} else {
socket.setRawOption(RawSocketOption.fromInt(
RawSocketOption.levelIPv6,
RawSocketOption.IPv6MulticastInterface,
interface.index,
));
}
// Join multicast on this interface.
incoming.joinMulticast(_mDnsAddress!, interface);
}
Expand All @@ -171,15 +147,10 @@ class MDnsClient {
throw StateError('Cannot stop mDNS client while it is starting.');
}

for (final RawDatagramSocket socket in _sockets) {
socket.close();
}
_sockets.clear();

for (final RawDatagramSocket socket in _toBeClosed) {
socket.close();
}
_toBeClosed.clear();
_incomingIPv4?.close();
_incomingIPv6?.close();
_incomingIPv4 = null;
_incomingIPv6 = null;

biagiopietro marked this conversation as resolved.
Show resolved Hide resolved
_resolver.clearPendingRequests();

Expand Down Expand Up @@ -219,11 +190,8 @@ class MDnsClient {
final Stream<T> results = _resolver.addPendingRequest<T>(
query.resourceRecordType, query.fullyQualifiedName, timeout);

// Send the request on all interfaces.
final List<int> packet = query.encode();
for (final RawDatagramSocket socket in _sockets) {
socket.send(packet, _mDnsAddress!, selectedMDnsPort);
}
// Send and listen on same "ANY" interface
_incomingIPv4?.send(query.encode(), _mDnsAddress!, selectedMDnsPort);
return results;
}

Expand Down
2 changes: 1 addition & 1 deletion packages/multicast_dns/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: multicast_dns
description: Dart package for performing mDNS queries (e.g. Bonjour, Avahi).
repository: https://github.com/flutter/packages/tree/main/packages/multicast_dns
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+multicast_dns%22
version: 0.3.2+6
version: 0.3.2+7

environment:
sdk: ^3.2.0
Expand Down
85 changes: 85 additions & 0 deletions packages/multicast_dns/test/client_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,69 @@ void main() {
await client.start();
await client.lookup(ResourceRecordQuery.serverPointer('_')).toList();
});

group('Bind a single socket to ANY IPv4/6', () {
final List<Map<String, Object>> testCases = <Map<String, Object>>[
<String, Object>{
'name': 'IPv4',
'datagramSocketType': InternetAddress.anyIPv4,
'interfacePrefix': '192.168.2.'
},
<String, Object>{
'name': 'IPv6',
'datagramSocketType': InternetAddress.anyIPv6,
'interfacePrefix': '2001:0db8:85a3:0000:0000:8a2e:7335:030'
}
];

for (final Map<String, Object> testCase in testCases) {
test('Bind a single socket to ANY ${testCase["name"]}', () async {
final FakeRawDatagramSocket datagramSocket = FakeRawDatagramSocket();

datagramSocket.address =
testCase['datagramSocketType']! as InternetAddress;

final List<dynamic> selectedInterfacesForSendingPackets = <dynamic>[];
final MDnsClient client = MDnsClient(rawDatagramSocketFactory:
(dynamic host, int port,
{bool reuseAddress = true,
bool reusePort = true,
int ttl = 1}) async {
selectedInterfacesForSendingPackets.add(host);
return datagramSocket;
});

Future<Iterable<NetworkInterface>> fakeNetworkInterfacesFactory(
InternetAddressType type) async {
final List<NetworkInterface> fakeInterfaces = <NetworkInterface>[];

// Generate "fake" interfaces
for (int i = 0; i < 10; i++) {
fakeInterfaces.add(FakeNetworkInterface(
'inetfake$i',
<InternetAddress>[
InternetAddress("${testCase['interfacePrefix']! as String}$i")
],
0,
));
}

// ignore: always_specify_types
return Future.value(fakeInterfaces);
}

final InternetAddress listenAddress =
testCase['datagramSocketType']! as InternetAddress;
await client.start(
listenAddress: listenAddress,
mDnsPort: 1234,
interfacesFactory: fakeNetworkInterfacesFactory);
client.stop();
expect(selectedInterfacesForSendingPackets.length, 1);
expect(selectedInterfacesForSendingPackets[0], listenAddress.address);
});
}
});
}

class FakeRawDatagramSocket extends Fake implements RawDatagramSocket {
Expand Down Expand Up @@ -113,4 +176,26 @@ class FakeRawDatagramSocket extends Fake implements RawDatagramSocket {
int send(List<int> buffer, InternetAddress address, int port) {
return buffer.length;
}

@override
void joinMulticast(InternetAddress group, [NetworkInterface? interface]) {
// nothing to do here
}
}

class FakeNetworkInterface implements NetworkInterface {
FakeNetworkInterface(this._name, this._addresses, this._index);

final String _name;
final List<InternetAddress> _addresses;
final int _index;

@override
List<InternetAddress> get addresses => _addresses;

@override
String get name => _name;

@override
int get index => _index;
}