Пример #1
0
        /// <summary>
        ///     Resolves available ZeroConf distinct services continuously until disposed
        /// </summary>
        public static IObservable <IZeroconfHost> ResolveContinuousDistinct(ResolveOptions options)
        {
            var inner = Resolve(options);

            return(inner.Repeat().Distinct());
        }
Пример #2
0
        static ZeroconfHost ResponseToZeroconf(Response response, string remoteAddress, ResolveOptions options)
        {
            var ipv4Adresses = response.Answers
                               .Select(r => r.RECORD)
                               .OfType <RecordA>()
                               .Concat(response.Additionals
                                       .Select(r => r.RECORD)
                                       .OfType <RecordA>())
                               .Select(aRecord => aRecord.Address)
                               .Distinct()
                               .ToList();

            var ipv6Adresses = response.Answers
                               .Select(r => r.RECORD)
                               .OfType <RecordAAAA>()
                               .Concat(response.Additionals
                                       .Select(r => r.RECORD)
                                       .OfType <RecordAAAA>())
                               .Select(aRecord => aRecord.Address)
                               .Distinct()
                               .ToList();

            var z = new ZeroconfHost
            {
                IPAddresses = ipv4Adresses.Concat(ipv6Adresses).ToList()
            };

            z.Id = z.IPAddresses.FirstOrDefault() ?? remoteAddress;

            var dispNameSet = false;

            foreach (var ptrRec in response.RecordsPTR)
            {
                // set the display name if needed
                if (!dispNameSet &&
                    (options == null ||
                     (options != null &&
                      options.Protocols.Contains(ptrRec.RR.NAME))))
                {
                    z.DisplayName = ptrRec.PTRDNAME.Replace($".{ptrRec.RR.NAME}", "");
                    dispNameSet   = true;
                }

                // Get the matching service records
                var responseRecords = response.RecordsRR
                                      .Where(r => r.NAME == ptrRec.PTRDNAME)
                                      .Select(r => r.RECORD)
                                      .ToList();

                var srvRec = responseRecords.OfType <RecordSRV>().FirstOrDefault();
                if (srvRec == null)
                {
                    continue; // Missing the SRV record, not valid
                }
                var svc = new Service
                {
                    Name        = ptrRec.RR.NAME,
                    ServiceName = srvRec.RR.NAME,
                    Port        = srvRec.PORT,
                    Ttl         = (int)srvRec.RR.TTL,
                };

                // There may be 0 or more text records - property sets
                foreach (var txtRec in responseRecords.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);
        }