コード例 #1
0
ファイル: DnsResourceData.cs プロジェクト: amitla/Pcap.Net
 internal static DnsResourceData Read(DnsDatagram dns, DnsType type, int offsetInDns, int length)
 {
     DnsResourceData prototype = TryGetPrototype(type);
     if (prototype != null)
         return prototype.CreateInstance(dns, offsetInDns, length);
     return new DnsResourceDataAnything(dns.Subsegment(offsetInDns, length));
 }
コード例 #2
0
        internal override DnsResourceData CreateInstance(DnsDatagram dns, int offsetInDns, int length)
        {
            DnsDomainName mailingList;
            DnsDomainName errorMailbox;
            if (!TryRead(out mailingList, out errorMailbox, dns, offsetInDns, length))
                return null;

            return new DnsResourceDataMailingListInfo(mailingList, errorMailbox);
        }
コード例 #3
0
        internal override DnsResourceData CreateInstance(DnsDatagram dns, int offsetInDns, int length)
        {
            ushort preference;
            DnsDomainName mailExchangeHost;
            if (!TryRead(out preference, out mailExchangeHost, dns, offsetInDns, length))
                return null;

            return new DnsResourceDataMailExchange(preference, mailExchangeHost);
        }
コード例 #4
0
        internal override DnsResourceData CreateInstance(DnsDatagram dns, int offsetInDns, int length)
        {
            ushort preference;
            DnsDomainName intermediateHost;
            if (!TryRead(out preference, out intermediateHost, dns, offsetInDns, length))
                return null;

            return new DnsResourceDataRouteThrough(preference, intermediateHost);
        }
コード例 #5
0
        internal override DnsResourceData CreateInstance(DnsDatagram dns, int offsetInDns, int length)
        {
            DnsDomainName mailbox;
            DnsDomainName textDomain;
            if (!TryRead(out mailbox, out textDomain, dns, offsetInDns, length))
                return null;

            return new DnsResourceDataResponsiblePerson(mailbox, textDomain);
        }
コード例 #6
0
        internal override DnsResourceData CreateInstance(DnsDatagram dns, int offsetInDns, int length)
        {
            ushort subtype;
            DnsDomainName hostName;
            if (!TryRead(out subtype, out hostName, dns, offsetInDns, length))
                return null;

            return new DnsResourceDataAfsDatabase((DnsAfsDatabaseSubtype)subtype, hostName);
        }
コード例 #7
0
        internal static bool TryRead(out DnsDomainName first, out DnsDomainName second,
                                     DnsDatagram dns, int offsetInDns, int length)
        {
            List<DnsDomainName> domainNames = ReadDomainNames(dns, offsetInDns, length, NumDomains);
            if (domainNames == null || domainNames.Count != NumDomains)
            {
                first = null;
                second = null;
                return false;
            }

            first = domainNames[0];
            second = domainNames[1];
            return true;
        }
コード例 #8
0
        public override DnsDatagram Query(DnsDatagram request)
        {
            //DoH JSON format request
            DateTime sentAt = DateTime.UtcNow;

            byte[] responseBuffer;

            using (WebClientEx wC = new WebClientEx())
            {
                wC.AddHeader("accept", "application/dns-json");
                wC.AddHeader("host", _server.DnsOverHttpEndPoint.Host + ":" + _server.DnsOverHttpEndPoint.Port);
                wC.UserAgent = "DoH client";
                wC.Proxy     = _proxy;
                wC.Timeout   = _timeout;

                Uri queryUri;

                if (_proxy == null)
                {
                    if (_server.IPEndPoint == null)
                    {
                        _server.RecursiveResolveIPAddress();
                    }

                    queryUri = new Uri(_server.DnsOverHttpEndPoint.Scheme + "://" + _server.IPEndPoint.ToString() + _server.DnsOverHttpEndPoint.PathAndQuery);
                }
                else
                {
                    queryUri = _server.DnsOverHttpEndPoint;
                }

                wC.QueryString.Clear();
                wC.QueryString.Add("name", request.Question[0].Name);
                wC.QueryString.Add("type", Convert.ToString(((int)request.Question[0].Type)));

                responseBuffer = wC.DownloadData(queryUri);
            }

            //parse response
            dynamic jsonResponse = JsonConvert.DeserializeObject(Encoding.ASCII.GetString(responseBuffer));

            DnsDatagram response = new DnsDatagram(jsonResponse);

            response.SetMetadata(new DnsDatagramMetadata(_server, _protocol, responseBuffer.Length, (DateTime.UtcNow - sentAt).TotalMilliseconds));

            return(response);
        }
コード例 #9
0
        protected override void Parse(Stream s)
        {
            _algorithmName = DnsDatagram.DeserializeDomainName(s);
            _timeSigned    = DnsDatagram.ReadUInt48NetworkOrder(s);
            _fudge         = DnsDatagram.ReadUInt16NetworkOrder(s);

            ushort macSize = DnsDatagram.ReadUInt16NetworkOrder(s);

            _mac = s.ReadBytes(macSize);

            _originalID = DnsDatagram.ReadUInt16NetworkOrder(s);
            _error      = (DnsTsigError)DnsDatagram.ReadUInt16NetworkOrder(s);

            ushort otherLen = DnsDatagram.ReadUInt16NetworkOrder(s);

            _otherData = s.ReadBytes(otherLen);
        }
コード例 #10
0
        public void Update(DnsDatagram response, IPAddress clientIpAddress)
        {
            StatsResponseType responseType;
            bool cacheHit;

            if ("blocked".Equals(response.Tag))
            {
                responseType = StatsResponseType.Blocked;
                cacheHit     = true;
            }
            else
            {
                switch (response.Header.RCODE)
                {
                case DnsResponseCode.NoError:
                    responseType = StatsResponseType.NoError;
                    break;

                case DnsResponseCode.ServerFailure:
                    responseType = StatsResponseType.ServerFailure;
                    break;

                case DnsResponseCode.NameError:
                    responseType = StatsResponseType.NameError;
                    break;

                case DnsResponseCode.Refused:
                    responseType = StatsResponseType.Refused;
                    break;

                default:
                    return;
                }

                cacheHit = ("cacheHit".Equals(response.Tag));
            }

            if (response.Header.QDCOUNT > 0)
            {
                Update(response.Question[0], responseType, cacheHit, clientIpAddress);
            }
            else
            {
                Update(new DnsQuestionRecord("", DnsResourceRecordType.ANY, DnsClass.IN), responseType, cacheHit, clientIpAddress);
            }
        }
