/// <summary> Listen for services of a given type. The type has to be a fully qualified /// type name such as <code>_http._tcp.local.</code>. /// </summary> /// <param name="type">full qualified service type, such as <code>_http._tcp.local.</code>. /// </param> /// <param name="listener">listener for service updates /// </param> public virtual void AddServiceListener(string type, IServiceListener listener) { string lotype = type.ToLower(); RemoveServiceListener(lotype, listener); IList list = null; lock (this) { list = (IList)serviceListeners[lotype]; if (list == null) { list = ArrayList.Synchronized(new ArrayList()); serviceListeners[lotype] = list; } list.Add(listener); } // report cached service types foreach (DictionaryEntry entry in cache) { for (DNSCache.CacheNode n = (DNSCache.CacheNode)entry.Value; n != null; n = n.Next) { DNSRecord rec = (DNSRecord)n.Value; if (rec.type == DNSConstants.TYPE_SRV) { if (rec.name.EndsWith(type)) { listener.ServiceAdded(this, new ServiceEvent(this, type, ToUnqualifiedName(type, rec.name), null)); } } } } new ServiceResolver(this, type).start(); }
/// <summary> Generate a possibly unique name for a host using the information we /// have in the cache. /// /// </summary> /// <returns> returns true, if the name of the host had to be changed. /// </returns> private bool MakeHostNameUnique(Address host) { string originalName = host.Name; long now = (DateTime.Now.Ticks - 621355968000000000) / 10000; bool collision; do { collision = false; // Check for collision in cache for (DNSCache.CacheNode j = cache.find(host.Name.ToLower()); j != null; j = j.Next) { DNSRecord a = (DNSRecord)j.Value; if (false) // TODO: huh? { host.name = IncrementName(host.Name); collision = true; break; } } }while (collision); if (originalName.Equals(host.Name)) { return(false); } else { return(true); } }
/// <summary> Generate a possibly unique name for a service using the information we /// have in the cache. /// /// </summary> /// <returns> returns true, if the name of the service info had to be changed. /// </returns> private bool makeServiceNameUnique(ServiceInfo info) { string originalQualifiedName = info.QualifiedName; long now = (DateTime.Now.Ticks - 621355968000000000) / 10000; bool collision; do { collision = false; // Check for collision in cache for (DNSCache.CacheNode j = cache.find(info.QualifiedName.ToLower()); j != null; j = j.Next) { DNSRecord a = (DNSRecord)j.Value; if ((a.type == DNSConstants.TYPE_SRV) && !a.IsExpired(now)) { Service s = (Service)a; if (s.port != info.port || !s.server.Equals(localHost.Name)) { logger.Debug("makeServiceNameUnique() JmDNS.makeServiceNameUnique srv collision:" + a + " s.server=" + s.server + " " + localHost.Name + " equals:" + (s.server.Equals(localHost.Name))); info.SetName(IncrementName(info.getName())); collision = true; break; } } } // Check for collision with other service infos published by JmDNS object selfService = services[info.QualifiedName.ToLower()]; if (selfService != null && selfService != info) { info.SetName(IncrementName(info.getName())); collision = true; } }while (collision); return(!(originalQualifiedName.Equals(info.QualifiedName))); }
public void Run(object state) { lock (Enclosing_Instance) { if (Enclosing_Instance.State == DNSState.CANCELED) { return; } logger.Debug("run() JmDNS reaping cache"); // Remove expired answers from the cache // ------------------------------------- // To prevent race conditions, we defensively copy all cache // entries into a list. IList list = new ArrayList(); lock (Enclosing_Instance.Cache) { foreach (DictionaryEntry entry in Enclosing_Instance.Cache) { DNSCache.CacheNode node = (DNSCache.CacheNode)entry.Value; for (DNSCache.CacheNode n = node; n != null; n = n.Next) { list.Add(n.Value); } } } // Now, we remove them. long now = (DateTime.Now.Ticks - 621355968000000000) / 10000; foreach (DNSRecord c in list) { if (c.IsExpired(now)) { Enclosing_Instance.UpdateRecord(now, c); Enclosing_Instance.Cache.remove(c); } } } }
/// <summary> Add a listener for a question. The listener will receive updates /// of answers to the question as they arrive, or from the cache if they /// are already available. /// </summary> internal virtual void AddListener(IDNSListener listener, DNSQuestion question) { long now = (DateTime.Now.Ticks - 621355968000000000) / 10000; // add the new listener lock (this) { listeners.Add(listener); } // report existing matched records if (question != null) { for (DNSCache.CacheNode i = cache.find(question.name); i != null; i = i.Next) { DNSRecord c = (DNSRecord)i.Value; if (question.IsAnsweredBy(c) && !c.IsExpired(now)) { listener.UpdateRecord(this, now, c); } } } }