Пример #1
0
        /// <summary>
        /// Unregister a service.
        /// </summary>
        /// <param name="info">Info.</param>
        public void UnregisterService(ServiceInfo info)
        {
            string nameLower = info.Type.ToLower();

            if (this.services.ContainsKey(nameLower))
            {
                this.services.Remove(nameLower);
                if (this.serviceTypes[info.Type] > 0)
                {
                    this.serviceTypes[info.Type] -= 1;
                }
                else
                {
                    this.serviceTypes.Remove(info.Type);
                }
            }

            long now      = Utilities.CurrentTimeMilliseconds();
            long nextTime = now;
            int  i        = 0;

            while (i < 3)
            {
                if (now < nextTime)
                {
                    Wait(nextTime - now);
                    now = Utilities.CurrentTimeMilliseconds();
                    continue;
                }
                DNSOutgoing outgoing = new DNSOutgoing((ushort)QueryFlags.Response | (ushort)Flags.AA);
                outgoing.AddAnswerAtTime(
                    new DNSPointer(info.Type, DNSType.PTR, DNSClass.IN, 0, info.Name), 0);
                outgoing.AddAnswerAtTime(
                    new DNSService(info.Name, DNSType.SRV, DNSClass.IN, 0,
                                   info.Priority, info.Weight, info.Port, info.Name), 0);

                outgoing.AddAnswerAtTime(
                    new DNSText(info.Name, DNSType.TXT, DNSClass.IN, 0, info.Text), 0);
                if (info.Address != null)
                {
                    outgoing.AddAnswerAtTime(
                        new DNSAddress(info.Server, DNSType.A, DNSClass.IN, 0,
                                       Utilities.AddressToBytes(info.Address)), 0);
                }

                Send(outgoing);
                i++;
                nextTime += Timing.Unregister;
            }
        }
Пример #2
0
        /// <summary>
        /// Registers service information to the network with a default TTL
        // of 60 seconds.Zeroconf will then respond to requests for
        // information for that service.The name of the service may be
        // changed if needed to make it unique on the network.
        /// </summary>
        /// <param name="info">Info.</param>
        /// <param name="ttl">Ttl.</param>
        /// <param name="allowNameChange">If set to <c>true</c> allow name change.</param>
        public void RegisterService(ServiceInfo info, ushort ttl = Constants.DNS_TTL,
                                    bool allowNameChange         = false)
        {
            CheckService(info, allowNameChange);

            this.services[info.Name.ToLower()] = info;
            if (this.serviceTypes.ContainsKey(info.Type))
            {
                this.serviceTypes[info.Type] += 1;
            }
            else
            {
                this.serviceTypes[info.Type] = 1;
            }

            long now      = Utilities.CurrentTimeMilliseconds();
            long nextTime = now;
            int  i        = 0;

            while (i < 3)
            {
                if (now < nextTime)
                {
                    Wait(nextTime - now);
                    now = Utilities.CurrentTimeMilliseconds();
                    continue;
                }
                DNSOutgoing outgoing = new DNSOutgoing((ushort)QueryFlags.Response | (ushort)Flags.AA);
                outgoing.AddAnswerAtTime(
                    new DNSPointer(info.Type, DNSType.PTR, DNSClass.IN, ttl, info.Name), 0);
                outgoing.AddAnswerAtTime(
                    new DNSService(info.Name, DNSType.SRV, DNSClass.IN, ttl,
                                   info.Priority, info.Weight, info.Port, info.Server), 0);

                outgoing.AddAnswerAtTime(
                    new DNSText(info.Name, DNSType.TXT, DNSClass.IN, ttl, info.Text), 0);
                if (info.Address != null)
                {
                    outgoing.AddAnswerAtTime(
                        new DNSAddress(info.Server, DNSType.A, DNSClass.IN, ttl,
                                       Utilities.AddressToBytes(info.Address)), 0);
                }

                Send(outgoing);
                i++;
                nextTime += Timing.Register;
            }
        }
Пример #3
0
        public void Run()
        {
            this.zc.AddListener(this, new DNSQuestion(this.type,
                                                      DNSType.PTR, DNSClass.IN));

            long now;

            while (true)
            {
                now = Utilities.CurrentTimeMilliseconds();
                if (this.eventArgs.Count == 0 && this.nextTime > now)
                {
                    this.zc.Wait(this.nextTime - now);
                }
                if (this.zc.Done || this.done)
                {
                    return;
                }
                now = Utilities.CurrentTimeMilliseconds();
                if (this.nextTime <= now)
                {
                    DNSOutgoing outgoing = new DNSOutgoing((ushort)QueryFlags.Query);
                    outgoing.AddQuestion(new DNSQuestion(this.type, DNSType.PTR, DNSClass.IN));
                    foreach (DNSRecord record in this.services.Values)
                    {
                        if (!record.IsStale(now))
                        {
                            outgoing.AddAnswerAtTime(record, now);
                        }
                    }
                    this.zc.Send(outgoing);
                    this.nextTime = now + this.delay;
                    this.delay    = Math.Min(20 * 1000, this.delay * 2);
                }

                if (this.eventArgs.Count > 0 && !this.zc.Done)
                {
                    Delegates.OnChangeEventArgs args = this.eventArgs.Dequeue();
                    this._handlersToCall(this.zc, args);
                }
            }
        }
Пример #4
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);
        }