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); }
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() }; }