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

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

Issue 1412063015: Improve resource record implementation in the mdns package. (Closed) Base URL: https://github.com/dart-lang/fletch.git@master
Patch Set: Created 5 years, 1 month 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/src/native_protocol_client.dart
diff --git a/pkg/mdns/lib/src/native_protocol_client.dart b/pkg/mdns/lib/src/native_protocol_client.dart
index 23854300ee9281e44c4dac70c3755474579346bb..4ee0d00baa44d918d32f6bc4a6f21d03b60f8c48 100644
--- a/pkg/mdns/lib/src/native_protocol_client.dart
+++ b/pkg/mdns/lib/src/native_protocol_client.dart
@@ -13,6 +13,53 @@ import 'package:mdns/src/constants.dart';
import 'package:mdns/src/lookup_resolver.dart';
import 'package:mdns/src/packet.dart';
+class ResourceRecordCache {
Søren Gjesse 2015/11/06 08:44:48 Maybe explain how this cache works. Any reason for
karlklose 2015/11/06 12:20:00 Done. The main reason was to control the size of
+ final List buffer;
+ final int size;
+ int position;
+
+ ResourceRecordCache({int size: 32})
+ : buffer = new List(size),
+ size = size,
+ position = 0;
+
+ void updateRecords(List<ResourceRecord> records) {
+ // TODO(karlklose): include flush bit in the record and only flush if
+ // necessary.
+ for (int i = position; i < position + size; i++) {
Søren Gjesse 2015/11/06 08:44:48 The clearing could just run from 0 to size, but ma
+ ResourceRecord r = buffer[i % size];
+ if (r == null) continue;
+ String name = r.name;
+ int type = r.type;
+ for (ResourceRecord record in records) {
+ if (name == record.name && type == record.type) {
+ buffer[i % size] = null;
+ break;
+ }
+ }
+ }
+
+ for (ResourceRecord record in records) {
+ buffer[position] = record;
+ position = (position + 1) % size;
+ }
+ }
+
+ void lookup(String name, int type, List results) {
+ int time = new DateTime.now().millisecondsSinceEpoch;
+ for (int i = position + size; i >= position; i--) {
+ int index = i % size;
+ ResourceRecord record = buffer[index];
+ if (record == null) continue;
+ if (record.validUntil < time) {
+ buffer[index] = null;
+ } else if (record.name == name && record.type == type) {
+ results.add(record);
+ }
+ }
+ }
+}
+
// Implementation of mDNS client using the native protocol.
class NativeProtocolMDnsClient implements MDnsClient {
bool _starting = false;
@@ -20,6 +67,7 @@ class NativeProtocolMDnsClient implements MDnsClient {
RawDatagramSocket _incoming;
final List<RawDatagramSocket> _sockets = <RawDatagramSocket>[];
final LookupResolver _resolver = new LookupResolver();
+ ResourceRecordCache cache = new ResourceRecordCache();
/// Start the mDNS client.
Future start() async {
@@ -62,30 +110,43 @@ class NativeProtocolMDnsClient implements MDnsClient {
_started = false;
}
- Future<InternetAddress> lookup(
- String hostname, {Duration timeout: const Duration(seconds: 5)}) {
+ Stream<InternetAddress> lookup(
+ int type,
+ String name,
+ {Duration timeout: const Duration(seconds: 5)}) {
if (!_started) {
throw new StateError('mDNS client is not started');
}
+ // Look for entries in the cache.
+ List<ResourceRecordCache> cached = <ResourceRecord>[];
+ cache.lookup(name, type, cached);
+ if (cached.isNotEmpty) {
+ StreamController controller = new StreamController();
+ cached.forEach(controller.add);
+ controller.close();
+ return controller.stream;
+ }
+
// Add the pending request before sending the query.
- var future = _resolver.addPendingRequest(hostname, timeout);
+ var results = _resolver.addPendingRequest(type, name, timeout);
// Send the request on all interfaces.
- List<int> packet = encodeMDnsQuery(hostname);
+ List<int> packet = encodeMDnsQuery(name, type);
for (int i = 0; i < _sockets.length; i++) {
_sockets[i].send(packet, mDnsAddress, mDnsPort);
}
- return future;
+ return results;
}
// Process incoming datagrams.
_handleIncoming(event) {
if (event == RawSocketEvent.READ) {
- var data = _incoming.receive();
- var response = decodeMDnsResponse(data.data);
+ Datagram datagram = _incoming.receive();
+ List<ResourceRecord> response = decodeMDnsResponse(datagram.data);
if (response != null) {
+ cache.updateRecords(response);
_resolver.handleResponse(response);
}
}

Powered by Google App Engine
This is Rietveld 408576698