static public List <string> Find(Zeroconf zc = null, int timeout = 5,
                                         InterfaceChoice interfaces = InterfaceChoice.All)
        {
            Zeroconf localZc = null;

            if (zc != null)
            {
                localZc = zc;
            }
            else
            {
                localZc = new Zeroconf(interfaces: interfaces);
            }

            ZeroconfServiceTypes listener = new ZeroconfServiceTypes();
            ServiceBrowser       browser  = new ServiceBrowser(
                localZc, "_services._dns-sd._udp.local.",
                listener: listener
                );

            // Wait for responses
            System.Threading.Thread.Sleep(timeout * 1000);

            // Close down anything we opened
            if (zc == null)
            {
                localZc.Close();
            }
            else
            {
                browser.Cancel();
            }

            return(listener.foundServices);
        }
Exemple #2
0
 /// <summary>
 /// Updates service information from a DNS record
 /// </summary>
 /// <param name="zc">Zc.</param>
 /// <param name="now">Now.</param>
 /// <param name="record">Record.</param>
 public void UpdateRecord(Zeroconf zc, long now, DNSRecord record)
 {
     if (record != null && !record.IsExpired(now))
     {
         if (record.Type == DNSType.A && record.Name == this.Server)
         {
             this.Address = ((DNSAddress)record).Address.ToString();
         }
         else if (record.Type == DNSType.SRV && record.Name == this.Name)
         {
             this.Server   = ((DNSService)record).Server.ToString();
             this.Port     = ((DNSService)record).Port;
             this.Weight   = ((DNSService)record).Weight;
             this.Priority = ((DNSService)record).Priority;
             UpdateRecord(zc, now, (DNSAddress)zc.Cache.GetByDetails(
                              this.Server,
                              DNSType.A,
                              DNSClass.IN));
         }
         else if (record.Type == DNSType.TXT && record.Name == this.Name)
         {
             SetText(((DNSText)record).Text);
         }
     }
 }
Exemple #3
0
        public ServiceBrowser(Zeroconf zc, string type,
                              List <Delegates.HandlerDelegate> handlers = null,
                              IListener listener = null)
        {
            if (handlers == null && listener == null)
            {
                throw new Exception("You need to specify at least one handler");
            }

            if (!type.EndsWith(Utilities.ServiceTypeName(type), StringComparison.CurrentCulture))
            {
                throw new BadTypeInNameException("");
            }

            this.t = new Thread(Run)
            {
                Name         = "zeroconf-ServiceBrowser_" + type,
                IsBackground = true
            };

            this.zc       = zc;
            this.type     = type;
            this.services = new Dictionary <string, DNSRecord>();
            this.nextTime = Utilities.CurrentTimeMilliseconds();
            this.delay    = Timing.Browser;

            this.done = false;

            if (handlers != null)
            {
                foreach (Delegates.HandlerDelegate h in handlers)
                {
                    this._handlersToCall += h;
                }
            }

            if (listener != null)
            {
                Delegates.HandlerDelegate OnChange = (sender, e) => {
                    Zeroconf _zc = sender as Zeroconf;
                    if (e.StateChange == ServiceStateChange.Added)
                    {
                        listener.AddService(_zc, e.Type, e.Name);
                    }
                    else if (e.StateChange == ServiceStateChange.Removed)
                    {
                        listener.RemoveService(_zc, e.Type, e.Name);
                    }
                    else
                    {
                        throw new NotImplementedException(e.StateChange.ToString());
                    }
                };

                this._handlersToCall += OnChange;
            }
            this.eventArgs = new Queue <Delegates.OnChangeEventArgs>();

            this.t.Start();
        }
Exemple #4
0
 public Reaper(Zeroconf zc)
 {
     this.t = new Thread(Run)
     {
         Name         = "zeroconf-Reaper",
         IsBackground = true
     };
     this.zc = zc;
     this.t.Start();
 }
Exemple #5
0
 public Engine(Zeroconf zc)
 {
     this.t = new Thread(Run)
     {
         Name         = "zeroconf-Engine",
         IsBackground = true
     };
     this.zc        = zc;
     this.readers   = new Dictionary <Socket, IReader>();
     this.timeout   = 5;
     this.condition = new object();
     this.t.Start();
 }
