internal override void Write(DNSOutgoing out_Renamed) { out_Renamed.WriteShort(priority); out_Renamed.WriteShort(weight); out_Renamed.WriteShort(port); out_Renamed.WriteName(server); }
public void Run(object state) { try { if (Enclosing_Instance.State == DNSState.ANNOUNCED) { if (count++ < 3 && !info.HasData) { long now = (DateTime.Now.Ticks - 621355968000000000) / 10000; DNSOutgoing out_Renamed = new DNSOutgoing(DNSConstants.FLAGS_QR_QUERY); out_Renamed.AddQuestion(new DNSQuestion(info.QualifiedName, DNSConstants.TYPE_SRV, DNSConstants.CLASS_IN)); out_Renamed.AddQuestion(new DNSQuestion(info.QualifiedName, DNSConstants.TYPE_TXT, DNSConstants.CLASS_IN)); if (info.server != null) { out_Renamed.AddQuestion(new DNSQuestion(info.server, DNSConstants.TYPE_A, DNSConstants.CLASS_IN)); } out_Renamed.AddAnswer((DNSRecord)Enclosing_Instance.Cache.get_Renamed(info.QualifiedName, DNSConstants.TYPE_SRV, DNSConstants.CLASS_IN), now); out_Renamed.AddAnswer((DNSRecord)Enclosing_Instance.Cache.get_Renamed(info.QualifiedName, DNSConstants.TYPE_TXT, DNSConstants.CLASS_IN), now); if (info.server != null) { out_Renamed.AddAnswer((DNSRecord)Enclosing_Instance.Cache.get_Renamed(info.server, DNSConstants.TYPE_A, DNSConstants.CLASS_IN), now); } Enclosing_Instance.Send(out_Renamed); } else { // After three queries, we can quit. // TODO: can omit cancel()? //cancel(); Enclosing_Instance.RemoveListener(info); } ; } else if (Enclosing_Instance.State == DNSState.CANCELED) { // TODO: can omit cancel?? //cancel(); Enclosing_Instance.RemoveListener(info); } } catch (Exception e) { logger.Warn("run() exception ", e); Enclosing_Instance.Recover(); } }
public void Run(object state) { try { if (Enclosing_Instance.State == DNSState.ANNOUNCED) { if (count++ < 3 && !info.HasData) { long now = (DateTime.Now.Ticks - 621355968000000000) / 10000; DNSOutgoing out_Renamed = new DNSOutgoing(DNSConstants.FLAGS_QR_QUERY); out_Renamed.AddQuestion(new DNSQuestion(info.QualifiedName, DNSConstants.TYPE_SRV, DNSConstants.CLASS_IN)); out_Renamed.AddQuestion(new DNSQuestion(info.QualifiedName, DNSConstants.TYPE_TXT, DNSConstants.CLASS_IN)); if (info.server != null) { out_Renamed.AddQuestion(new DNSQuestion(info.server, DNSConstants.TYPE_A, DNSConstants.CLASS_IN)); } out_Renamed.AddAnswer((DNSRecord) Enclosing_Instance.Cache.get_Renamed(info.QualifiedName, DNSConstants.TYPE_SRV, DNSConstants.CLASS_IN), now); out_Renamed.AddAnswer((DNSRecord) Enclosing_Instance.Cache.get_Renamed(info.QualifiedName, DNSConstants.TYPE_TXT, DNSConstants.CLASS_IN), now); if (info.server != null) { out_Renamed.AddAnswer((DNSRecord) Enclosing_Instance.Cache.get_Renamed(info.server, DNSConstants.TYPE_A, DNSConstants.CLASS_IN), now); } Enclosing_Instance.Send(out_Renamed); } else { // After three queries, we can quit. // TODO: can omit cancel()? //cancel(); Enclosing_Instance.RemoveListener(info); } ; } else if (Enclosing_Instance.State == DNSState.CANCELED) { // TODO: can omit cancel?? //cancel(); Enclosing_Instance.RemoveListener(info); } } catch (Exception e) { logger.Warn("run() exception ", e); Enclosing_Instance.Recover(); } }
public void Run(object state) { try { if (++count < 3) { logger.Debug("run() JmDNS canceling service"); // announce the service DNSOutgoing out_Renamed = new DNSOutgoing(DNSConstants.FLAGS_QR_RESPONSE | DNSConstants.FLAGS_AA); for (int i = 0; i < infos.Length; i++) { ServiceInfo info = infos[i]; out_Renamed.AddAnswer(new Pointer(info.type, DNSConstants.TYPE_PTR, DNSConstants.CLASS_IN, ttl, info.QualifiedName), 0); out_Renamed.AddAnswer(new Service(info.QualifiedName, DNSConstants.TYPE_SRV, DNSConstants.CLASS_IN, ttl, info.priority, info.weight, info.port, Enclosing_Instance.localHost.Name), 0); out_Renamed.AddAnswer(new Text(info.QualifiedName, DNSConstants.TYPE_TXT, DNSConstants.CLASS_IN, ttl, info.text), 0); DNSRecord answer = Enclosing_Instance.localHost.DNS4AddressRecord; if (answer != null) { out_Renamed.AddAnswer(answer, 0); } answer = Enclosing_Instance.localHost.DNS6AddressRecord; if (answer != null) { out_Renamed.AddAnswer(answer, 0); } } Enclosing_Instance.Send(out_Renamed); } else { // After three successful announcements, we are finished. lock (lock_Renamed) { Monitor.PulseAll(lock_Renamed); } // TODO: omit cancel? //cancel(); } } catch (Exception e) { logger.Warn("run() exception ", e); Enclosing_Instance.Recover(); } }
public void Run(object state) { try { if (Enclosing_Instance.State == DNSState.ANNOUNCED) { if (count++ < 3) { logger.Debug("run() JmDNS querying service"); long now = (DateTime.Now.Ticks - 621355968000000000) / 10000; DNSOutgoing out_Renamed = new DNSOutgoing(DNSConstants.FLAGS_QR_QUERY); out_Renamed.AddQuestion(new DNSQuestion(type, DNSConstants.TYPE_PTR, DNSConstants.CLASS_IN)); foreach (ServiceInfo info in Enclosing_Instance.services.Values) { try { out_Renamed.AddAnswer(new Pointer(info.type, DNSConstants.TYPE_PTR, DNSConstants.CLASS_IN, DNSConstants.DNS_TTL, info.QualifiedName), now); } catch { break; } } Enclosing_Instance.Send(out_Renamed); } else { // After three queries, we can quit. // TODO: can omit? //cancel(); } ; } else if (Enclosing_Instance.State == DNSState.CANCELED) { // TODO: can omit? //cancel(); } } catch (Exception e) { logger.Warn("run() exception ", e); Enclosing_Instance.Recover(); } }
internal override void Write(DNSOutgoing out_Renamed) { if (addr != null) { sbyte[] buffer = SupportClass.ToSByteArray(addr.GetAddressBytes()); if (DNSConstants.TYPE_A == type) { // If we have a type A records we should answer with a IPv4 address if (addr.AddressFamily == AddressFamily.InterNetwork) { // All is good } else { // Get the last four bytes sbyte[] tempbuffer = buffer; buffer = new sbyte[4]; Array.Copy(tempbuffer, 12, buffer, 0, 4); } } else { // If we have a type AAAA records we should answer with a IPv6 address if (addr.AddressFamily == AddressFamily.InterNetwork) { sbyte[] tempbuffer = buffer; buffer = new sbyte[16]; for (int i = 0; i < 16; i++) { if (i < 11) { buffer[i] = tempbuffer[i - 12]; } else { buffer[i] = 0; } } } } int length = buffer.Length; out_Renamed.WriteBytes(buffer, 0, length); } }
/// <summary> Send an outgoing multicast DNS message.</summary> internal async Task Send(DNSOutgoing out_Renamed) { out_Renamed.Finish(); if (!out_Renamed.Empty) { SupportClass.PacketSupport packet = new SupportClass.PacketSupport(SupportClass.ToByteArray(out_Renamed.data), out_Renamed.off, new IPEndPoint(group, DNSConstants.MDNS_PORT)); try { DNSIncoming msg = new DNSIncoming(packet); logger.Debug("send() JmDNS out:" + msg.Print(true)); } catch (IOException e) { logger.Error("send(DNSOutgoing) - JmDNS can not parse what it sends!!!", e); } await SupportClass.UdpClientSupport.Send(socket, packet); } }
internal override void Write(DNSOutgoing out_Renamed) { if (addr != null) { sbyte[] buffer = SupportClass.ToSByteArray(addr.GetAddressBytes()); if (DNSConstants.TYPE_A == type) { // If we have a type A records we should answer with a IPv4 address if (addr.AddressFamily == AddressFamily.InterNetwork) { // All is good } else { // Get the last four bytes sbyte[] tempbuffer = buffer; buffer = new sbyte[4]; Array.Copy(tempbuffer, 12, buffer, 0, 4); } } else { // If we have a type AAAA records we should answer with a IPv6 address if (addr.AddressFamily == AddressFamily.InterNetwork) { sbyte[] tempbuffer = buffer; buffer = new sbyte[16]; for (int i = 0; i < 16; i++) { if (i < 11) buffer[i] = tempbuffer[i - 12]; else buffer[i] = 0; } } } int length = buffer.Length; out_Renamed.WriteBytes(buffer, 0, length); } }
/// <summary> Add an answer to a question. Deal with the case when the /// outgoing packet overflows /// </summary> internal virtual DNSOutgoing AddAnswer(DNSIncoming in_Renamed, IPAddress addr, int port, DNSOutgoing out_Renamed, DNSRecord rec) { if (out_Renamed == null) { out_Renamed = new DNSOutgoing(DNSConstants.FLAGS_QR_RESPONSE | DNSConstants.FLAGS_AA); } try { out_Renamed.AddAnswer(in_Renamed, rec); } catch { out_Renamed.flags |= DNSConstants.FLAGS_TC; out_Renamed.id = in_Renamed.id; out_Renamed.Finish(); Send(out_Renamed); out_Renamed = new DNSOutgoing(DNSConstants.FLAGS_QR_RESPONSE | DNSConstants.FLAGS_AA); out_Renamed.AddAnswer(in_Renamed, rec); } return(out_Renamed); }
public void Run(object state) { try { if (Enclosing_Instance.State == DNSState.ANNOUNCED) { if (++count < 3) { logger.Debug("run() JmDNS querying type"); DNSOutgoing out_Renamed = new DNSOutgoing(DNSConstants.FLAGS_QR_QUERY); out_Renamed.AddQuestion(new DNSQuestion("_services._mdns._udp.local.", DNSConstants.TYPE_PTR, DNSConstants.CLASS_IN)); foreach (string s in Enclosing_Instance.serviceTypes.Values) { out_Renamed.AddAnswer(new Pointer("_services._mdns._udp.local.", DNSConstants.TYPE_PTR, DNSConstants.CLASS_IN, DNSConstants.DNS_TTL, s), 0); } Enclosing_Instance.Send(out_Renamed); } else { // After three queries, we can quit. // TODO: can we omit this? //cancel(); } ; } else if (Enclosing_Instance.State == DNSState.CANCELED) { // TODO: can omit this? //cancel(); } } catch (Exception e) { logger.Warn("run() exception ", e); Enclosing_Instance.Recover(); } }
/// <summary> Add an answer to a question. Deal with the case when the /// outgoing packet overflows /// </summary> internal virtual DNSOutgoing AddAnswer(DNSIncoming in_Renamed, IPAddress addr, int port, DNSOutgoing out_Renamed, DNSRecord rec) { if (out_Renamed == null) { out_Renamed = new DNSOutgoing(DNSConstants.FLAGS_QR_RESPONSE | DNSConstants.FLAGS_AA); } try { out_Renamed.AddAnswer(in_Renamed, rec); } catch { out_Renamed.flags |= DNSConstants.FLAGS_TC; out_Renamed.id = in_Renamed.id; out_Renamed.Finish(); Send(out_Renamed); out_Renamed = new DNSOutgoing(DNSConstants.FLAGS_QR_RESPONSE | DNSConstants.FLAGS_AA); out_Renamed.AddAnswer(in_Renamed, rec); } return out_Renamed; }
internal override DNSOutgoing AddAnswer(mDNS dns, DNSIncoming in_Renamed, IPAddress addr, int port, DNSOutgoing out_Renamed) { return out_Renamed; }
public void Run(object state) { lock (Enclosing_Instance.IOLock) { DNSOutgoing out_Renamed = null; try { // send probes for JmDNS itself if (Enclosing_Instance.State == taskState && Enclosing_Instance.Task == this) { if (out_Renamed == null) { out_Renamed = new DNSOutgoing(DNSConstants.FLAGS_QR_QUERY); } out_Renamed.AddQuestion(new DNSQuestion(Enclosing_Instance.localHost.Name, DNSConstants.TYPE_ANY, DNSConstants.CLASS_IN)); DNSRecord answer = Enclosing_Instance.localHost.DNS4AddressRecord; if (answer != null) out_Renamed.AddAuthorativeAnswer(answer); answer = Enclosing_Instance.localHost.DNS6AddressRecord; if (answer != null) out_Renamed.AddAuthorativeAnswer(answer); Enclosing_Instance.AdvanceState(); } // send probes for services // Defensively copy the services into a local list, // to prevent race conditions with methods registerService // and unregisterService. IList list; lock (Enclosing_Instance) { list = new ArrayList(Enclosing_Instance.services.Values); } foreach (ServiceInfo info in list) { lock (info) { if (info.State == taskState && info.task == this) { info.AdvanceState(); logger.Info("run() JmDNS probing " + info.QualifiedName + " state " + info.State); if (out_Renamed == null) { out_Renamed = new DNSOutgoing(DNSConstants.FLAGS_QR_QUERY); out_Renamed.AddQuestion(new DNSQuestion(info.QualifiedName, DNSConstants.TYPE_ANY, DNSConstants.CLASS_IN)); } out_Renamed.AddAuthorativeAnswer(new Service(info.QualifiedName, DNSConstants.TYPE_SRV, DNSConstants.CLASS_IN, DNSConstants.DNS_TTL, info.priority, info.weight, info.port, info.server)); } } } if (out_Renamed != null) { logger.Debug("run() JmDNS probing #" + taskState); Enclosing_Instance.Send(out_Renamed); } else { // If we have nothing to send, another timer taskState ahead // of us has done the job for us. We can cancel. cancel(); return ; } } catch (Exception e) { logger.Warn("run() exception ", e); Enclosing_Instance.Recover(); } taskState = taskState.Advance(); if (!taskState.Probing) { cancel(); new Announcer(enclosingInstance).start(); } } }
internal override void Write(DNSOutgoing out_Renamed) { out_Renamed.WriteBytes(text, 0, text.Length); }
/// <summary> Write this record into an outgoing message.</summary> internal abstract void Write(DNSOutgoing out_Renamed);
public void Run(object state) { DNSOutgoing out_Renamed = null; try { // send probes for JmDNS itself if (Enclosing_Instance.State == taskState) { if (out_Renamed == null) { out_Renamed = new DNSOutgoing(DNSConstants.FLAGS_QR_RESPONSE | DNSConstants.FLAGS_AA); } DNSRecord answer = Enclosing_Instance.localHost.DNS4AddressRecord; if (answer != null) { out_Renamed.AddAnswer(answer, 0); } answer = Enclosing_Instance.localHost.DNS6AddressRecord; if (answer != null) { out_Renamed.AddAnswer(answer, 0); } Enclosing_Instance.AdvanceState(); } // send announces for services // Defensively copy the services into a local list, // to prevent race conditions with methods registerService // and unregisterService. IList list; lock (Enclosing_Instance) { list = new ArrayList(Enclosing_Instance.services.Values); } foreach (ServiceInfo info in list) { lock (info) { if (info.State == taskState && info.task == this) { info.AdvanceState(); logger.Debug("run() JmDNS announcing " + info.QualifiedName + " state " + info.State); if (out_Renamed == null) { out_Renamed = new DNSOutgoing(DNSConstants.FLAGS_QR_RESPONSE | DNSConstants.FLAGS_AA); } out_Renamed.AddAnswer(new Pointer(info.type, DNSConstants.TYPE_PTR, DNSConstants.CLASS_IN, DNSConstants.DNS_TTL, info.QualifiedName), 0); out_Renamed.AddAnswer(new Service(info.QualifiedName, DNSConstants.TYPE_SRV, DNSConstants.CLASS_IN, DNSConstants.DNS_TTL, info.priority, info.weight, info.port, Enclosing_Instance.localHost.Name), 0); out_Renamed.AddAnswer(new Text(info.QualifiedName, DNSConstants.TYPE_TXT, DNSConstants.CLASS_IN, DNSConstants.DNS_TTL, info.text), 0); } } } if (out_Renamed != null) { logger.Debug("run() JmDNS announcing #" + taskState); Enclosing_Instance.Send(out_Renamed); } else { // If we have nothing to send, another timer taskState ahead // of us has done the job for us. We can cancel. cancel(); } } catch (Exception e) { logger.Warn("run() exception ", e); Enclosing_Instance.Recover(); } taskState = taskState.Advance(); if (!taskState.Announcing) { cancel(); new Renewer(enclosingInstance).start(); } }
internal override void Write(DNSOutgoing out_Renamed) { out_Renamed.WriteName(alias); }
internal override DNSOutgoing AddAnswer(mDNS dns, DNSIncoming in_Renamed, IPAddress addr, int port, DNSOutgoing out_Renamed) { ServiceInfo info = (ServiceInfo) dns.services[name.ToLower()]; if (info != null) { if (this.port == info.port != server.Equals(dns.LocalHost.Name)) { return dns.AddAnswer(in_Renamed, addr, port, out_Renamed, new Service(info.QualifiedName, DNSConstants.TYPE_SRV, DNSConstants.CLASS_IN | DNSConstants.CLASS_UNIQUE, DNSConstants.DNS_TTL, info.priority, info.weight, info.port, dns.LocalHost.Name)); } } return out_Renamed; }
/// <summary> Adds this as an answer to the provided outgoing datagram.</summary> internal abstract DNSOutgoing AddAnswer(mDNS dns, DNSIncoming in_Renamed, IPAddress addr, int port, DNSOutgoing out_Renamed);
public void Run(object state) { DNSOutgoing out_Renamed = null; try { // send probes for JmDNS itself if (Enclosing_Instance.State == taskState) { if (out_Renamed == null) { out_Renamed = new DNSOutgoing(DNSConstants.FLAGS_QR_RESPONSE | DNSConstants.FLAGS_AA); } DNSRecord answer = Enclosing_Instance.localHost.DNS4AddressRecord; if (answer != null) out_Renamed.AddAnswer(answer, 0); answer = Enclosing_Instance.localHost.DNS6AddressRecord; if (answer != null) out_Renamed.AddAnswer(answer, 0); Enclosing_Instance.AdvanceState(); } // send announces for services // Defensively copy the services into a local list, // to prevent race conditions with methods registerService // and unregisterService. IList list; lock (Enclosing_Instance) { list = new ArrayList(Enclosing_Instance.services.Values); } foreach (ServiceInfo info in list) { lock (info) { if (info.State == taskState && info.task == this) { info.AdvanceState(); logger.Debug("run() JmDNS announced " + info.QualifiedName + " state " + info.State); if (out_Renamed == null) { out_Renamed = new DNSOutgoing(DNSConstants.FLAGS_QR_RESPONSE | DNSConstants.FLAGS_AA); } out_Renamed.AddAnswer(new Pointer(info.type, DNSConstants.TYPE_PTR, DNSConstants.CLASS_IN, DNSConstants.DNS_TTL, info.QualifiedName), 0); out_Renamed.AddAnswer(new Service(info.QualifiedName, DNSConstants.TYPE_SRV, DNSConstants.CLASS_IN, DNSConstants.DNS_TTL, info.priority, info.weight, info.port, Enclosing_Instance.localHost.Name), 0); out_Renamed.AddAnswer(new Text(info.QualifiedName, DNSConstants.TYPE_TXT, DNSConstants.CLASS_IN, DNSConstants.DNS_TTL, info.text), 0); } } } if (out_Renamed != null) { logger.Debug("run() JmDNS announced"); Enclosing_Instance.Send(out_Renamed); } else { // If we have nothing to send, another timer taskState ahead // of us has done the job for us. We can cancel. cancel(); } } catch (Exception e) { logger.Warn("run() exception ", e); Enclosing_Instance.Recover(); } taskState = taskState.Advance(); if (!taskState.Announced) { cancel(); } }
internal override DNSOutgoing AddAnswer(mDNS dns, DNSIncoming in_Renamed, IPAddress addr, int port, DNSOutgoing out_Renamed) { return(out_Renamed); }
public void Run(object state) { try { if (++count < 3) { logger.Debug("run() JmDNS canceling service"); // announce the service DNSOutgoing out_Renamed = new DNSOutgoing(DNSConstants.FLAGS_QR_RESPONSE | DNSConstants.FLAGS_AA); for (int i = 0; i < infos.Length; i++) { ServiceInfo info = infos[i]; out_Renamed.AddAnswer(new Pointer(info.type, DNSConstants.TYPE_PTR, DNSConstants.CLASS_IN, ttl, info.QualifiedName), 0); out_Renamed.AddAnswer(new Service(info.QualifiedName, DNSConstants.TYPE_SRV, DNSConstants.CLASS_IN, ttl, info.priority, info.weight, info.port, Enclosing_Instance.localHost.Name), 0); out_Renamed.AddAnswer(new Text(info.QualifiedName, DNSConstants.TYPE_TXT, DNSConstants.CLASS_IN, ttl, info.text), 0); DNSRecord answer = Enclosing_Instance.localHost.DNS4AddressRecord; if (answer != null) out_Renamed.AddAnswer(answer, 0); answer = Enclosing_Instance.localHost.DNS6AddressRecord; if (answer != null) out_Renamed.AddAnswer(answer, 0); } Enclosing_Instance.Send(out_Renamed); } else { // After three successful announcements, we are finished. lock (lock_Renamed) { Monitor.PulseAll(lock_Renamed); } // TODO: omit cancel? //cancel(); } } catch (Exception e) { logger.Warn("run() exception ", e); Enclosing_Instance.Recover(); } }
internal override DNSOutgoing AddAnswer(mDNS dns, DNSIncoming in_Renamed, IPAddress addr, int port, DNSOutgoing out_Renamed) { ServiceInfo info = (ServiceInfo)dns.services[name.ToLower()]; if (info != null) { if (this.port == info.port != server.Equals(dns.LocalHost.Name)) { return(dns.AddAnswer(in_Renamed, addr, port, out_Renamed, new Service(info.QualifiedName, DNSConstants.TYPE_SRV, DNSConstants.CLASS_IN | DNSConstants.CLASS_UNIQUE, DNSConstants.DNS_TTL, info.priority, info.weight, info.port, dns.LocalHost.Name))); } } return(out_Renamed); }
public void Run(object state) { lock (Enclosing_Instance.IOLock) { if (Enclosing_Instance.PlannedAnswer == in_Renamed) { Enclosing_Instance.PlannedAnswer = null; } // We use these sets to prevent duplicate records // FIXME - This should be moved into DNSOutgoing // TODO: check these for compatibility SupportClass.HashSetSupport questions = new SupportClass.HashSetSupport(); SupportClass.HashSetSupport answers = new SupportClass.HashSetSupport(); if (Enclosing_Instance.State == DNSState.ANNOUNCED) { try { long now = (DateTime.Now.Ticks - 621355968000000000) / 10000; long expirationTime = now + 1; //=now+DNSConstants.KNOWN_ANSWER_TTL; bool isUnicast = (port != DNSConstants.MDNS_PORT); // Answer questions foreach (DNSEntry entry in in_Renamed.questions) { if (entry is DNSQuestion) { DNSQuestion q = (DNSQuestion)entry; // for unicast responses the question must be included if (isUnicast) { //out.addQuestion(q); questions.Add(q); } int type = q.type; if (type == DNSConstants.TYPE_ANY || type == DNSConstants.TYPE_SRV) { // I ama not sure of why there is a special case here [PJYF Oct 15 2004] if (Enclosing_Instance.localHost.Name.ToUpper().Equals(q.Name.ToUpper())) { // type = DNSConstants.TYPE_A; DNSRecord answer = Enclosing_Instance.localHost.DNS4AddressRecord; if (answer != null) { answers.Add(answer); } answer = Enclosing_Instance.localHost.DNS6AddressRecord; if (answer != null) { answers.Add(answer); } type = DNSConstants.TYPE_IGNORE; } else if (Enclosing_Instance.serviceTypes.Contains(q.Name.ToLower())) { type = DNSConstants.TYPE_PTR; } } switch (type) { case DNSConstants.TYPE_A: { // Answer a query for a domain name //out = addAnswer( in, addr, port, out, host ); DNSRecord answer = Enclosing_Instance.localHost.DNS4AddressRecord; if (answer != null) { answers.Add(answer); } break; } case DNSConstants.TYPE_AAAA: { // Answer a query for a domain name DNSRecord answer = Enclosing_Instance.localHost.DNS6AddressRecord; if (answer != null) { answers.Add(answer); } break; } case DNSConstants.TYPE_PTR: { // Answer a query for services of a given type // find matching services foreach (ServiceInfo info in Enclosing_Instance.services.Values) { if (info.State == DNSState.ANNOUNCED) { if (q.name.ToUpper().Equals(info.type.ToUpper())) { DNSRecord answer = Enclosing_Instance.localHost.DNS4AddressRecord; if (answer != null) { answers.Add(answer); } answer = Enclosing_Instance.localHost.DNS6AddressRecord; if (answer != null) { answers.Add(answer); } answers.Add(new Pointer(info.type, DNSConstants.TYPE_PTR, DNSConstants.CLASS_IN, DNSConstants.DNS_TTL, info.QualifiedName)); answers.Add(new Service(info.QualifiedName, DNSConstants.TYPE_SRV, DNSConstants.CLASS_IN | DNSConstants.CLASS_UNIQUE, DNSConstants.DNS_TTL, info.priority, info.weight, info.port, Enclosing_Instance.localHost.Name)); answers.Add(new Text(info.QualifiedName, DNSConstants.TYPE_TXT, DNSConstants.CLASS_IN | DNSConstants.CLASS_UNIQUE, DNSConstants.DNS_TTL, info.text)); } } } if (q.name.ToUpper().Equals("_services._mdns._udp.local.".ToUpper())) { foreach (String s in Enclosing_Instance.serviceTypes.Values) { answers.Add(new Pointer("_services._mdns._udp.local.", DNSConstants.TYPE_PTR, DNSConstants.CLASS_IN, DNSConstants.DNS_TTL, s)); } } break; } case DNSConstants.TYPE_SRV: case DNSConstants.TYPE_ANY: case DNSConstants.TYPE_TXT: { ServiceInfo info = (ServiceInfo)Enclosing_Instance.services[q.name.ToLower()]; if (info != null && info.State == DNSState.ANNOUNCED) { DNSRecord answer = Enclosing_Instance.localHost.DNS4AddressRecord; if (answer != null) { answers.Add(answer); } answer = Enclosing_Instance.localHost.DNS6AddressRecord; if (answer != null) { answers.Add(answer); } answers.Add(new Pointer(info.type, DNSConstants.TYPE_PTR, DNSConstants.CLASS_IN, DNSConstants.DNS_TTL, info.QualifiedName)); answers.Add(new Service(info.QualifiedName, DNSConstants.TYPE_SRV, DNSConstants.CLASS_IN | DNSConstants.CLASS_UNIQUE, DNSConstants.DNS_TTL, info.priority, info.weight, info.port, Enclosing_Instance.localHost.Name)); answers.Add(new Text(info.QualifiedName, DNSConstants.TYPE_TXT, DNSConstants.CLASS_IN | DNSConstants.CLASS_UNIQUE, DNSConstants.DNS_TTL, info.text)); } break; } default: { //Console.WriteLine("JmDNSResponder.unhandled query:"+q); break; } } } } // remove known answers, if the ttl is at least half of // the correct value. (See Draft Cheshire chapter 7.1.). foreach (DNSRecord knownAnswer in in_Renamed.answers) { bool tempBoolean; tempBoolean = answers.Contains(knownAnswer); answers.Remove(knownAnswer); if (knownAnswer.ttl > DNSConstants.DNS_TTL / 2 && tempBoolean) { logger.Debug("JmDNS Responder Known Answer Removed"); } } // responde if we have answers if (answers.Count != 0) { logger.Debug("run() JmDNS responding"); DNSOutgoing out_Renamed = null; if (isUnicast) { out_Renamed = new DNSOutgoing(DNSConstants.FLAGS_QR_RESPONSE | DNSConstants.FLAGS_AA, false); } foreach (DNSQuestion question in questions) { out_Renamed.AddQuestion(question); } foreach (DNSRecord answer in answers) { out_Renamed = Enclosing_Instance.AddAnswer(in_Renamed, addr, port, out_Renamed, answer); } Enclosing_Instance.Send(out_Renamed); } // TODO: do we need this? //cancel(); } catch (Exception e) { logger.Warn("run() exception ", e); Enclosing_Instance.Close(); } } } }
public void Run(object state) { lock (Enclosing_Instance.IOLock) { if (Enclosing_Instance.PlannedAnswer == in_Renamed) { Enclosing_Instance.PlannedAnswer = null; } // We use these sets to prevent duplicate records // FIXME - This should be moved into DNSOutgoing // TODO: check these for compatibility SupportClass.HashSetSupport questions = new SupportClass.HashSetSupport(); SupportClass.HashSetSupport answers = new SupportClass.HashSetSupport(); if (Enclosing_Instance.State == DNSState.ANNOUNCED) { try { long now = (DateTime.Now.Ticks - 621355968000000000) / 10000; long expirationTime = now + 1; //=now+DNSConstants.KNOWN_ANSWER_TTL; bool isUnicast = (port != DNSConstants.MDNS_PORT); // Answer questions foreach (DNSEntry entry in in_Renamed.questions) { if (entry is DNSQuestion) { DNSQuestion q = (DNSQuestion) entry; // for unicast responses the question must be included if (isUnicast) { //out.addQuestion(q); questions.Add(q); } int type = q.type; if (type == DNSConstants.TYPE_ANY || type == DNSConstants.TYPE_SRV) { // I ama not sure of why there is a special case here [PJYF Oct 15 2004] if (Enclosing_Instance.localHost.Name.ToUpper().Equals(q.Name.ToUpper())) { // type = DNSConstants.TYPE_A; DNSRecord answer = Enclosing_Instance.localHost.DNS4AddressRecord; if (answer != null) answers.Add(answer); answer = Enclosing_Instance.localHost.DNS6AddressRecord; if (answer != null) answers.Add(answer); type = DNSConstants.TYPE_IGNORE; } else if (Enclosing_Instance.serviceTypes.Contains(q.Name.ToLower())) { type = DNSConstants.TYPE_PTR; } } switch (type) { case DNSConstants.TYPE_A: { // Answer a query for a domain name //out = addAnswer( in, addr, port, out, host ); DNSRecord answer = Enclosing_Instance.localHost.DNS4AddressRecord; if (answer != null) answers.Add(answer); break; } case DNSConstants.TYPE_AAAA: { // Answer a query for a domain name DNSRecord answer = Enclosing_Instance.localHost.DNS6AddressRecord; if (answer != null) answers.Add(answer); break; } case DNSConstants.TYPE_PTR: { // Answer a query for services of a given type // find matching services foreach (ServiceInfo info in Enclosing_Instance.services.Values) { if (info.State == DNSState.ANNOUNCED) { if (q.name.ToUpper().Equals(info.type.ToUpper())) { DNSRecord answer = Enclosing_Instance.localHost.DNS4AddressRecord; if (answer != null) answers.Add(answer); answer = Enclosing_Instance.localHost.DNS6AddressRecord; if (answer != null) answers.Add(answer); answers.Add(new Pointer(info.type, DNSConstants.TYPE_PTR, DNSConstants.CLASS_IN, DNSConstants.DNS_TTL, info.QualifiedName)); answers.Add(new Service(info.QualifiedName, DNSConstants.TYPE_SRV, DNSConstants.CLASS_IN | DNSConstants.CLASS_UNIQUE, DNSConstants.DNS_TTL, info.priority, info.weight, info.port, Enclosing_Instance.localHost.Name)); answers.Add(new Text(info.QualifiedName, DNSConstants.TYPE_TXT, DNSConstants.CLASS_IN | DNSConstants.CLASS_UNIQUE, DNSConstants.DNS_TTL, info.text)); } } } if (q.name.ToUpper().Equals("_services._mdns._udp.local.".ToUpper())) { foreach (String s in Enclosing_Instance.serviceTypes.Values) { answers.Add(new Pointer("_services._mdns._udp.local.", DNSConstants.TYPE_PTR, DNSConstants.CLASS_IN, DNSConstants.DNS_TTL, s)); } } break; } case DNSConstants.TYPE_SRV: case DNSConstants.TYPE_ANY: case DNSConstants.TYPE_TXT: { ServiceInfo info = (ServiceInfo) Enclosing_Instance.services[q.name.ToLower()]; if (info != null && info.State == DNSState.ANNOUNCED) { DNSRecord answer = Enclosing_Instance.localHost.DNS4AddressRecord; if (answer != null) answers.Add(answer); answer = Enclosing_Instance.localHost.DNS6AddressRecord; if (answer != null) answers.Add(answer); answers.Add(new Pointer(info.type, DNSConstants.TYPE_PTR, DNSConstants.CLASS_IN, DNSConstants.DNS_TTL, info.QualifiedName)); answers.Add(new Service(info.QualifiedName, DNSConstants.TYPE_SRV, DNSConstants.CLASS_IN | DNSConstants.CLASS_UNIQUE, DNSConstants.DNS_TTL, info.priority, info.weight, info.port, Enclosing_Instance.localHost.Name)); answers.Add(new Text(info.QualifiedName, DNSConstants.TYPE_TXT, DNSConstants.CLASS_IN | DNSConstants.CLASS_UNIQUE, DNSConstants.DNS_TTL, info.text)); } break; } default: { //Console.WriteLine("JmDNSResponder.unhandled query:"+q); break; } } } } // remove known answers, if the ttl is at least half of // the correct value. (See Draft Cheshire chapter 7.1.). foreach (DNSRecord knownAnswer in in_Renamed.answers) { bool tempBoolean; tempBoolean = answers.Contains(knownAnswer); answers.Remove(knownAnswer); if (knownAnswer.ttl > DNSConstants.DNS_TTL / 2 && tempBoolean) { logger.Debug("JmDNS Responder Known Answer Removed"); } } // responde if we have answers if (answers.Count != 0) { logger.Debug("run() JmDNS responding"); DNSOutgoing out_Renamed = null; if (isUnicast) { out_Renamed = new DNSOutgoing(DNSConstants.FLAGS_QR_RESPONSE | DNSConstants.FLAGS_AA, false); } foreach (DNSQuestion question in questions) { out_Renamed.AddQuestion(question); } foreach (DNSRecord answer in answers) { out_Renamed = Enclosing_Instance.AddAnswer(in_Renamed, addr, port, out_Renamed, answer); } Enclosing_Instance.Send(out_Renamed); } // TODO: do we need this? //cancel(); } catch (Exception e) { logger.Warn("run() exception ", e); Enclosing_Instance.Close(); } } } }