Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(451)

Unified Diff: pkg/mdns/lib/mdns.dart

Issue 1426863003: Add a mDNS package (Closed) Base URL: git@github.com:dart-lang/fletch.git@master
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: pkg/mdns/lib/mdns.dart
diff --git a/pkg/mdns/lib/mdns.dart b/pkg/mdns/lib/mdns.dart
new file mode 100644
index 0000000000000000000000000000000000000000..1e9594f7fe1cdf49c98a7f802244a8059ef0ce74
--- /dev/null
+++ b/pkg/mdns/lib/mdns.dart
@@ -0,0 +1,112 @@
+// Copyright (c) 2015, the Dart 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: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';
+
+/// 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 {
karlklose 2015/10/28 10:14:30 I think this should be 'MDnsClient'.
Søren Gjesse 2015/10/28 11:36:57 Yes, you are probably right.
+ bool _starting = false;
+ bool _started = false;
+ RawDatagramSocket _incoming;
+ final List<RawDatagramSocket> _sockets = [];
karlklose 2015/10/28 10:14:30 Consider adding a type to the list literal to catc
Søren Gjesse 2015/10/28 11:36:57 Done.
+ final LookupResolver _resolver = new LookupResolver();
+ final Duration _defaultTimeout = new Duration(seconds: 5);
karlklose 2015/10/28 10:14:30 Does it make sense to remove this field (it cannot
Søren Gjesse 2015/10/28 11:36:57 Absolutely. Done.
+
+ MDNSClient();
karlklose 2015/10/28 10:14:30 Not needed.
Søren Gjesse 2015/10/28 11:36:57 Removed.
+
+ /// 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);
+ var socket;
karlklose 2015/10/28 10:14:30 Move declaration to line 45?
Søren Gjesse 2015/10/28 11:36:57 Done.
+ for (int i = 0; i < interfaces.length; i++) {
karlklose 2015/10/28 10:14:30 How about: for (NetworkInterface interface in i
Søren Gjesse 2015/10/28 11:36:57 Sure, done.
+ // Create a socket for sending on each adapter.
+ socket = await RawDatagramSocket.bind(
+ interfaces[i].addresses[0], mDNSPort, reuseAddress: true);
+ _sockets.add(socket);
+
+ // Join multicast on this interface.
+ _incoming.joinMulticast(mDNSAddress, interfaces[i]);
+ }
+ _incoming.listen(_handleIncoming);
+
+ _starting = false;
+ _started = true;
+ }
+
+ /// Stop the mDNS client.
+ void stop() {
+ if (!_started) return;
karlklose 2015/10/28 10:14:30 Should this method throw if '_starting == true'?
Søren Gjesse 2015/10/28 11:36:57 Done.
+
+ _sockets.forEach((socket) => socket.close());
+ _incoming.close();
+
+ _started = false;
+ }
+
+ /// Lookup [hostname] using mDNS.
+ ///
+ /// The `hostname` must have the form `single-dns-label.local`,
+ /// e.g. `printer.local`.
+ ///
+ /// 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}) {
+ if (!_started) {
+ throw new StateError('mDNS client is not started');
+ }
+
+ // Add the pending request before sending the query.
+ var future = _resolver.addPendingRequest(
+ hostname, timeout != null ? timeout : _defaultTimeout);
+
+ // 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);
+ }
+ }
+ }
+}
+
+// Simple standalone test.
+main() async {
+ var client = new MDNSClient();
+ await client.start();
+ var address = await client.lookup('raspberrypi.local');
+ client.stop();
+ print(address);
+}
« no previous file with comments | « .packages ('k') | pkg/mdns/lib/src/constants.dart » ('j') | pkg/mdns/lib/src/constants.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698