| Index: pkg/mdns/lib/mdns.dart
|
| diff --git a/pkg/mdns/lib/mdns.dart b/pkg/mdns/lib/mdns.dart
|
| index f707136d4c865cb33b8b6f39c022af0af5fbd5f7..55682a7b4ca2c2360d0554cb504ef3c130f4e71f 100644
|
| --- a/pkg/mdns/lib/mdns.dart
|
| +++ b/pkg/mdns/lib/mdns.dart
|
| @@ -1,68 +1,48 @@
|
| -// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
|
| +// Copyright (c) 2015, the Fletch 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.
|
| +// BSD-style license that can be found in the LICENSE.md file.
|
| +
|
| +library mdns;
|
|
|
| import 'dart:async';
|
| import 'dart:collection';
|
| import 'dart:io';
|
| import 'dart:typed_data';
|
|
|
| -import 'package:mdns/src/constants.dart';
|
| -import 'package:mdns/src/lookup_resolver.dart';
|
| -import 'package:mdns/src/packet.dart';
|
| +import 'package:mdns/src/native_extension_client.dart';
|
| +import 'package:mdns/src/native_protocol_client.dart';
|
|
|
| /// Client for DNS lookup using the mDNS protocol.
|
| ///
|
| /// This client only support "One-Shot Multicast DNS Queries" as described in
|
| /// section 5.1 of https://tools.ietf.org/html/rfc6762
|
| -class MDnsClient {
|
| - bool _starting = false;
|
| - bool _started = false;
|
| - RawDatagramSocket _incoming;
|
| - final List<RawDatagramSocket> _sockets = <RawDatagramSocket>[];
|
| - final LookupResolver _resolver = new LookupResolver();
|
| -
|
| - /// Start the mDNS client.
|
| - Future start() async {
|
| - if (_started && _starting) {
|
| - throw new StateError('mDNS client already started');
|
| - }
|
| - _starting = true;
|
| -
|
| - // Listen on all addresses.
|
| - _incoming = await RawDatagramSocket.bind(
|
| - InternetAddress.ANY_IP_V4, mDnsPort, reuseAddress: true);
|
| -
|
| - // Find all network interfaces with an IPv4 address.
|
| - var interfaces =
|
| - await NetworkInterface.list(type: InternetAddressType.IP_V4);
|
| - for (NetworkInterface interface in interfaces) {
|
| - // Create a socket for sending on each adapter.
|
| - var socket = await RawDatagramSocket.bind(
|
| - interface.addresses[0], mDnsPort, reuseAddress: true);
|
| - _sockets.add(socket);
|
| -
|
| - // Join multicast on this interface.
|
| - _incoming.joinMulticast(mDnsAddress, interface);
|
| +abstract class MDnsClient {
|
| + // Instantiate Client for DNS lookup using the mDNS protocol.
|
| + //
|
| + // On Mac OS a native extension is used as the mDNSResponder opens the mDNS
|
| + // port in exclusive mode. To test the protocol implementation on Mac OS
|
| + // one can turn off mDNSResponder:
|
| + //
|
| + // sudo launchctl unload -w \
|
| + // /System/Library/LaunchDaemons/com.apple.mDNSResponder.plist
|
| + //
|
| + // And turn it on again:
|
| + //
|
| + // sudo launchctl load -w \
|
| + // /System/Library/LaunchDaemons/com.apple.mDNSResponder.plist
|
| + factory MDnsClient() {
|
| + if (Platform.isMacOS) {
|
| + return new NativeExtensionMDnsClient();
|
| + } else {
|
| + return new NativeProtocolMDnsClient();
|
| }
|
| - _incoming.listen(_handleIncoming);
|
| -
|
| - _starting = false;
|
| - _started = true;
|
| }
|
|
|
| - /// Stop the mDNS client.
|
| - void stop() {
|
| - if (!_started) return;
|
| - if (_starting) {
|
| - throw new StateError('Cannot stop mDNS client wile it is starting');
|
| - }
|
| -
|
| - _sockets.forEach((socket) => socket.close());
|
| - _incoming.close();
|
| + /// Start the mDNS client.
|
| + Future start();
|
|
|
| - _started = false;
|
| - }
|
| + /// Stop the mDNS client.
|
| + void stop();
|
|
|
| /// Lookup [hostname] using mDNS.
|
| ///
|
| @@ -72,40 +52,14 @@ class MDnsClient {
|
| /// If no answer has been received within the specified [timeout]
|
| /// this method will complete with the value `null`.
|
| Future<InternetAddress> lookup(
|
| - String hostname, {Duration timeout: const Duration(seconds: 5)}) {
|
| - if (!_started) {
|
| - throw new StateError('mDNS client is not started');
|
| - }
|
| -
|
| - // Add the pending request before sending the query.
|
| - var future = _resolver.addPendingRequest(hostname, timeout);
|
| -
|
| - // Send the request on all interfaces.
|
| - List<int> packet = encodeMDnsQuery(hostname);
|
| - for (int i = 0; i < _sockets.length; i++) {
|
| - _sockets[i].send(packet, mDnsAddress, mDnsPort);
|
| - }
|
| -
|
| - return future;
|
| - }
|
| -
|
| - // Process incoming datagrams.
|
| - _handleIncoming(event) {
|
| - if (event == RawSocketEvent.READ) {
|
| - var data = _incoming.receive();
|
| - var response = decodeMDnsResponse(data.data);
|
| - if (response != null) {
|
| - _resolver.handleResponse(response);
|
| - }
|
| - }
|
| - }
|
| + String hostname, {Duration timeout: const Duration(seconds: 5)});
|
| }
|
|
|
| // Simple standalone test.
|
| -main() async {
|
| +Future main(List<String> args) async {
|
| var client = new MDnsClient();
|
| await client.start();
|
| - var address = await client.lookup('raspberrypi.local');
|
| + var address = await client.lookup(args[0]);
|
| client.stop();
|
| print(address);
|
| }
|
|
|