private static ZeroconfHost ResponseToZeroconf(Response response, string remoteAddress) { var z = new ZeroconfHost(); // Get the Id and IP address from the A record var aRecord = response.Additionals .Select(r => r.RECORD) .OfType<RecordA>() .FirstOrDefault(); if (aRecord != null) { z.Id = aRecord.RR.NAME.Split('.')[0]; z.IPAddress = aRecord.Address; } else { // Is this valid? z.Id = remoteAddress; z.IPAddress = remoteAddress; } var dispNameSet = false; var services = response.Answers .Select(r => r.RECORD) .OfType<RecordPTR>(); foreach (var ptrRec in services) { // set the display name if needed if (!dispNameSet) { z.DisplayName = ptrRec.PTRDNAME.Split('.')[0]; dispNameSet = true; } // Get the matching service records var serviceRecords = response.Additionals .Where(r => r.NAME == ptrRec.PTRDNAME) .Select(r => r.RECORD) .ToList(); var srvRec = serviceRecords.OfType<RecordSRV>().FirstOrDefault(); if (srvRec == null) continue; // Missing the SRV record, not valid var svc = new Service { Name = ptrRec.RR.NAME, Port = srvRec.PORT }; // There may be 0 or more text records - property sets foreach (var txtRec in serviceRecords.OfType<RecordTXT>()) { var set = new Dictionary<string, string>(); foreach (var txt in txtRec.TXT) { var split = txt.Split(new[] {'='}, 2); if (split.Length == 1) { if (!string.IsNullOrWhiteSpace(split[0])) set[split[0]] = null; } else { set[split[0]] = split[1]; } } svc.AddPropertySet(set); } z.AddService(svc); } return z; }
private static async Task<IDictionary<string, Response>> ResolveInternal(IEnumerable<string> protocols, byte[] requestBytes, TimeSpan scanTime, int retries, int retryDelayMilliseconds, Action<string, Response> callback, CancellationToken cancellationToken) { using (await ResolverLock.LockAsync()) { cancellationToken.ThrowIfCancellationRequested(); if (scanTime == default(TimeSpan)) scanTime = TimeSpan.FromSeconds(2); var dict = new Dictionary<string, Response>(); Action<string, byte[]> converter = (address, buffer) => { var resp = new Response(buffer); Debug.WriteLine("IP: {0}, Bytes: {1}, IsResponse: {2}", address, buffer.Length, resp.header.QR); if (resp.header.QR) { lock (dict) { dict[address] = resp; } if (callback != null) callback(address, resp); } }; Debug.WriteLine("Looking for {0} with scantime {1}", string.Join(", ", protocols), scanTime); await NetworkInterface.NetworkRequestAsync(requestBytes, scanTime, retries, retryDelayMilliseconds, converter, cancellationToken) .ConfigureAwait(false); return dict; } }
private static IEnumerable<string> BrowseResponseParser(Response response) { return response.RecordsPTR.Select(ptr => ptr.PTRDNAME); }
private static IEnumerable<string> BrowseResponseParser(Response response) { return response.RecordsRR.Select(record => record.RECORD) .OfType<RecordPTR>() .Select(ptr => ptr.PTRDNAME); }
/// <summary> /// Listens for mDNS Service Announcements /// </summary> /// <param name="callback"></param> /// <param name="cancellationToken"></param> /// <returns></returns> public static Task ListenForAnnouncementsAsync(Action<ServiceAnnouncement> callback, CancellationToken cancellationToken) { return NetworkInterface.ListenForAnnouncementsAsync((adapter, address, buffer) => { var response = new Response(buffer); if (response.IsQueryResponse) callback(new ServiceAnnouncement(adapter, ResponseToZeroconf(response, address))); }, cancellationToken); }