Allow configuration of port and address

This commit is contained in:
Jonah Williams
2019-07-31 09:46:22 -07:00
committed by GitHub
parent bc85a0b605
commit caf02e0174
4 changed files with 70 additions and 7 deletions

View File

@ -1,3 +1,6 @@
## 0.2.0
* Allow configuration of the port and address the mdns query is performed on.
## 0.1.1
* Fixes [flutter/issue/31854](https://github.com/flutter/flutter/issues/31854) where `decodeMDnsResponse` advanced to incorrect code points and ignored some records.

View File

@ -24,6 +24,14 @@ export 'package:multicast_dns/src/resource_record.dart';
typedef NetworkInterfacesFactory = Future<Iterable<NetworkInterface>> Function(
InternetAddressType type);
/// A factory for construction of datagram sockets.
///
/// This can be injected into the [MDnsClient] to provide alternative
/// implementations of [RawDatagramSocket.bind].
typedef RawDatagramSocketFactory = Future<RawDatagramSocket> Function(
dynamic host, int port,
{bool reuseAddress, bool reusePort, int ttl});
/// Client for DNS lookup and publishing using the mDNS protocol.
///
/// Users should call [MDnsQuerier.start] when ready to start querying and
@ -33,13 +41,21 @@ typedef NetworkInterfacesFactory = Future<Iterable<NetworkInterface>> Function(
/// This client only supports "One-Shot Multicast DNS Queries" as described in
/// section 5.1 of [RFC 6762](https://tools.ietf.org/html/rfc6762).
class MDnsClient {
/// Create a new [MDnsClient].
MDnsClient({
RawDatagramSocketFactory rawDatagramSocketFactory = RawDatagramSocket.bind,
}) : _rawDatagramSocketFactory = rawDatagramSocketFactory;
bool _starting = false;
bool _started = false;
RawDatagramSocket _incoming;
final List<RawDatagramSocket> _sockets = <RawDatagramSocket>[];
final LookupResolver _resolver = LookupResolver();
final ResourceRecordCache _cache = ResourceRecordCache();
final RawDatagramSocketFactory _rawDatagramSocketFactory;
InternetAddress _mDnsAddress;
int _mDnsPort;
/// Find all network interfaces with an the [InternetAddressType] specified.
static NetworkInterfacesFactory allInterfacesFactory =
@ -58,12 +74,23 @@ class MDnsClient {
/// [InternetAddress.anyIPv6], and will default to anyIPv4.
///
/// The [interfaceFactory] defaults to [allInterfacesFactory].
///
/// The [mDnsPort] allows configuring what port is used for the mDNS
/// query. If not provided, defaults to `5353`.
///
/// The [mDnsAddress] allows configuring what internet address is used
/// for the mDNS query. If not provided, defaults to either `224.0.0.251` or
/// or `FF02::FB`.
Future<void> start({
InternetAddress listenAddress,
NetworkInterfacesFactory interfacesFactory,
int mDnsPort = mDnsPort,
InternetAddress mDnsAddress,
}) async {
listenAddress ??= InternetAddress.anyIPv4;
interfacesFactory ??= allInterfacesFactory;
_mDnsPort = mDnsPort;
_mDnsAddress = mDnsAddress;
assert(listenAddress.address == InternetAddress.anyIPv4.address ||
listenAddress.address == InternetAddress.anyIPv6.address);
@ -74,9 +101,9 @@ class MDnsClient {
_starting = true;
// Listen on all addresses.
_incoming = await RawDatagramSocket.bind(
_incoming = await _rawDatagramSocketFactory(
listenAddress.address,
mDnsPort,
_mDnsPort,
reuseAddress: true,
reusePort: true,
ttl: 255,
@ -87,7 +114,7 @@ class MDnsClient {
_sockets.add(_incoming);
}
_mDnsAddress = _incoming.address.type == InternetAddressType.IPv4
_mDnsAddress ??= _incoming.address.type == InternetAddressType.IPv4
? mDnsAddressIPv4
: mDnsAddressIPv6;
@ -97,9 +124,9 @@ class MDnsClient {
for (NetworkInterface interface in interfaces) {
// Create a socket for sending on each adapter.
final InternetAddress targetAddress = interface.addresses[0];
final RawDatagramSocket socket = await RawDatagramSocket.bind(
final RawDatagramSocket socket = await _rawDatagramSocketFactory(
targetAddress,
mDnsPort,
_mDnsPort,
reuseAddress: true,
reusePort: true,
ttl: 255,
@ -180,7 +207,7 @@ class MDnsClient {
// Send the request on all interfaces.
final List<int> packet = query.encode();
for (RawDatagramSocket socket in _sockets) {
socket.send(packet, _mDnsAddress, mDnsPort);
socket.send(packet, _mDnsAddress, _mDnsPort);
}
return results;
}

View File

@ -2,13 +2,14 @@ name: multicast_dns
description: Dart package for mDNS queries (e.g. Bonjour, Avahi).
author: Flutter Team <flutter-dev@googlegroups.com>
homepage: https://github.com/flutter/packages/tree/master/packages/multicast_dns
version: 0.1.1
version: 0.2.0
dependencies:
meta: ^1.1.6
dev_dependencies:
test: "^1.3.4"
mockito: "^4.1.0"
environment:
sdk: ">=2.1.1-dev.2.0 <3.0.0"

View File

@ -0,0 +1,32 @@
// Copyright (c) 2015, the Dartino project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:io';
import 'package:multicast_dns/multicast_dns.dart';
import 'package:mockito/mockito.dart';
import 'package:test/test.dart';
void main() {
test('Can inject datagram socket factory and configure mdns port', () async {
int lastPort;
final MockRawDatagramSocket mockRawDatagramSocket = MockRawDatagramSocket();
final MDnsClient client = MDnsClient(rawDatagramSocketFactory:
(dynamic host, int port,
{bool reuseAddress, bool reusePort, int ttl = 1}) async {
lastPort = port;
return mockRawDatagramSocket;
});
when(mockRawDatagramSocket.address).thenReturn(InternetAddress.anyIPv4);
await client.start(
mDnsPort: 1234,
interfacesFactory: (InternetAddressType type) async =>
<NetworkInterface>[]);
expect(lastPort, 1234);
});
}
class MockRawDatagramSocket extends Mock implements RawDatagramSocket {}