Ejemplo n.º 1
0
            public IDnsQueryResponse GetResponse()
            {
                var elapsed = Elapsed();

                if (elapsed <= 0)
                {
                    return(_response);
                }

                var response = new DnsResponseMessage(_response.Header, _response.MessageSize)
                {
                    Audit = (_response as DnsQueryResponse)?.Audit ?? new LookupClientAudit()
                };

                foreach (var record in _response.Questions)
                {
                    response.AddQuestion(record);
                }

                foreach (var record in _response.Answers)
                {
                    var clone = record.Clone();
                    clone.TimeToLive = clone.TimeToLive - elapsed;
                    response.AddAnswer(clone);
                }

                foreach (var record in _response.Additionals)
                {
                    var clone = record.Clone();
                    clone.TimeToLive = clone.TimeToLive - elapsed;
                    response.AddAnswer(clone);
                }

                foreach (var record in _response.Authorities)
                {
                    var clone = record.Clone();
                    clone.TimeToLive = clone.TimeToLive - elapsed;
                    response.AddAnswer(clone);
                }

                var qr = response.AsQueryResponse(_response.NameServer);

                return(qr);
            }
Ejemplo n.º 2
0
        private IDnsQueryResponse ResolveQuery(DnsMessageHandler handler, DnsRequestMessage request, Audit continueAudit = null)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            var audit   = continueAudit ?? new Audit();
            var servers = GetNextServers();

            foreach (var serverInfo in servers)
            {
                var tries = 0;
                do
                {
                    tries++;

                    try
                    {
                        if (EnableAuditTrail)
                        {
                            audit.StartTimer();
                        }

                        DnsResponseMessage response = handler.Query(serverInfo.Endpoint, request, Timeout);

                        if (response.Header.ResultTruncated && UseTcpFallback && !handler.GetType().Equals(typeof(DnsTcpMessageHandler)))
                        {
                            if (EnableAuditTrail)
                            {
                                audit.AuditTruncatedRetryTcp();
                            }

                            return(ResolveQuery(_tcpFallbackHandler, request, audit));
                        }

                        if (EnableAuditTrail)
                        {
                            audit.AuditResolveServers(_endpoints.Count);
                            audit.AuditResponseHeader(response.Header);
                        }

                        if (response.Header.ResponseCode != DnsResponseCode.NoError)
                        {
                            if (EnableAuditTrail)
                            {
                                audit.AuditResponseError(response.Header.ResponseCode);
                            }

                            if (ThrowDnsErrors)
                            {
                                throw new DnsResponseException(response.Header.ResponseCode);
                            }
                        }

                        HandleOptRecords(audit, serverInfo, response);

                        DnsQueryResponse queryResponse = response.AsQueryResponse(serverInfo.Clone());

                        if (EnableAuditTrail)
                        {
                            audit.AuditResponse(queryResponse);
                            audit.AuditEnd(queryResponse);
                            queryResponse.AuditTrail = audit.Build();
                        }

                        Interlocked.Increment(ref StaticLog.ResolveQueryCount);
                        Interlocked.Add(ref StaticLog.ResolveQueryTries, tries);
                        return(queryResponse);
                    }
                    catch (DnsResponseException ex)
                    {
                        audit.AuditException(ex);
                        ex.AuditTrail = audit.Build();
                        throw;
                    }
                    catch (SocketException ex) when(ex.SocketErrorCode == SocketError.AddressFamilyNotSupported)
                    {
                        // this socket error might indicate the server endpoint is actually bad and should be ignored in future queries.
                        DisableServer(serverInfo);
                        break;
                    }
                    catch (Exception ex) when(ex is TimeoutException || handler.IsTransientException(ex))
                    {
                        DisableServer(serverInfo);
                    }
                    catch (Exception ex)
                    {
                        DisableServer(serverInfo);

                        if (ex is OperationCanceledException || ex is TaskCanceledException)
                        {
                            // timeout
                            continue;
                        }

                        audit.AuditException(ex);

                        throw new DnsResponseException(DnsResponseCode.Unassigned, "Unhandled exception", ex)
                              {
                                  AuditTrail = audit.Build()
                              };
                    }
                } while (tries <= Retries && serverInfo.Enabled);
            }
            throw new DnsResponseException(DnsResponseCode.ConnectionTimeout, $"No connection could be established to any of the following name servers: {string.Join(", ", NameServers)}.")
                  {
                      AuditTrail = audit.Build()
                  };
        }