using System; namespace DnsClient.Protocol { /// /// Base class for all resource records. /// /// public abstract class DnsResourceRecord : ResourceRecordInfo { /// /// Initializes a new instance of the class. /// /// The information. /// If is null. public DnsResourceRecord(ResourceRecordInfo info) : base( info?.DomainName ?? throw new ArgumentNullException(nameof(info)), info?.RecordType ?? throw new ArgumentNullException(nameof(info)), info?.RecordClass ?? throw new ArgumentNullException(nameof(info)), info?.InitialTimeToLive ?? throw new ArgumentNullException(nameof(info)), info?.RawDataLength ?? throw new ArgumentNullException(nameof(info))) { } /// public override string ToString() { return ToString(0); } /// /// Same as ToString but offsets the /// by . /// Set the offset to -32 for example to make it print nicely in consols. /// /// The offset. /// A string representing this instance. public virtual string ToString(int offset = 0) { return string.Format("{0," + offset + "}{1} \t{2} \t{3} \t{4}", DomainName, TimeToLive, RecordClass, RecordType, RecordToString()); } /// /// Returns a string representation of the record's value only. /// uses this to compose the full string value of this instance. /// /// A string representing this record. private protected abstract string RecordToString(); } /// /// The type represents a . /// public class ResourceRecordInfo { private readonly int _ticks; /// /// The domain name used to query. /// public DnsString DomainName { get; } /// /// Specifies type of resource record. /// public ResourceRecordType RecordType { get; } /// /// Specifies type class of resource record, mostly IN but can be CS, CH or HS . /// public QueryClass RecordClass { get; } /// /// Gets the current time to live value for the record. /// public int TimeToLive { get { var curTicks = Environment.TickCount & int.MaxValue; if (curTicks < _ticks) { return 0; } var ttl = InitialTimeToLive - ((curTicks - _ticks) / 1000); return ttl < 0 ? 0 : ttl; } } /// /// Gets or sets the original time to live returned from the server. /// public int InitialTimeToLive { get; internal set; } /// /// Gets the number of bytes for this resource record stored in RDATA /// public int RawDataLength { get; } /// /// Initializes a new instance of the class. /// /// The domain name used by the query. /// Type of the record. /// The record class. /// The time to live. /// Length of the raw data. /// If is null. public ResourceRecordInfo(string domainName, ResourceRecordType recordType, QueryClass recordClass, int timeToLive, int rawDataLength) : this(DnsString.Parse(domainName), recordType, recordClass, timeToLive, rawDataLength) { } /// /// Initializes a new instance of the class. /// /// The used by the query. /// Type of the record. /// The record class. /// The time to live. /// Length of the raw data. /// If is null or empty. public ResourceRecordInfo(DnsString domainName, ResourceRecordType recordType, QueryClass recordClass, int timeToLive, int rawDataLength) { DomainName = domainName ?? throw new ArgumentNullException(nameof(domainName)); RecordType = recordType; RecordClass = recordClass; RawDataLength = rawDataLength; InitialTimeToLive = timeToLive; _ticks = Environment.TickCount; } } }