using System;
using System.Collections.Generic;
namespace DnsClient
{
/*
* Reference RFC6895#section-2.3
*/
///
/// Response codes of the .
///
/// RFC 6895
public enum DnsResponseCode : short
{
///
/// No error condition
///
/// RFC 1035
NoError = 0,
///
/// Format error. The name server was unable to interpret the query.
///
/// RFC 1035
FormatError = 1,
///
/// Server failure. The name server was unable to process this query due to a problem with the name server.
///
/// RFC 1035
ServerFailure = 2,
///
/// Name Error. Meaningful only for responses from an authoritative name server,
/// this code signifies that the domain name referenced in the query does not exist.
///
/// RFC 1035
NotExistentDomain = 3,
///
/// Not Implemented. The name server does not support the requested kind of query.
///
/// RFC 1035
NotImplemented = 4,
///
/// Refused. The name server refuses to perform the specified operation for policy reasons.
/// For example, a name server may not wish to provide the information to the particular requester,
/// or a name server may not wish to perform a particular operation (e.g., zone transfer) for particular data.
///
/// RFC 1035
Refused = 5,
///
/// Name Exists when it should not.
///
/// RFC 2136
ExistingDomain = 6,
///
/// Resource record set exists when it should not.
///
/// RFC 2136
ExistingResourceRecordSet = 7,
///
/// Resource record set that should exist but does not.
///
/// RFC 2136
MissingResourceRecordSet = 8,
///
/// Server Not Authoritative for zone / Not Authorized.
///
/// RFC 2136
/// RFC 2845
NotAuthorized = 9,
///
/// Name not contained in zone.
///
/// RFC 2136
NotZone = 10,
///
/// Bad OPT Version or TSIG Signature Failure.
///
/// RFC 2671
/// RFC 2845
BadVersionOrBadSignature = 16,
///
/// Key not recognized.
///
/// RFC 2845
BadKey = 17,
///
/// Signature out of time window.
///
/// RFC 2845
BadTime = 18,
///
/// Bad TKEY Mode.
///
/// RFC 2930
BadMode = 19,
///
/// Duplicate key name.
///
/// RFC 2930
BadName = 20,
///
/// Algorithm not supported.
///
/// RFC 2930
BadAlgorithm = 21,
///
/// Bad Truncation.
///
/// RFC 4635
BadTruncation = 22,
///
/// Bad/missing Server Cookie
///
/// RFC 7873
BadCookie = 23,
///
/// Unknown error.
///
Unassigned = 666,
///
/// Indicates a timeout error. Connection to the remote server couldn't be established.
///
ConnectionTimeout = 999
}
///
/// A DnsClient specific exception transporting additional information about the query causing this exception.
///
///
public class DnsResponseException : Exception
{
///
/// Gets the response code.
///
///
/// The response code.
///
public DnsResponseCode Code { get; }
///
/// Gets the audit trail if . as set to true, null otherwise.
///
///
/// The audit trail.
///
public string AuditTrail { get; internal set; }
///
/// Gets a human readable error message.
///
///
/// The error message.
///
public string DnsError { get; }
///
/// Initializes a new instance of the class
/// with set to .
///
public DnsResponseException() : base(DnsResponseCodeText.Unassigned)
{
Code = DnsResponseCode.Unassigned;
DnsError = DnsResponseCodeText.GetErrorText(Code);
}
///
/// Initializes a new instance of the class
/// with set to
/// and a custom .
///
public DnsResponseException(string message) : base(message)
{
Code = DnsResponseCode.Unassigned;
DnsError = DnsResponseCodeText.GetErrorText(Code);
}
///
/// Initializes a new instance of the class
/// with the standard error text for the given .
///
public DnsResponseException(DnsResponseCode code) : base(DnsResponseCodeText.GetErrorText(code))
{
Code = code;
DnsError = DnsResponseCodeText.GetErrorText(Code);
}
///
/// Initializes a new instance of the class
/// with set to
/// and a custom and inner .
///
public DnsResponseException(string message, Exception innerException) : base(message, innerException)
{
Code = DnsResponseCode.Unassigned;
DnsError = DnsResponseCodeText.GetErrorText(Code);
}
///
/// Initializes a new instance of the class
/// with a custom and the given .
///
public DnsResponseException(DnsResponseCode code, string message) : base(message)
{
Code = code;
DnsError = DnsResponseCodeText.GetErrorText(Code);
}
///
/// Initializes a new instance of the class
/// with a custom and the given .
///
public DnsResponseException(DnsResponseCode code, string message, Exception innerException) : base(message, innerException)
{
Code = code;
DnsError = DnsResponseCodeText.GetErrorText(Code);
}
}
internal static class DnsResponseCodeText
{
internal const string BADALG = "Algorithm not supported";
internal const string BADCOOKIE = "Bad/missing Server Cookie";
internal const string BADKEY = "Key not recognized";
internal const string BADMODE = "Bad TKEY Mode";
internal const string BADNAME = "Duplicate key name";
internal const string BADSIG = "TSIG Signature Failure";
internal const string BADTIME = "Signature out of time window";
internal const string BADTRUNC = "Bad Truncation";
internal const string BADVERS = "Bad OPT Version";
internal const string FormErr = "Format Error";
internal const string NoError = "No Error";
internal const string NotAuth = "Server Not Authoritative for zone or Not Authorized";
internal const string NotImp = "Not Implemented";
internal const string NotZone = "Name not contained in zone";
internal const string NXDomain = "Non-Existent Domain";
internal const string NXRRSet = "RR Set that should exist does not";
internal const string Refused = "Query Refused";
internal const string ServFail = "Server Failure";
internal const string Unassigned = "Unknown Error";
internal const string YXDomain = "Name Exists when it should not";
internal const string YXRRSet = "RR Set Exists when it should not";
private static readonly Dictionary errors = new Dictionary()
{
{ DnsResponseCode.NoError, DnsResponseCodeText.NoError },
{ DnsResponseCode.FormatError, DnsResponseCodeText.FormErr },
{ DnsResponseCode.ServerFailure, DnsResponseCodeText.ServFail },
{ DnsResponseCode.NotExistentDomain, DnsResponseCodeText.NXDomain },
{ DnsResponseCode.NotImplemented, DnsResponseCodeText.NotImp },
{ DnsResponseCode.Refused, DnsResponseCodeText.Refused },
{ DnsResponseCode.ExistingDomain, DnsResponseCodeText.YXDomain },
{ DnsResponseCode.ExistingResourceRecordSet, DnsResponseCodeText.YXRRSet },
{ DnsResponseCode.MissingResourceRecordSet, DnsResponseCodeText.NXRRSet },
{ DnsResponseCode.NotAuthorized, DnsResponseCodeText.NotAuth },
{ DnsResponseCode.NotZone, DnsResponseCodeText.NotZone },
{ DnsResponseCode.BadVersionOrBadSignature, DnsResponseCodeText.BADVERS },
{ DnsResponseCode.BadKey, DnsResponseCodeText.BADKEY },
{ DnsResponseCode.BadTime, DnsResponseCodeText.BADTIME },
{ DnsResponseCode.BadMode, DnsResponseCodeText.BADMODE },
{ DnsResponseCode.BadName, DnsResponseCodeText.BADNAME },
{ DnsResponseCode.BadAlgorithm, DnsResponseCodeText.BADALG },
{ DnsResponseCode.BadTruncation, DnsResponseCodeText.BADTRUNC },
{ DnsResponseCode.BadCookie, DnsResponseCodeText.BADCOOKIE },
};
public static string GetErrorText(DnsResponseCode code)
{
if (!errors.ContainsKey(code))
{
return Unassigned;
}
return errors[code];
}
}
}