Различают EIdDnsResolverError разного вида - PullRequest
0 голосов
/ 08 января 2019

Я сканирую DNS-серверы в локальной сети, используя TIdDNSResolver, поэтому результат запроса DNS не важен. Я проверяю, есть ли вообще DNS-сервер.

Приложение также не должно зависеть от наличия запрошенной записи DNS, поэтому вместо существующего хоста оно запрашивает заведомо несуществующее имя.

В этом случае возникает исключение типа EIdDnsResolverError.

Это исключение может сопровождаться следующими текстами ошибок:

  • TimedOut - это означает, что DNS-сервер не ответил вовремя, и мы должны предположить, что он не существует.
  • DNS-сервер сообщает об ошибке имени запроса - DNS-сервер существует
  • DNS-сервер сообщает об ошибке Query Server - DNS-сервер существует

Я не люблю различать эти ошибки по тексту ошибки. Есть ли какие-то другие средства различия?

function TDNSChecker.CheckServer(host: string): Boolean;
var
  dr: TIdDNSResolver;
begin
  Result := False;
  try
    dr := TIdDNSResolver.Create(nil);
    try
      dr.Host := host;
      dr.QueryType := [qtA];
      dr.WaitingTime := 1000;
      dr.Resolve('feufgzrfapoduiuzgfuzfsufseuszfu'); //knowingly non-existent name
      Result := True;
    finally
      _finished := True;
      dr.Free();
    end;
  except
    on ex: EIdDnsResolverError do
      if ex.Message <> 'TimedOut' then begin
        if (ex.Message = 'DNS Server Reports Query Name Error') or (ex.Message = 'DNS Server Reports Query Server Error') then
          Result := True
        else
          Log(host + ' - ' + ex.ClassName + ': ' + ex.Message.Replace(#13#10, ' '));
      end;
    on ex: Exception do;
  end;
end;

1 Ответ

0 голосов
/ 08 января 2019

К сожалению, TIdDNSResolver в настоящее время не использует разные типы классов исключений для разных ошибок DNS, он использует только EIdDnsResolverError. Я открыл билет в системе отслеживания проблем Indy, чтобы возможно добавить больше классов ошибок в будущем выпуске.

Итак, чтобы различать ошибки DNS, вам нужно взглянуть на свойство Message исключения. Сообщения о возможных ошибках хранятся в виде строк ресурсов в блоке IdResourceStringsProtocols (около 21 строки связано с ошибками DNS). Просто обратите внимание, что некоторые из них являются отформатированными строками, поэтому простое сравнение как есть не будет работать, вам придется использовать что-то вроде TextStartsWith() или подобное, чтобы игнорировать любые отформатированные части.

С другой стороны, тот факт, что вы вообще получаете исключение EIdDnsResolverError, обычно означает, что вы получили ответ от DNS-сервера. Вам не нужно различать все возможные ошибки Indy DNS, чтобы знать, что DNS-сервер существует. Только несколько ошибок EIdDnsResolverError связаны с самим соединением, таким как RSDNSTimeout, RSTunnelConnectToMasterFailed и т. Д., А не с содержимым сообщений DNS.

Если вы используете версию Delphi с доступным свойством Exception.InnerException, тогда InnerException может быть установлен на EIdConnectTimeout или EIdConnectException, когда TIdDNSResolver использует TCP (только когда qtAXFR или qtIXFR присутствует в QueryType) вместо UDP. Также возможно, что InnerException может быть EIdNotEnoughData, но это будет ошибка обмена сообщениями, а не ошибка соединения.

В вашем примере будет использоваться UDP, поэтому я думаю, что любая ошибка EIdDNSResolverError, отличная от RSDNSTimeout, будет указывать на наличие DNS-сервера.

...