Exemple #6
0
        /// <summary>
        /// Callback invoked by Zeroconf when new information arrives.
        /// Updates information required by browser in the Zeroconf cache.
        /// </summary>
        /// <param name="zc">Zc.</param>
        /// <param name="now">Now.</param>
        /// <param name="record">Record.</param>
        public void UpdateRecord(Zeroconf zc, long now, DNSRecord record)
        {
            if (record.Type == DNSType.PTR && record.Name == this.type)
            {
                bool      expired    = record.IsExpired(now);
                string    alias      = ((DNSPointer)record).Alias;
                string    serviceKey = alias.ToLower();
                DNSRecord oldRecord;

                bool success = this.services.TryGetValue(serviceKey, out oldRecord);
                if (!success && !expired)
                {
                    this.services[serviceKey] = record;
                    this.eventArgs.Enqueue(
                        new Delegates.OnChangeEventArgs(this.type, alias,
                                                        ServiceStateChange.Added)
                        );
                }
                else if (!expired)
                {
                    oldRecord.ResetTTL(record);
                }
                else
                {
                    this.services.Remove(serviceKey);
                    this.eventArgs.Enqueue(
                        new Delegates.OnChangeEventArgs(this.type, alias,
                                                        ServiceStateChange.Removed)
                        );
                    return;
                }

                long expires = record.GetExpirationTime(75);
                if (expires < this.nextTime)
                {
                    this.nextTime = expires;
                }
            }
        }
Exemple #7
0
        public bool Request(Zeroconf zc, long timeout)
        {
            long now   = Utilities.CurrentTimeMilliseconds();
            long delay = Timing.Listener;
            long next  = now + delay;
            long last  = now + timeout;

            List <Tuple <DNSType, DNSClass> > recordTypesForCheckCache = new List <Tuple <DNSType, DNSClass> >()
            {
                new Tuple <DNSType, DNSClass>(DNSType.SRV, DNSClass.IN),
                new Tuple <DNSType, DNSClass>(DNSType.TXT, DNSClass.IN),
            };

            if (this.Server != null)
            {
                recordTypesForCheckCache.Add(new Tuple <DNSType, DNSClass>(DNSType.A, DNSClass.IN));
            }

            foreach (Tuple <DNSType, DNSClass> record_type in recordTypesForCheckCache)
            {
                DNSRecord cached = (DNSRecord)zc.Cache.GetByDetails(this.Name,
                                                                    record_type.Item1,
                                                                    record_type.Item2);
                if (cached != null)
                {
                    this.UpdateRecord(zc, now, cached);
                }
            }

            if (this.Server != null || this.Address != null || this.Text != null)
            {
                return(true);
            }

            try
            {
                zc.AddListener(this, new DNSQuestion(this.Name, DNSType.ANY, DNSClass.IN));
                while (this.Server == null || this.Address == null || this.Text == null)
                {
                    if (last <= now)
                    {
                        return(false);
                    }
                    if (next <= now)
                    {
                        DNSOutgoing outgoing = new DNSOutgoing((ushort)QueryFlags.Query);

                        outgoing.AddQuestion(
                            new DNSQuestion(this.Name, DNSType.SRV, DNSClass.IN));
                        outgoing.AddAnswerAtTime(
                            (DNSService)zc.Cache.GetByDetails(this.Name, DNSType.SRV, DNSClass.IN),
                            now
                            );

                        outgoing.AddQuestion(
                            new DNSQuestion(this.Name, DNSType.TXT, DNSClass.IN));
                        outgoing.AddAnswerAtTime(
                            (DNSText)zc.Cache.GetByDetails(this.Name, DNSType.TXT, DNSClass.IN),
                            now
                            );

                        if (this.Server != null)
                        {
                            outgoing.AddQuestion(
                                new DNSQuestion(this.Name, DNSType.A, DNSClass.IN));
                            outgoing.AddAnswerAtTime(
                                (DNSAddress)zc.Cache.GetByDetails(this.Name, DNSType.A, DNSClass.IN),
                                now
                                );
                        }

                        zc.Send(outgoing);
                        next   = now + delay;
                        delay *= 2;
                    }
                    zc.Wait(Math.Min(next, last) - now);
                    now = Utilities.CurrentTimeMilliseconds();
                }
            }
            finally
            {
                zc.RemoveListener(this);
            }
            return(true);
        }
 public void RemoveService(Zeroconf zc, string type, string name)
 {
 }
 public void AddService(Zeroconf zc, string type, string name)
 {
     this.foundServices.Add(name);
 }
Exemple #10
0
 public Listener(Zeroconf zc)
 {
     this.zc = zc;
 }