示例#1
0
        public static Message Read(PacketReader reader)
        {
            Message result = new Message();

            result.TransactionId = reader.ReadUShort();
            result.Flags = new MessageFlags(reader.ReadUShort());

            ushort questions = reader.ReadUShort();
            ushort answers = reader.ReadUShort();
            ushort authorityRecords = reader.ReadUShort();
            ushort additionalRecords = reader.ReadUShort();

            for (int i = 0; i < questions; ++i)
            {
                result.Questions.Add(Question.ReadFrom(reader));
            }

            for (int i = 0; i < answers; ++i)
            {
                result.Answers.Add(ResourceRecord.ReadFrom(reader));
            }

            for (int i = 0; i < authorityRecords; ++i)
            {
                result.AuthorityRecords.Add(ResourceRecord.ReadFrom(reader));
            }

            for (int i = 0; i < additionalRecords; ++i)
            {
                result.AdditionalRecords.Add(ResourceRecord.ReadFrom(reader));
            }

            return result;
        }
        private ResourceRecord[] QueryNetwork(string name, RecordType type)
        {
            ushort transactionId = _nextTransId++;
            string normName = NormalizeDomainName(name);

            Transaction transaction = new Transaction();
            try
            {
                lock (_transactions)
                {
                    _transactions.Add(transactionId, transaction);
                }

                PacketWriter writer = new PacketWriter(1800);
                Message msg = new Message();
                msg.TransactionId = transactionId;
                msg.Flags = new MessageFlags(false, OpCode.Query, false, false, false, false, ResponseCode.Success);
                msg.Questions.Add(new Question() { Name = normName, Type = type, Class = RecordClass.Internet });

                msg.WriteTo(writer);

                byte[] msgBytes = writer.GetBytes();

                IPEndPoint mDnsAddress = new IPEndPoint(IPAddress.Parse("224.0.0.251"), 5353);
                lock (_udpClient)
                {
                    _udpClient.Send(msgBytes, msgBytes.Length, mDnsAddress);
                }

                transaction.CompleteEvent.WaitOne(2000);
            }
            finally
            {
                lock (_transactions)
                {
                    _transactions.Remove(transactionId);
                }
            }

            return transaction.Answers.ToArray();
        }
        /// <summary>
        /// Looks up a record in DNS.
        /// </summary>
        /// <param name="name">The name to lookup</param>
        /// <param name="type">The type of record requested</param>
        /// <returns>The records returned by the DNS server, if any</returns>
        public override ResourceRecord[] Lookup(string name, RecordType type)
        {
            ushort transactionId = _nextTransId++;
            string normName = NormalizeDomainName(name);

            using (UdpClient udpClient = new UdpClient(0))
            {
                IAsyncResult result = udpClient.BeginReceive(null, null);

                PacketWriter writer = new PacketWriter(1800);
                Message msg = new Message();
                msg.TransactionId = transactionId;
                msg.Flags = new MessageFlags(false, OpCode.Query, false, false, false, false, ResponseCode.Success);
                msg.Questions.Add(new Question() { Name = normName, Type = type, Class = RecordClass.Internet });

                msg.WriteTo(writer);

                byte[] msgBytes = writer.GetBytes();

                foreach (var server in _servers)
                {
                    udpClient.Send(msgBytes, msgBytes.Length, server);
                }

                for (int i = 0; i < maxRetries; ++i)
                {
                    DateTime now = DateTime.UtcNow;
                    while (result.AsyncWaitHandle.WaitOne(Math.Max(responseTimeout - (DateTime.UtcNow - now).Milliseconds, 0)))
                    {
                        try
                        {
                            IPEndPoint sourceEndPoint = null;
                            byte[] packetBytes = udpClient.EndReceive(result, ref sourceEndPoint);
                            PacketReader reader = new PacketReader(packetBytes);

                            Message response = Message.Read(reader);

                            if (response.TransactionId == transactionId)
                            {
                                return response.Answers.ToArray();
                            }
                        }
                        catch
                        {
                            // Do nothing - bad packet (probably...)
                        }
                    }
                }
            }

            return null;
        }