Beispiel #1
0
        /// <summary>
        /// Deal with incoming response packets.  All answers
        /// are held in the cache, and listeners are notified.
        /// </summary>
        /// <param name="msg">Message.</param>
        public void HandleResponse(DNSIncoming msg)
        {
            long now = Utilities.CurrentTimeMilliseconds();

            foreach (DNSRecord record in msg.Answers)
            {
                bool expired = record.IsExpired(now);
                if (this.Cache.Entries().Contains(record))
                {
                    if (expired)
                    {
                        this.Cache.Remove(record);
                    }
                    else
                    {
                        DNSRecord entry = (DNSRecord)this.Cache.Get(record);
                        if (entry != null)
                        {
                            entry.ResetTTL(record);
                        }
                    }
                }
                else
                {
                    this.Cache.Add(record);
                }
            }

            foreach (DNSRecord record in msg.Answers)
            {
                UpdateRecord(now, record);
            }
        }
Beispiel #2
0
 public void AddAnswer(DNSIncoming incoming, DNSRecord record)
 {
     if (!record.SuppressedBy(incoming))
     {
         AddAnswerAtTime(record, 0);
     }
 }
Beispiel #3
0
 /// <summary>
 /// Returns true if any answer in a message can suffice for the
 /// information held in this record
 /// </summary>
 /// <returns><c>true</c>, if supressed, <c>false</c> otherwise.</returns>
 /// <param name="incoming">Incoming.</param>
 public bool SuppressedBy(DNSIncoming incoming)
 {
     foreach (DNSRecord record in incoming.Answers)
     {
         if (SuppressedByAnswer(record))
         {
             return(true);
         }
     }
     return(false);
 }
Beispiel #4
0
        public void HandleRead(Socket socket)
        {
            int recvSize = 0;

            byte[]   buf      = new byte[Constants.MAX_MSG_ABSOLUTE];
            EndPoint remoteEp = new IPEndPoint(0, 0);

            try
            {
                recvSize = socket.ReceiveFrom(buf, ref remoteEp);
            }
            catch (SocketException e)
            {
                Console.WriteLine("HandleRead: Threw {0}", e);
                return;
            }

            Console.WriteLine("Received {0} bytes from {1}", recvSize, remoteEp);
            Array.Resize <byte>(ref buf, recvSize);

            this.data = buf;
            DNSIncoming msg = new DNSIncoming(buf);

            if (!msg.Valid)
            {
                Console.WriteLine("Incoming msg not valid...");
            }
            else if (msg.IsQuery)
            {
                // Always multicast responses
                if (((IPEndPoint)remoteEp).Port == Constants.MDNS_PORT)
                {
                    this.zc.HandleQuery(msg, Constants.MDNS_ADDRESS, Constants.MDNS_PORT);
                }
                // If it's not a multicast query, reply via unicast
                // and multicast
                else if (((IPEndPoint)remoteEp).Port == Constants.DNS_PORT)
                {
                    this.zc.HandleQuery(msg, ((IPEndPoint)remoteEp).Address, ((IPEndPoint)remoteEp).Port);
                    this.zc.HandleQuery(msg, Constants.MDNS_ADDRESS, Constants.MDNS_PORT);
                }
            }
            else
            {
                this.zc.HandleResponse(msg);
            }
        }
Beispiel #5
0
        /// <summary>
        /// Deal with incoming query packets.  Provides a response if
        /// possible.
        /// </summary>
        /// <param name="msg">Message.</param>
        /// <param name="address">Address.</param>
        /// <param name="port">Port.</param>
        public void HandleQuery(DNSIncoming msg, IPAddress address, int port)
        {
            DNSOutgoing outgoing = null;

            // Support unicast client responses
            if (port != Constants.MDNS_PORT)
            {
                outgoing = new DNSOutgoing((ushort)QueryFlags.Response | (ushort)Flags.AA,
                                           multicast: false);
                foreach (DNSQuestion question in msg.Questions)
                {
                    outgoing.AddQuestion(question);
                }
            }

            foreach (DNSQuestion question in msg.Questions)
            {
                if (question.Type == DNSType.PTR)
                {
                    if (question.Name == "_services._dns-sd._udp.local.")
                    {
                        foreach (string stype in this.serviceTypes.Keys)
                        {
                            if (outgoing == null)
                            {
                                outgoing = new DNSOutgoing((ushort)QueryFlags.Response | (ushort)Flags.AA);
                            }
                            outgoing.AddAnswer(msg, new DNSPointer(
                                                   "_services._dns-sd._udp.local.", DNSType.PTR,
                                                   DNSClass.IN, Constants.DNS_TTL, stype));
                        }
                    }

                    foreach (ServiceInfo service in this.services.Values)
                    {
                        if (question.Name == service.Type)
                        {
                            if (outgoing == null)
                            {
                                outgoing = new DNSOutgoing((ushort)QueryFlags.Response | (ushort)Flags.AA);
                            }
                            outgoing.AddAnswer(msg, new DNSPointer(
                                                   service.Type, DNSType.PTR,
                                                   DNSClass.IN, Constants.DNS_TTL, service.Name));
                        }
                    }
                }
                else
                {
                    if (outgoing == null)
                    {
                        outgoing = new DNSOutgoing((ushort)QueryFlags.Response | (ushort)Flags.AA);
                    }

                    // Answer A record queries for any service addresses we know
                    if (question.Type == DNSType.A || question.Type == DNSType.ANY)
                    {
                        foreach (ServiceInfo s in this.services.Values)
                        {
                            if (s.Server == question.Name.ToLower())
                            {
                                outgoing.AddAnswer(msg, new DNSAddress(
                                                       question.Name, DNSType.A,
                                                       DNSClass.IN | DNSClass.UNIQUE,
                                                       Constants.DNS_TTL,
                                                       Utilities.AddressToBytes(s.Address)));
                            }
                        }
                    }

                    if (!this.services.ContainsKey(question.Name.ToLower()))
                    {
                        continue;
                    }

                    ServiceInfo service = this.services[question.Name.ToLower()];

                    if (question.Type == DNSType.SRV || question.Type == DNSType.ANY)
                    {
                        outgoing.AddAnswer(msg, new DNSService(
                                               question.Name, DNSType.SRV, DNSClass.IN | DNSClass.UNIQUE,
                                               Constants.DNS_TTL, service.Priority, service.Weight,
                                               service.Port, service.Server));
                    }
                    if (question.Type == DNSType.TXT || question.Type == DNSType.ANY)
                    {
                        outgoing.AddAnswer(msg, new DNSText(
                                               question.Name, DNSType.TXT, DNSClass.IN | DNSClass.UNIQUE,
                                               Constants.DNS_TTL, service.Text));
                    }
                    if (question.Type == DNSType.SRV)
                    {
                        outgoing.AddAdditionalAnswer(new DNSAddress(
                                                         service.Server, DNSType.A, DNSClass.IN | DNSClass.UNIQUE,
                                                         Constants.DNS_TTL, Utilities.AddressToBytes(service.Address)));
                    }
                }
            }
            if (outgoing != null && outgoing.Answers.Count > 0)
            {
                outgoing.ID = msg.ID;
                Send(outgoing, address, port);
            }
        }