コード例 #11
0
        private async Task ReadDnsDatagramAsync()
        {
            try
            {
                while (true)
                {
                    //read response datagram
                    DnsDatagram response = await DnsDatagram.ReadFromTcpAsync(_tcpStream, _recvBuffer).WithTimeout(ASYNC_RECEIVE_TIMEOUT);

                    //signal waiting thread of response
                    if (_transactions.TryGetValue(response.Identifier, out Transaction transaction))
                    {
                        transaction.Stopwatch.Stop();

                        response.SetMetadata(new DnsDatagramMetadata(_server, _protocol, response.Size, transaction.Stopwatch.Elapsed.TotalMilliseconds));

                        transaction.ResponseTask.TrySetResult(response);
                    }
                }
            }
            catch (Exception ex)
            {
                await _sendRequestSemaphore.WaitAsync();

                try
                {
                    if (_tcpStream != null)
                    {
                        _tcpStream.Dispose();
                        _tcpStream = null;
                    }

                    foreach (Transaction transaction in _transactions.Values)
                    {
                        transaction.Stopwatch.Stop();
                        transaction.ResponseTask.SetException(ex);
                    }

                    _transactions.Clear();
                }
                finally
                {
                    _sendRequestSemaphore.Release();
                }
            }
        }
コード例 #12
0
        public static async Task <SecondaryZone> CreateAsync(DnsServer dnsServer, string name, string primaryNameServerAddresses = null, DnsTransportProtocol zoneTransferProtocol = DnsTransportProtocol.Tcp, string tsigKeyName = null)
        {
            switch (zoneTransferProtocol)
            {
            case DnsTransportProtocol.Tcp:
            case DnsTransportProtocol.Tls:
                break;

            default:
                throw new NotSupportedException("Zone transfer protocol is not supported: XFR-over-" + zoneTransferProtocol.ToString().ToUpper());
            }

            SecondaryZone secondaryZone = new SecondaryZone(dnsServer, name);

            DnsQuestionRecord soaQuestion = new DnsQuestionRecord(name, DnsResourceRecordType.SOA, DnsClass.IN);
            DnsDatagram       soaResponse;

            if (primaryNameServerAddresses == null)
            {
                soaResponse = await secondaryZone._dnsServer.DirectQueryAsync(soaQuestion);
            }
            else
            {
                DnsClient dnsClient = new DnsClient(primaryNameServerAddresses);

                foreach (NameServerAddress nameServerAddress in dnsClient.Servers)
                {
                    if (nameServerAddress.IsIPEndPointStale)
                    {
                        await nameServerAddress.ResolveIPAddressAsync(secondaryZone._dnsServer, secondaryZone._dnsServer.PreferIPv6);
                    }
                }

                dnsClient.Proxy      = secondaryZone._dnsServer.Proxy;
                dnsClient.PreferIPv6 = secondaryZone._dnsServer.PreferIPv6;

                DnsDatagram soaRequest = new DnsDatagram(0, false, DnsOpcode.StandardQuery, false, false, false, false, false, false, DnsResponseCode.NoError, new DnsQuestionRecord[] { soaQuestion }, null, null, null, DnsDatagram.EDNS_DEFAULT_UDP_PAYLOAD_SIZE);

                if (string.IsNullOrEmpty(tsigKeyName))
                {
                    soaResponse = await dnsClient.ResolveAsync(soaRequest);
                }
                else if ((dnsServer.TsigKeys is not null) && dnsServer.TsigKeys.TryGetValue(tsigKeyName, out TsigKey key))
                {
                    soaResponse = await dnsClient.ResolveAsync(soaRequest, key, REFRESH_TSIG_FUDGE);
                }
コード例 #13
0
ファイル: StubZone.cs プロジェクト: yangmain/DnsServer
        public static async Task <StubZone> CreateAsync(DnsServer dnsServer, string name, string primaryNameServerAddresses = null)
        {
            StubZone stubZone = new StubZone(name);

            stubZone._dnsServer = dnsServer;

            DnsQuestionRecord soaQuestion = new DnsQuestionRecord(name, DnsResourceRecordType.SOA, DnsClass.IN);
            DnsDatagram       soaResponse = null;

            if (primaryNameServerAddresses == null)
            {
                soaResponse = await stubZone._dnsServer.DirectQueryAsync(soaQuestion);
            }
            else
            {
                DnsClient dnsClient = new DnsClient(primaryNameServerAddresses);

                dnsClient.Proxy      = stubZone._dnsServer.Proxy;
                dnsClient.PreferIPv6 = stubZone._dnsServer.PreferIPv6;

                soaResponse = await dnsClient.ResolveAsync(soaQuestion);
            }

            if ((soaResponse == null) || (soaResponse.Answer.Count == 0) || (soaResponse.Answer[0].Type != DnsResourceRecordType.SOA))
            {
                throw new DnsServerException("DNS Server failed to find SOA record for: " + name);
            }

            DnsSOARecord receivedSoa = soaResponse.Answer[0].RDATA as DnsSOARecord;

            DnsSOARecord soa = new DnsSOARecord(receivedSoa.PrimaryNameServer, receivedSoa.ResponsiblePerson, receivedSoa.Serial - 1, receivedSoa.Refresh, receivedSoa.Retry, receivedSoa.Expire, receivedSoa.Minimum);

            DnsResourceRecord[] soaRR = new DnsResourceRecord[] { new DnsResourceRecord(stubZone._name, DnsResourceRecordType.SOA, DnsClass.IN, soa.Refresh, soa) };

            if (!string.IsNullOrEmpty(primaryNameServerAddresses))
            {
                soaRR[0].SetGlueRecords(primaryNameServerAddresses);
            }

            stubZone._entries[DnsResourceRecordType.SOA] = soaRR;

            stubZone._isExpired    = true; //new stub zone is considered expired till it refreshes
            stubZone._refreshTimer = new Timer(stubZone.RefreshTimerCallback, null, Timeout.Infinite, Timeout.Infinite);

            return(stubZone);
        }
コード例 #14
0
        private DnsDatagram GetReferralResponse(DnsDatagram request, AuthZone delegationZone, bool isRecursionAllowed)
        {
            IReadOnlyList <DnsResourceRecord> authority;

            if (delegationZone is StubZone)
            {
                authority = delegationZone.GetRecords(DnsResourceRecordType.NS); //stub zone has no authority so cant query
            }
            else
            {
                authority = delegationZone.QueryRecords(DnsResourceRecordType.NS);
            }

            IReadOnlyList <DnsResourceRecord> additional = GetAdditionalRecords(authority);

            return(new DnsDatagram(request.Identifier, true, DnsOpcode.StandardQuery, false, false, request.RecursionDesired, isRecursionAllowed, false, false, DnsResponseCode.NoError, request.Question, null, authority, additional));
        }
コード例 #15
0
        public DnsDatagram Query(DnsDatagram request)
        {
            List <Uri> blockLists = IsZoneBlocked(request.Question[0].Name.ToLower());

            if (blockLists == null)
            {
                //zone not blocked
                return(null);
            }

            //zone is blocked
            DnsResourceRecord[] answers   = null;
            DnsResourceRecord[] authority = null;

            switch (request.Question[0].Type)
            {
            case DnsResourceRecordType.A:
                answers = new DnsResourceRecord[] { new DnsResourceRecord(request.Question[0].Name, DnsResourceRecordType.A, request.Question[0].Class, 60, _aRecord) };
                break;

            case DnsResourceRecordType.AAAA:
                answers = new DnsResourceRecord[] { new DnsResourceRecord(request.Question[0].Name, DnsResourceRecordType.AAAA, request.Question[0].Class, 60, _aaaaRecord) };
                break;

            case DnsResourceRecordType.NS:
                answers = new DnsResourceRecord[] { new DnsResourceRecord(request.Question[0].Name, DnsResourceRecordType.NS, request.Question[0].Class, 60, _nsRecord) };
                break;

            case DnsResourceRecordType.TXT:
                answers = new DnsResourceRecord[blockLists.Count];

                for (int i = 0; i < answers.Length; i++)
                {
                    answers[i] = new DnsResourceRecord(request.Question[0].Name, DnsResourceRecordType.TXT, request.Question[0].Class, 60, new DnsTXTRecord("blockList=" + blockLists[i].AbsoluteUri + "; domain=" + request.Question[0].Name));
                }

                break;

            default:
                authority = new DnsResourceRecord[] { new DnsResourceRecord(request.Question[0].Name, DnsResourceRecordType.SOA, request.Question[0].Class, 60, _soaRecord) };
                break;
            }

            return(new DnsDatagram(request.Identifier, true, DnsOpcode.StandardQuery, true, false, request.RecursionDesired, true, false, false, DnsResponseCode.NoError, request.Question, answers, authority));
        }
コード例 #16
0
ファイル: SecondaryZone.cs プロジェクト: zhouzu/DnsServer
        public SecondaryZone(DnsServer dnsServer, string name, string primaryNameServerAddresses = null)
            : base(name)
        {
            _dnsServer = dnsServer;

            DnsQuestionRecord soaQuestion = new DnsQuestionRecord(name, DnsResourceRecordType.SOA, DnsClass.IN);
            DnsDatagram       soaResponse = null;

            if (primaryNameServerAddresses == null)
            {
                soaResponse = _dnsServer.DirectQuery(soaQuestion);
            }
            else
            {
                DnsClient dnsClient = new DnsClient(primaryNameServerAddresses);

                dnsClient.Proxy      = _dnsServer.Proxy;
                dnsClient.PreferIPv6 = _dnsServer.PreferIPv6;
                dnsClient.Retries    = _dnsServer.Retries;
                dnsClient.Timeout    = _dnsServer.Timeout;

                soaResponse = dnsClient.Resolve(soaQuestion);
            }

            if ((soaResponse == null) || (soaResponse.Answer.Count == 0) || (soaResponse.Answer[0].Type != DnsResourceRecordType.SOA))
            {
                throw new DnsServerException("DNS Server failed to find SOA record for: " + name);
            }

            DnsSOARecord receivedSoa = soaResponse.Answer[0].RDATA as DnsSOARecord;

            DnsSOARecord soa = new DnsSOARecord(receivedSoa.PrimaryNameServer, receivedSoa.ResponsiblePerson, receivedSoa.Serial - 1, receivedSoa.Refresh, receivedSoa.Retry, receivedSoa.Expire, receivedSoa.Minimum);

            DnsResourceRecord[] soaRR = new DnsResourceRecord[] { new DnsResourceRecord(_name, DnsResourceRecordType.SOA, DnsClass.IN, soa.Refresh, soa) };

            if (!string.IsNullOrEmpty(primaryNameServerAddresses))
            {
                soaRR[0].SetGlueRecords(primaryNameServerAddresses);
            }

            _entries[DnsResourceRecordType.SOA] = soaRR;

            _isExpired    = true; //new secondary zone is considered expired till it refreshes
            _refreshTimer = new Timer(RefreshTimerCallback, null, Timeout.Infinite, Timeout.Infinite);
        }
コード例 #17
0
ファイル: CacheZoneManager.cs プロジェクト: IMULMUL/DnsServer
        public DnsDatagram QueryClosestDelegation(DnsDatagram request)
        {
            _ = _root.FindZone(request.Question[0].Name, out CacheZone delegation, out _, out _);
            if (delegation is not null)
            {
                //return closest name servers in delegation
                IReadOnlyList <DnsResourceRecord> closestAuthority = delegation.QueryRecords(DnsResourceRecordType.NS, false, true);
                if ((closestAuthority.Count > 0) && (closestAuthority[0].Type == DnsResourceRecordType.NS) && (closestAuthority[0].Name.Length > 0)) //dont trust root name servers from cache!
                {
                    IReadOnlyList <DnsResourceRecord> additional = GetAdditionalRecords(closestAuthority, false);

                    return(new DnsDatagram(request.Identifier, true, DnsOpcode.StandardQuery, false, false, request.RecursionDesired, true, false, false, DnsResponseCode.NoError, request.Question, null, closestAuthority, additional));
                }
            }

            //no cached delegation found
            return(null);
        }
コード例 #18
0
ファイル: CNAME.cs プロジェクト: jessenich/DnsServer
        public Task <DnsDatagram> ProcessRequestAsync(DnsDatagram request, IPEndPoint remoteEP, string zoneName, uint appRecordTtl, string appRecordData, bool isRecursionAllowed, IDnsServer dnsServer)
        {
            dynamic jsonAppRecordData = JsonConvert.DeserializeObject(appRecordData);
            dynamic jsonCountry;

            if (_mmCountryReader.TryCountry(remoteEP.Address, out CountryResponse response))
            {
                jsonCountry = jsonAppRecordData[response.Country.IsoCode];
                if (jsonCountry == null)
                {
                    jsonCountry = jsonAppRecordData["default"];
                }
            }
            else
            {
                jsonCountry = jsonAppRecordData["default"];
            }

            if (jsonCountry == null)
            {
                return(Task.FromResult <DnsDatagram>(null));
            }

            string cname = jsonCountry.Value;

            if (string.IsNullOrEmpty(cname))
            {
                return(Task.FromResult <DnsDatagram>(null));
            }

            IReadOnlyList <DnsResourceRecord> answers;

            if (request.Question[0].Name.Equals(zoneName, StringComparison.OrdinalIgnoreCase)) //check for zone apex
            {
                answers = new DnsResourceRecord[] { new DnsResourceRecord(request.Question[0].Name, DnsResourceRecordType.ANAME, DnsClass.IN, appRecordTtl, new DnsANAMERecord(cname)) }
            }
            ;                                                                                                                                                                             //use ANAME
            else
            {
                answers = new DnsResourceRecord[] { new DnsResourceRecord(request.Question[0].Name, DnsResourceRecordType.CNAME, DnsClass.IN, appRecordTtl, new DnsCNAMERecord(cname)) }
            };

            return(Task.FromResult(new DnsDatagram(request.Identifier, true, request.OPCODE, true, false, request.RecursionDesired, isRecursionAllowed, false, false, DnsResponseCode.NoError, request.Question, answers)));
        }
コード例 #19
0
        protected override void ParseOptionValue(Stream s)
        {
            if (s.Length < 3)
            {
                throw new InvalidDataException();
            }

            int flags = s.ReadByte();

            if (flags < 0)
            {
                throw new EndOfStreamException();
            }

            _flags = (ClientFullyQualifiedDomainNameFlags)flags;

            int rcode;

            rcode = s.ReadByte();
            if (rcode < 0)
            {
                throw new EndOfStreamException();
            }

            _rcode1 = (byte)rcode;

            rcode = s.ReadByte();
            if (rcode < 0)
            {
                throw new EndOfStreamException();
            }

            _rcode2 = (byte)rcode;

            if (_flags.HasFlag(ClientFullyQualifiedDomainNameFlags.EncodeUsingCanonicalWireFormat))
            {
                _domainName = DnsDatagram.DeserializeDomainName(s);
            }
            else
            {
                _domainName = Encoding.ASCII.GetString(s.ReadBytes((int)s.Length - 3));
            }
        }
コード例 #20
0
        private DnsDatagram DnsApplicationQueryClosestDelegation(DnsDatagram request)
        {
            if ((_dnsApplicationManager.DnsAuthoritativeRequestHandlers.Count < 1) || (request.Question.Count != 1))
            {
                return(null);
            }

            IPEndPoint        localEP       = new IPEndPoint(IPAddress.Any, 0);
            DnsQuestionRecord question      = request.Question[0];
            string            currentDomain = question.Name;

            while (true)
            {
                DnsDatagram nsRequest = new DnsDatagram(0, false, DnsOpcode.StandardQuery, false, false, true, false, false, false, DnsResponseCode.NoError, new DnsQuestionRecord[] { new DnsQuestionRecord(currentDomain, DnsResourceRecordType.NS, DnsClass.IN) });

                foreach (IDnsAuthoritativeRequestHandler requestHandler in _dnsApplicationManager.DnsAuthoritativeRequestHandlers)
                {
                    DnsDatagram nsResponse = requestHandler.ProcessRequestAsync(nsRequest, localEP, DnsTransportProtocol.Tcp, false).Sync();
                    if (nsResponse is not null)
                    {
                        if ((nsResponse.Answer.Count > 0) && (nsResponse.Answer[0].Type == DnsResourceRecordType.NS))
                        {
                            return(new DnsDatagram(request.Identifier, true, nsResponse.OPCODE, nsResponse.AuthoritativeAnswer, nsResponse.Truncation, nsResponse.RecursionDesired, nsResponse.RecursionAvailable, nsResponse.AuthenticData, nsResponse.CheckingDisabled, nsResponse.RCODE, request.Question, null, nsResponse.Answer, nsResponse.Additional));
                        }
                        else if ((nsResponse.Authority.Count > 0) && (nsResponse.Authority[0].Type == DnsResourceRecordType.NS))
                        {
                            return(new DnsDatagram(request.Identifier, true, nsResponse.OPCODE, nsResponse.AuthoritativeAnswer, nsResponse.Truncation, nsResponse.RecursionDesired, nsResponse.RecursionAvailable, nsResponse.AuthenticData, nsResponse.CheckingDisabled, nsResponse.RCODE, request.Question, null, nsResponse.Authority, nsResponse.Additional));
                        }
                    }
                }

                //get parent domain
                int i = currentDomain.IndexOf('.');
                if (i < 0)
                {
                    break;
                }

                currentDomain = currentDomain.Substring(i + 1);
            }

            return(null);
        }
コード例 #21
0
        public Task <DnsRequestControllerAction> GetRequestActionAsync(DnsDatagram request, IPEndPoint remoteEP, DnsTransportProtocol protocol)
        {
            if (!_enableBlocking)
            {
                return(Task.FromResult(DnsRequestControllerAction.Allow));
            }

            IPAddress remoteIp = remoteEP.Address;

            foreach (NetworkAddress allowedNetwork in _allowedNetworks)
            {
                if (allowedNetwork.Contains(remoteIp))
                {
                    return(Task.FromResult(DnsRequestControllerAction.Allow));
                }
            }

            foreach (NetworkAddress blockedNetwork in _blockedNetworks)
            {
                if (blockedNetwork.Contains(remoteIp))
                {
                    return(Task.FromResult(DnsRequestControllerAction.DropSilently));
                }
            }

            if (request.Question.Count != 1)
            {
                return(Task.FromResult(DnsRequestControllerAction.DropSilently));
            }

            DnsQuestionRecord requestQuestion = request.Question[0];

            foreach (BlockedQuestion blockedQuestion in _blockedQuestions)
            {
                if (blockedQuestion.Matches(requestQuestion))
                {
                    return(Task.FromResult(DnsRequestControllerAction.DropSilently));
                }
            }

            return(Task.FromResult(DnsRequestControllerAction.Allow));
        }
コード例 #22
0
ファイル: StatsManager.cs プロジェクト: orf53975/DnsServer
        public void Update(DnsDatagram response, IPAddress clientIpAddress)
        {
            StatsResponseType responseType;

            if (response.Tag == "blocked")
            {
                responseType = StatsResponseType.Blocked;
            }
            else
            {
                switch (response.Header.RCODE)
                {
                case DnsResponseCode.NoError:
                    responseType = StatsResponseType.NoError;
                    break;

                case DnsResponseCode.ServerFailure:
                    responseType = StatsResponseType.ServerFailure;
                    break;

                case DnsResponseCode.NameError:
                    responseType = StatsResponseType.NameError;
                    break;

                case DnsResponseCode.Refused:
                    responseType = StatsResponseType.Refused;
                    break;

                default:
                    return;
                }
            }

            if (response.Header.QDCOUNT > 0)
            {
                Update(response.Question[0].Name, response.Question[0].Type, responseType, clientIpAddress);
            }
            else
            {
                Update("", DnsResourceRecordType.ANY, responseType, clientIpAddress);
            }
        }
コード例 #23
0
        private async Task ReadDnsDatagramAsync()
        {
            try
            {
                while (true)
                {
                    //read response datagram
                    DnsDatagram response = await DnsDatagram.ReadFromTcpAsync(_tcpStream, _recvBuffer).WithTimeout(ASYNC_RECEIVE_TIMEOUT);

                    //signal response
                    if (_transactions.TryGetValue(response.Identifier, out Transaction transaction))
                    {
                        transaction.SetResponse(response, _server, _protocol);
                    }
                }
            }
            catch (Exception ex)
            {
                await _sendRequestSemaphore.WaitAsync();

                try
                {
                    if (_tcpStream != null)
                    {
                        _tcpStream.Dispose();
                        _tcpStream = null;
                    }

                    foreach (KeyValuePair <ushort, Transaction> transaction in _transactions)
                    {
                        transaction.Value.SetException(ex);
                    }

                    _transactions.Clear();
                }
                finally
                {
                    _sendRequestSemaphore.Release();
                }
            }
        }
コード例 #24
0
        public Task <DnsDatagram> ProcessRequestAsync(DnsDatagram request, IPEndPoint remoteEP, string zoneName, uint appRecordTtl, string appRecordData, bool isRecursionAllowed, IDnsServer dnsServer)
        {
            DnsResourceRecord answer;

            switch (request.Question[0].Type)
            {
            case DnsResourceRecordType.A:
                if (remoteEP.AddressFamily == AddressFamily.InterNetwork)
                {
                    answer = new DnsResourceRecord(request.Question[0].Name, DnsResourceRecordType.A, DnsClass.IN, appRecordTtl, new DnsARecord(remoteEP.Address));
                }
                else
                {
                    return(Task.FromResult <DnsDatagram>(null));
                }

                break;

            case DnsResourceRecordType.AAAA:
                if (remoteEP.AddressFamily == AddressFamily.InterNetworkV6)
                {
                    answer = new DnsResourceRecord(request.Question[0].Name, DnsResourceRecordType.AAAA, DnsClass.IN, appRecordTtl, new DnsAAAARecord(remoteEP.Address));
                }
                else
                {
                    return(Task.FromResult <DnsDatagram>(null));
                }

                break;

            case DnsResourceRecordType.TXT:
                answer = new DnsResourceRecord(request.Question[0].Name, DnsResourceRecordType.TXT, DnsClass.IN, appRecordTtl, new DnsTXTRecord(remoteEP.Address.ToString()));
                break;

            default:
                return(Task.FromResult <DnsDatagram>(null));
            }

            return(Task.FromResult(new DnsDatagram(request.Identifier, true, request.OPCODE, true, false, request.RecursionDesired, isRecursionAllowed, false, false, DnsResponseCode.NoError, request.Question, new DnsResourceRecord[] { answer })));
        }
コード例 #25
0
        private void PacketHandler(Packet packet)
        {
            IpV4Datagram ip  = packet.Ethernet.IpV4;
            DnsDatagram  dns = ip.Udp.Dns;
            IEnumerable <DnsResourceRecord> queries = packet.Ethernet.IpV4.Udp.Dns.ResourceRecords;

            if (queries != null || queries.ToList().Count > 0)
            {
                if (dns.IsQuery)
                {
                    Query query = new Query(dns.Id, ip.Source, ip.Destination, ip.Protocol, queries);
                    repo.Events.Add(query);
                    MessageHelper.PrintMessage(query.PrintOutQueryInfo());
                }
                else if (dns.IsResponse)
                {
                    Response res = new Response(dns.Id, dns.ResponseCode, dns.DataResourceRecords, ip.Source, ip.Destination, ip.Protocol, queries);
                    repo.Events.Add(res);
                    MessageHelper.PrintMessage(res.PrintOutQueryInfo());
                }
            }
        }
コード例 #26
0
        public virtual DnsDatagram Query(DnsDatagram request, bool serveStale = false)
        {
            DnsDatagram authResponse = _authZoneManager.Query(request, true);

            if ((authResponse != null))
            {
                if ((authResponse.Answer.Count > 0) || ((authResponse.Authority.Count > 0) && (authResponse.Authority[0].Type == DnsResourceRecordType.SOA)))
                {
                    return(authResponse);
                }
            }

            DnsDatagram cacheResponse = _cacheZoneManager.Query(request, serveStale);

            if (cacheResponse != null)
            {
                if ((cacheResponse.Answer.Count > 0) || ((cacheResponse.Authority.Count > 0) && (cacheResponse.Authority[0].Type == DnsResourceRecordType.SOA)))
                {
                    return(cacheResponse);
                }
            }

            if ((authResponse != null) && (authResponse.Authority.Count > 0))
            {
                if ((cacheResponse != null) && (cacheResponse.Authority.Count > 0))
                {
                    if (cacheResponse.Authority[0].Name.Length > authResponse.Authority[0].Name.Length)
                    {
                        return(cacheResponse);
                    }
                }

                return(authResponse);
            }
            else
            {
                return(cacheResponse);
            }
        }
コード例 #27
0
        private static async Task ResolveNameServerAddressesAsync(DnsServer dnsServer, string nsDomain, int port, DnsTransportProtocol protocol, List <NameServerAddress> outNameServers)
        {
            try
            {
                DnsDatagram response = await dnsServer.DirectQueryAsync(new DnsQuestionRecord(nsDomain, DnsResourceRecordType.A, DnsClass.IN));

                if (response.Answer.Count > 0)
                {
                    IReadOnlyList <IPAddress> addresses = DnsClient.ParseResponseA(response);
                    foreach (IPAddress address in addresses)
                    {
                        outNameServers.Add(new NameServerAddress(nsDomain, new IPEndPoint(address, port), protocol));
                    }
                }
            }
            catch
            { }

            if (dnsServer.PreferIPv6)
            {
                try
                {
                    DnsDatagram response = await dnsServer.DirectQueryAsync(new DnsQuestionRecord(nsDomain, DnsResourceRecordType.AAAA, DnsClass.IN));

                    if (response.Answer.Count > 0)
                    {
                        IReadOnlyList <IPAddress> addresses = DnsClient.ParseResponseAAAA(response);
                        foreach (IPAddress address in addresses)
                        {
                            outNameServers.Add(new NameServerAddress(nsDomain, new IPEndPoint(address, port), protocol));
                        }
                    }
                }
                catch
                { }
            }
        }
コード例 #28
0
        public DnsHINFORecord(dynamic jsonResourceRecord)
        {
            _rdLength = Convert.ToUInt16(jsonResourceRecord.data.Value.Length);

            string value = DnsDatagram.DecodeCharacterString(jsonResourceRecord.data.Value);

            string[] parts;

            if (value.Contains("\" \""))
            {
                parts = value.Split(new string[] { "\" \"" }, StringSplitOptions.None);
            }
            else
            {
                parts = value.Split(new char[] { ' ' }, StringSplitOptions.None);
            }

            _cpu = parts[0];

            if (parts.Length > 1)
            {
                _os = parts[1];
            }
        }
コード例 #29
0
        public override async Task <DnsDatagram> QueryAsync(DnsDatagram request, int timeout, int retries, CancellationToken cancellationToken)
        {
            _lastQueried = DateTime.UtcNow;

            async Task <HttpRequestMessage> GetHttpRequest()
            {
                //serialize request
                byte[] requestBuffer;

                using (MemoryStream mS = new MemoryStream(32))
                {
                    request.WriteTo(mS);
                    requestBuffer = mS.ToArray();
                }

                Uri queryUri;

                if (_proxy == null)
                {
                    if (_server.IsIPEndPointStale)
                    {
                        await _server.RecursiveResolveIPAddressAsync();
                    }

                    queryUri = new Uri(_server.DnsOverHttpEndPoint.Scheme + "://" + _server.IPEndPoint.ToString() + _server.DnsOverHttpEndPoint.PathAndQuery);
                }
                else
                {
                    if (_server.IPEndPoint == null)
                    {
                        queryUri = _server.DnsOverHttpEndPoint;
                    }
                    else
                    {
                        queryUri = new Uri(_server.DnsOverHttpEndPoint.Scheme + "://" + _server.IPEndPoint.ToString() + _server.DnsOverHttpEndPoint.PathAndQuery);
                    }
                }

                HttpRequestMessage httpRequest = new HttpRequestMessage(HttpMethod.Post, queryUri);

                httpRequest.Content = new ByteArrayContent(requestBuffer);
                httpRequest.Content.Headers.ContentType = new MediaTypeHeaderValue("application/dns-message");

                return(httpRequest);
            }

            //DoH wire format request
            Stopwatch stopwatch = new Stopwatch();
            int       retry     = 0;

            while (retry < retries) //retry loop
            {
                retry++;

                if (cancellationToken.IsCancellationRequested)
                {
                    return(await Task.FromCanceled <DnsDatagram>(cancellationToken)); //task cancelled
                }
                stopwatch.Start();

                Task <HttpResponseMessage> task = _httpClient.SendAsync(await GetHttpRequest(), cancellationToken);

                using (CancellationTokenSource timeoutCancellationTokenSource = new CancellationTokenSource())
                {
                    using (CancellationTokenRegistration ctr = cancellationToken.Register(delegate() { timeoutCancellationTokenSource.Cancel(); }))
                    {
                        if (await Task.WhenAny(task, Task.Delay(timeout, timeoutCancellationTokenSource.Token)) != task)
                        {
                            continue; //request timed out; retry
                        }
                    }

                    timeoutCancellationTokenSource.Cancel(); //to stop delay task
                }

                HttpResponseMessage httpResponse = await task;

                stopwatch.Stop();
                httpResponse.EnsureSuccessStatusCode();

                byte[] responseBuffer = await httpResponse.Content.ReadAsByteArrayAsync(cancellationToken);

                //parse response
                using (MemoryStream mS = new MemoryStream(responseBuffer, false))
                {
                    DnsDatagram response = DnsDatagram.ReadFrom(mS);

                    response.SetMetadata(_server, _protocol, stopwatch.Elapsed.TotalMilliseconds);

                    if (response.Identifier != request.Identifier)
                    {
                        throw new DnsClientResponseValidationException("Invalid response was received: query ID mismatch.");
                    }

                    if (response.Question.Count != request.Question.Count)
                    {
                        throw new DnsClientResponseValidationException("Invalid response was received: question count mismatch.");
                    }

                    for (int i = 0; i < response.Question.Count; i++)
                    {
                        if (request.Question[i].ZoneCut == null)
                        {
                            if (!response.Question[i].Name.Equals(request.Question[i].Name, StringComparison.Ordinal))
                            {
                                throw new DnsClientResponseValidationException("Invalid response was received: QNAME mismatch.");
                            }

                            if (response.Question[i].Type != request.Question[i].Type)
                            {
                                throw new DnsClientResponseValidationException("Invalid response was received: QTYPE mismatch.");
                            }
                        }
                        else
                        {
                            if (!response.Question[i].Name.Equals(request.Question[i].MinimizedName, StringComparison.Ordinal))
                            {
                                throw new DnsClientResponseValidationException("Invalid response was received: QNAME mismatch.");
                            }

                            if (response.Question[i].Type != request.Question[i].MinimizedType)
                            {
                                throw new DnsClientResponseValidationException("Invalid response was received: QTYPE mismatch.");
                            }
                        }

                        if (response.Question[i].Class != request.Question[i].Class)
                        {
                            throw new DnsClientResponseValidationException("Invalid response was received: QCLASS mismatch.");
                        }
                    }

                    return(response);
                }
            }

            throw new DnsClientException("DnsClient failed to resolve the request: request timed out.");
        }
コード例 #30
0
ファイル: AuthZone.cs プロジェクト: piccobit/DnsServer
        private static async Task <IReadOnlyList <NameServerAddress> > GetNameServerAddressesAsync(DnsServer dnsServer, DnsResourceRecord record)
        {
            string nsDomain;

            switch (record.Type)
            {
            case DnsResourceRecordType.NS:
                nsDomain = (record.RDATA as DnsNSRecord).NameServer;
                break;

            case DnsResourceRecordType.SOA:
                nsDomain = (record.RDATA as DnsSOARecord).PrimaryNameServer;
                break;

            default:
                throw new InvalidOperationException();
            }

            List <NameServerAddress> nameServers = new List <NameServerAddress>(2);

            IReadOnlyList <DnsResourceRecord> glueRecords = record.GetGlueRecords();

            if (glueRecords.Count > 0)
            {
                foreach (DnsResourceRecord glueRecord in glueRecords)
                {
                    switch (glueRecord.Type)
                    {
                    case DnsResourceRecordType.A:
                        nameServers.Add(new NameServerAddress(nsDomain, (glueRecord.RDATA as DnsARecord).Address));
                        break;

                    case DnsResourceRecordType.AAAA:
                        if (dnsServer.PreferIPv6)
                        {
                            nameServers.Add(new NameServerAddress(nsDomain, (glueRecord.RDATA as DnsAAAARecord).Address));
                        }

                        break;
                    }
                }
            }
            else
            {
                //resolve addresses
                try
                {
                    DnsDatagram response = await dnsServer.DirectQueryAsync(new DnsQuestionRecord(nsDomain, DnsResourceRecordType.A, DnsClass.IN));

                    if ((response != null) && (response.Answer.Count > 0))
                    {
                        IReadOnlyList <IPAddress> addresses = DnsClient.ParseResponseA(response);
                        foreach (IPAddress address in addresses)
                        {
                            nameServers.Add(new NameServerAddress(nsDomain, address));
                        }
                    }
                }
                catch
                { }

                if (dnsServer.PreferIPv6)
                {
                    try
                    {
                        DnsDatagram response = await dnsServer.DirectQueryAsync(new DnsQuestionRecord(nsDomain, DnsResourceRecordType.AAAA, DnsClass.IN));

                        if ((response != null) && (response.Answer.Count > 0))
                        {
                            IReadOnlyList <IPAddress> addresses = DnsClient.ParseResponseAAAA(response);
                            foreach (IPAddress address in addresses)
                            {
                                nameServers.Add(new NameServerAddress(nsDomain, address));
                            }
                        }
                    }
                    catch
                    { }
                }
            }

            return(nameServers);
        }
コード例 #31
0
 protected override void WriteRecordData(Stream s, List <DnsDomainOffset> domainEntries)
 {
     DnsDatagram.WriteUInt16NetworkOrder(_preference, s);
     DnsDatagram.SerializeDomainName(_exchange, s, domainEntries);
 }
コード例 #32
0
 protected override void Parse(Stream s)
 {
     _preference = DnsDatagram.ReadUInt16NetworkOrder(s);
     _exchange   = DnsDatagram.DeserializeDomainName(s);
 }
コード例 #33
0
ファイル: DnsResourceData.cs プロジェクト: amitla/Pcap.Net
 internal abstract DnsResourceData CreateInstance(DnsDatagram dns, int offsetInDns, int length);
コード例 #34
0
ファイル: StubZone.cs プロジェクト: yangmain/DnsServer
        private async Task <bool> RefreshZoneAsync(IReadOnlyList <NameServerAddress> primaryNameServers)
        {
            try
            {
                {
                    LogManager log = _dnsServer.LogManager;
                    if (log != null)
                    {
                        log.Write("DNS Server has started zone refresh for stub zone: " + _name);
                    }
                }

                DnsClient client = new DnsClient(primaryNameServers);
                client.Timeout = REFRESH_TIMEOUT;
                client.Retries = REFRESH_RETRIES;

                DnsDatagram soaRequest  = new DnsDatagram(0, false, DnsOpcode.StandardQuery, false, false, false, false, false, false, DnsResponseCode.NoError, new DnsQuestionRecord[] { new DnsQuestionRecord(_name, DnsResourceRecordType.SOA, DnsClass.IN) });
                DnsDatagram soaResponse = await client.ResolveAsync(soaRequest);

                if (soaResponse.RCODE != DnsResponseCode.NoError)
                {
                    LogManager log = _dnsServer.LogManager;
                    if (log != null)
                    {
                        log.Write("DNS Server received RCODE=" + soaResponse.RCODE.ToString() + " for '" + _name + "' stub zone refresh from: " + soaResponse.Metadata.NameServerAddress.ToString());
                    }

                    return(false);
                }

                if (soaResponse.Answer.Count < 1)
                {
                    LogManager log = _dnsServer.LogManager;
                    if (log != null)
                    {
                        log.Write("DNS Server received an empty response for SOA query for '" + _name + "' stub zone refresh from: " + soaResponse.Metadata.NameServerAddress.ToString());
                    }

                    return(false);
                }

                DnsSOARecord currentSoaRecord  = _entries[DnsResourceRecordType.SOA][0].RDATA as DnsSOARecord;
                DnsSOARecord receivedSoaRecord = soaResponse.Answer[0].RDATA as DnsSOARecord;

                //compare using sequence space arithmetic
                if (!currentSoaRecord.IsZoneUpdateAvailable(receivedSoaRecord))
                {
                    LogManager log = _dnsServer.LogManager;
                    if (log != null)
                    {
                        log.Write("DNS Server successfully checked for update to '" + _name + "' stub zone from: " + soaResponse.Metadata.NameServerAddress.ToString());
                    }

                    return(true);
                }

                //update available; do zone sync with TCP transport
                List <NameServerAddress> tcpNameServers = new List <NameServerAddress>();

                foreach (NameServerAddress nameServer in primaryNameServers)
                {
                    tcpNameServers.Add(new NameServerAddress(nameServer, DnsTransportProtocol.Tcp));
                }

                primaryNameServers = tcpNameServers;
                client             = new DnsClient(primaryNameServers);
                client.Timeout     = REFRESH_TIMEOUT;
                client.Retries     = REFRESH_RETRIES;

                DnsDatagram nsRequest  = new DnsDatagram(0, false, DnsOpcode.StandardQuery, false, false, false, false, false, false, DnsResponseCode.NoError, new DnsQuestionRecord[] { new DnsQuestionRecord(_name, DnsResourceRecordType.NS, DnsClass.IN) });
                DnsDatagram nsResponse = await client.ResolveAsync(nsRequest);

                if (nsResponse.RCODE != DnsResponseCode.NoError)
                {
                    LogManager log = _dnsServer.LogManager;
                    if (log != null)
                    {
                        log.Write("DNS Server received RCODE=" + nsResponse.RCODE.ToString() + " for '" + _name + "' stub zone refresh from: " + nsResponse.Metadata.NameServerAddress.ToString());
                    }

                    return(false);
                }

                if (nsResponse.Answer.Count < 1)
                {
                    LogManager log = _dnsServer.LogManager;
                    if (log != null)
                    {
                        log.Write("DNS Server received an empty response for NS query for '" + _name + "' stub zone from: " + nsResponse.Metadata.NameServerAddress.ToString());
                    }

                    return(false);
                }

                List <DnsResourceRecord> allRecords = new List <DnsResourceRecord>();

                allRecords.AddRange(nsResponse.Answer);
                allRecords.AddRange(soaResponse.Answer); //to sync latest SOA record

                _dnsServer.AuthZoneManager.SyncRecords(_name, allRecords, nsResponse.Additional, true);

                {
                    LogManager log = _dnsServer.LogManager;
                    if (log != null)
                    {
                        log.Write("DNS Server successfully refreshed '" + _name + "' stub zone from: " + nsResponse.Metadata.NameServerAddress.ToString());
                    }
                }

                return(true);
            }
            catch (Exception ex)
            {
                LogManager log = _dnsServer.LogManager;
                if (log != null)
                {
                    string strNameServers = null;

                    foreach (NameServerAddress nameServer in primaryNameServers)
                    {
                        if (strNameServers == null)
                        {
                            strNameServers = nameServer.ToString();
                        }
                        else
                        {
                            strNameServers += ", " + nameServer.ToString();
                        }
                    }

                    log.Write("DNS Server failed to refresh '" + _name + "' stub zone from: " + strNameServers);
                    log.Write(ex);
                }

                return(false);
            }
        }
コード例 #35
0
 protected override void WriteRecordData(Stream s, List <DnsDomainOffset> domainEntries)
 {
     DnsDatagram.SerializeDomainName(_nameServer, s, domainEntries);
 }
コード例 #36
0
        public Task <DnsDatagram> ProcessRequestAsync(DnsDatagram request, IPEndPoint remoteEP, DnsTransportProtocol protocol, bool isRecursionAllowed, string zoneName, uint appRecordTtl, string appRecordData)
        {
            DnsQuestionRecord question = request.Question[0];

            switch (question.Type)
            {
            case DnsResourceRecordType.A:
            case DnsResourceRecordType.AAAA:
                dynamic jsonAppRecordData = JsonConvert.DeserializeObject(appRecordData);
                dynamic jsonCountry;

                if (_maxMind.DatabaseReader.TryCountry(remoteEP.Address, out CountryResponse response))
                {
                    jsonCountry = jsonAppRecordData[response.Country.IsoCode];
                    if (jsonCountry == null)
                    {
                        jsonCountry = jsonAppRecordData["default"];
                    }
                }
                else
                {
                    jsonCountry = jsonAppRecordData["default"];
                }

                if (jsonCountry == null)
                {
                    return(Task.FromResult <DnsDatagram>(null));
                }

                List <DnsResourceRecord> answers = new List <DnsResourceRecord>();

                switch (question.Type)
                {
                case DnsResourceRecordType.A:
                    foreach (dynamic jsonAddress in jsonCountry)
                    {
                        IPAddress address = IPAddress.Parse(jsonAddress.Value);

                        if (address.AddressFamily == AddressFamily.InterNetwork)
                        {
                            answers.Add(new DnsResourceRecord(question.Name, DnsResourceRecordType.A, DnsClass.IN, appRecordTtl, new DnsARecordData(address)));
                        }
                    }
                    break;

                case DnsResourceRecordType.AAAA:
                    foreach (dynamic jsonAddress in jsonCountry)
                    {
                        IPAddress address = IPAddress.Parse(jsonAddress.Value);

                        if (address.AddressFamily == AddressFamily.InterNetworkV6)
                        {
                            answers.Add(new DnsResourceRecord(question.Name, DnsResourceRecordType.AAAA, DnsClass.IN, appRecordTtl, new DnsAAAARecordData(address)));
                        }
                    }
                    break;
                }

                if (answers.Count == 0)
                {
                    return(Task.FromResult <DnsDatagram>(null));
                }

                if (answers.Count > 1)
                {
                    answers.Shuffle();
                }

                return(Task.FromResult(new DnsDatagram(request.Identifier, true, request.OPCODE, true, false, request.RecursionDesired, isRecursionAllowed, false, false, DnsResponseCode.NoError, request.Question, answers)));

            default:
                return(Task.FromResult <DnsDatagram>(null));
            }
        }
コード例 #37
0
 public void CacheResponse(DnsDatagram response)
 {
     _cacheZoneManager.CacheResponse(response);
 }
コード例 #38
0
 internal sealed override DnsResourceData CreateInstance(DnsDatagram dns, int offsetInDns, int length)
 {
     return CreateInstance(dns.Subsegment(offsetInDns, length));
 }
コード例 #39
0
 protected override void Parse(Stream s)
 {
     _nameServer = DnsDatagram.DeserializeDomainName(s);
 }
コード例 #40
0
ファイル: DnsResourceRecord.cs プロジェクト: amitla/Pcap.Net
        internal static bool TryParseBase(DnsDatagram dns, int offsetInDns,
                                          out DnsDomainName domainName, out DnsType type, out DnsClass dnsClass, out int numBytesRead)
        {
            type = DnsType.Any;
            dnsClass = DnsClass.Any;
            if (!DnsDomainName.TryParse(dns, offsetInDns, dns.Length - offsetInDns, out domainName, out numBytesRead))
                return false;

            if (offsetInDns + numBytesRead + MinimumLengthAfterDomainName > dns.Length)
                return false;

            type = (DnsType)dns.ReadUShort(offsetInDns + numBytesRead + OffsetAfterDomainName.Type, Endianity.Big);
            dnsClass = (DnsClass)dns.ReadUShort(offsetInDns + numBytesRead + OffsetAfterDomainName.DnsClass, Endianity.Big);
            numBytesRead += MinimumLengthAfterDomainName;
            return true;
        }