/// <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; } }
/// <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; } }
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); } } }
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); }