public Responder(mDNS enclosingInstance, DNSIncoming in_Renamed, IPAddress addr, int port) { InitBlock(enclosingInstance); this.in_Renamed = in_Renamed; this.addr = addr; this.port = port; }
/// <summary> Appends answers to this Incoming.</summary> /// <exception cref=""> InvalidArgumentException if this is not truncated, and /// that or this is not a query. /// </exception> internal void Append(DNSIncoming that) { if (this.Query && this.Truncated && that.Query) { SupportClass.ICollectionSupport.AddAll(this.questions, that.questions); this.numQuestions += that.numQuestions; if (SupportClass.EqualsSupport.Equals(ArrayList.ReadOnly(new ArrayList()), answers)) { answers = ArrayList.Synchronized(new ArrayList()); } if (that.numAnswers > 0) { SupportClass.IListSupport.AddAll(this.answers, this.numAnswers, (IList)((ArrayList)that.answers).GetRange(0, that.numAnswers - 0)); this.numAnswers += that.numAnswers; } if (that.numAuthorities > 0) { SupportClass.IListSupport.AddAll(this.answers, this.numAnswers + this.numAuthorities, (IList)((ArrayList)that.answers).GetRange(that.numAnswers, that.numAnswers + that.numAuthorities - that.numAnswers)); this.numAuthorities += that.numAuthorities; } if (that.numAdditionals > 0) { SupportClass.ICollectionSupport.AddAll(this.answers, (IList)((ArrayList)that.answers).GetRange(that.numAnswers + that.numAuthorities, that.numAnswers + that.numAuthorities + that.numAdditionals - (that.numAnswers + that.numAuthorities))); this.numAdditionals += that.numAdditionals; } } else { throw new ArgumentException(); } }
/// <summary> Add an additional answer to the record. Omit if there is no room.</summary> internal void AddAdditionalAnswer(DNSIncoming in_Renamed, DNSRecord rec) { if ((off < DNSConstants.MAX_MSG_TYPICAL - 200) && !rec.SuppressedBy(in_Renamed)) { WriteRecord(rec, 0); numAdditionals++; } }
/// <summary> Add an answer if it is not suppressed.</summary> internal void AddAnswer(DNSIncoming in_Renamed, DNSRecord rec) { if (numAuthorities > 0 || numAdditionals > 0) { // TODO is this the right exception throw new Exception("Answers must be added before authorities and additionals"); } if (!rec.SuppressedBy(in_Renamed)) { AddAnswer(rec, 0); } }
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> 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); } }
/// <summary> True if this record is suppressed by the answers in a message.</summary> internal virtual bool SuppressedBy(DNSIncoming msg) { try { for (int i = msg.numAnswers; i-- > 0; ) { if (SuppressedBy((DNSRecord) msg.answers[i])) { return true; } } return false; } catch (IndexOutOfRangeException e) { logger.Warn("suppressedBy() message " + msg + " exception ", e); // msg.print(true); return false; } }
/// <summary> True if this record is suppressed by the answers in a message.</summary> internal virtual bool SuppressedBy(DNSIncoming msg) { try { for (int i = msg.numAnswers; i-- > 0;) { if (SuppressedBy((DNSRecord)msg.answers[i])) { return(true); } } return(false); } catch (IndexOutOfRangeException e) { logger.Warn("suppressedBy() message " + msg + " exception ", e); // msg.print(true); return(false); } }
private void Socket_MessageReceived(Windows.Networking.Sockets.DatagramSocket sender, Windows.Networking.Sockets.DatagramSocketMessageReceivedEventArgs args) { uint dataLength = args.GetDataReader().UnconsumedBufferLength; byte[] result = new byte[dataLength]; args.GetDataReader().ReadBytes(result); SupportClass.PacketSupport packet = new SupportClass.PacketSupport(result, result.Length, new System.Net.IPEndPoint(System.Net.IPAddress.Parse(args.RemoteAddress.CanonicalName), int.Parse(args.RemotePort))); try { if (Enclosing_Instance.localHost.ShouldIgnorePacket(packet)) { return; } DNSIncoming msg = new DNSIncoming(packet); logger.Debug("SocketListener.run() JmDNS in:" + msg.Print(true)); lock (Enclosing_Instance.IOLock) { if (msg.Query) { if (packet.Port != DNSConstants.MDNS_PORT) { Enclosing_Instance.HandleQuery(msg, packet.Address, packet.Port); } Enclosing_Instance.HandleQuery(msg, Enclosing_Instance.Group, DNSConstants.MDNS_PORT); } else { Enclosing_Instance.HandleResponse(msg); } } } catch (IOException e) { logger.Warn("run() exception ", e); } }
/// <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); }
/// <summary> Handle an incoming query. See if we can answer any part of it /// given our service infos. /// </summary> internal void HandleQuery(DNSIncoming in_Renamed, IPAddress addr, int port) { // Track known answers bool hostConflictDetected = false; bool serviceConflictDetected = false; long expirationTime = (DateTime.Now.Ticks - 621355968000000000) / 10000 + DNSConstants.KNOWN_ANSWER_TTL; foreach (DNSRecord answer in in_Renamed.answers) { if ((answer.GetEntryType() == DNSConstants.TYPE_A) || (answer.GetEntryType() == DNSConstants.TYPE_AAAA)) { hostConflictDetected |= answer.HandleQuery(this, expirationTime); } else { serviceConflictDetected |= answer.HandleQuery(this, expirationTime); } } if (plannedAnswer != null) { plannedAnswer.Append(in_Renamed); } else { if (in_Renamed.Truncated) { plannedAnswer = in_Renamed; } new Responder(this, in_Renamed, addr, port).start(); } if (hostConflictDetected || serviceConflictDetected) { new Prober(this).start(); } }
private void Socket_MessageReceived(Windows.Networking.Sockets.DatagramSocket sender, Windows.Networking.Sockets.DatagramSocketMessageReceivedEventArgs args) { uint dataLength = args.GetDataReader().UnconsumedBufferLength; byte[] result = new byte[dataLength]; args.GetDataReader().ReadBytes(result); SupportClass.PacketSupport packet = new SupportClass.PacketSupport(result, result.Length, new System.Net.IPEndPoint(System.Net.IPAddress.Parse(args.RemoteAddress.CanonicalName), int.Parse(args.RemotePort))); try { if (Enclosing_Instance.localHost.ShouldIgnorePacket(packet)) return; DNSIncoming msg = new DNSIncoming(packet); logger.Debug("SocketListener.run() JmDNS in:" + msg.Print(true)); lock (Enclosing_Instance.IOLock) { if (msg.Query) { if (packet.Port != DNSConstants.MDNS_PORT) { Enclosing_Instance.HandleQuery(msg, packet.Address, packet.Port); } Enclosing_Instance.HandleQuery(msg, Enclosing_Instance.Group, DNSConstants.MDNS_PORT); } else { Enclosing_Instance.HandleResponse(msg); } } } catch (IOException e) { logger.Warn("run() exception ", e); } }
/// <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);
/// <summary> Handle an incoming response. Cache answers, and pass them on to /// the appropriate questions. /// </summary> internal void HandleResponse(DNSIncoming msg) { long now = (DateTime.Now.Ticks - 621355968000000000) / 10000; bool hostConflictDetected = false; bool serviceConflictDetected = false; for (int recIdx = 0; recIdx < msg.answers.Count; recIdx++) { DNSRecord rec = (DNSRecord)msg.answers[recIdx]; bool isInformative = false; bool expired = rec.IsExpired(now); // update the cache DNSRecord c = (DNSRecord)cache.get_Renamed(rec); if (c != null) { if (expired) { isInformative = true; cache.remove(c); } else { c.ResetTTL(rec); rec = c; msg.answers[recIdx] = c; // put back into collection } } else { if (!expired) { isInformative = true; cache.add(rec); } } switch (rec.type) { case DNSConstants.TYPE_PTR: // handle _mdns._udp records if (rec.Name.IndexOf("._mdns._udp.") >= 0) { if (!expired && rec.name.StartsWith("_services._mdns._udp.")) { isInformative = true; RegisterServiceType(((Pointer)rec).alias); } continue; } RegisterServiceType(rec.name); break; } if ((rec.GetEntryType() == DNSConstants.TYPE_A) || (rec.GetEntryType() == DNSConstants.TYPE_AAAA)) { hostConflictDetected |= rec.HandleResponse(this); } else { serviceConflictDetected |= rec.HandleResponse(this); } // notify the listeners if (isInformative) { UpdateRecord(now, rec); } } if (hostConflictDetected || serviceConflictDetected) { new Prober(this).start(); } }
/// <summary> Appends answers to this Incoming.</summary> /// <exception cref=""> InvalidArgumentException if this is not truncated, and /// that or this is not a query. /// </exception> internal void Append(DNSIncoming that) { if (this.Query && this.Truncated && that.Query) { SupportClass.ICollectionSupport.AddAll(this.questions, that.questions); this.numQuestions += that.numQuestions; if (SupportClass.EqualsSupport.Equals(ArrayList.ReadOnly(new ArrayList()), answers)) answers = ArrayList.Synchronized(new ArrayList()); if (that.numAnswers > 0) { SupportClass.IListSupport.AddAll(this.answers, this.numAnswers, (IList) ((ArrayList) that.answers).GetRange(0, that.numAnswers - 0)); this.numAnswers += that.numAnswers; } if (that.numAuthorities > 0) { SupportClass.IListSupport.AddAll(this.answers, this.numAnswers + this.numAuthorities, (IList) ((ArrayList) that.answers).GetRange(that.numAnswers, that.numAnswers + that.numAuthorities - that.numAnswers)); this.numAuthorities += that.numAuthorities; } if (that.numAdditionals > 0) { SupportClass.ICollectionSupport.AddAll(this.answers, (IList) ((ArrayList) that.answers).GetRange(that.numAnswers + that.numAuthorities, that.numAnswers + that.numAuthorities + that.numAdditionals - (that.numAnswers + that.numAuthorities))); this.numAdditionals += that.numAdditionals; } } else { throw new ArgumentException(); } }
internal override DNSOutgoing AddAnswer(mDNS dns, DNSIncoming in_Renamed, IPAddress addr, int port, DNSOutgoing out_Renamed) { return(out_Renamed); }
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; }
internal override DNSOutgoing AddAnswer(mDNS dns, DNSIncoming in_Renamed, IPAddress addr, int port, DNSOutgoing out_Renamed) { return out_Renamed; }
/// <summary> Handle an incoming response. Cache answers, and pass them on to /// the appropriate questions. /// </summary> internal void HandleResponse(DNSIncoming msg) { long now = (DateTime.Now.Ticks - 621355968000000000) / 10000; bool hostConflictDetected = false; bool serviceConflictDetected = false; for (int recIdx = 0; recIdx < msg.answers.Count; recIdx++) { DNSRecord rec = (DNSRecord) msg.answers[recIdx]; bool isInformative = false; bool expired = rec.IsExpired(now); // update the cache DNSRecord c = (DNSRecord) cache.get_Renamed(rec); if (c != null) { if (expired) { isInformative = true; cache.remove(c); } else { c.ResetTTL(rec); rec = c; msg.answers[recIdx] = c; // put back into collection } } else { if (!expired) { isInformative = true; cache.add(rec); } } switch (rec.type) { case DNSConstants.TYPE_PTR: // handle _mdns._udp records if (rec.Name.IndexOf("._mdns._udp.") >= 0) { if (!expired && rec.name.StartsWith("_services._mdns._udp.")) { isInformative = true; RegisterServiceType(((Pointer) rec).alias); } continue; } RegisterServiceType(rec.name); break; } if ((rec.GetEntryType() == DNSConstants.TYPE_A) || (rec.GetEntryType() == DNSConstants.TYPE_AAAA)) { hostConflictDetected |= rec.HandleResponse(this); } else { serviceConflictDetected |= rec.HandleResponse(this); } // notify the listeners if (isInformative) { UpdateRecord(now, rec); } } if (hostConflictDetected || serviceConflictDetected) { new Prober(this).start(); } }
/// <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; }