174 lines
5.8 KiB
C#
174 lines
5.8 KiB
C#
using Swan.Formatters;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.ObjectModel;
|
|
using System.IO;
|
|
using System.Linq;
|
|
|
|
namespace Swan.Net.Dns {
|
|
/// <summary>
|
|
/// DnsClient Response inner class.
|
|
/// </summary>
|
|
internal partial class DnsClient {
|
|
public class DnsClientResponse : IDnsResponse {
|
|
private readonly DnsResponse _response;
|
|
private readonly Byte[] _message;
|
|
|
|
internal DnsClientResponse(DnsClientRequest request, DnsResponse response, Byte[] message) {
|
|
this.Request = request;
|
|
|
|
this._message = message;
|
|
this._response = response;
|
|
}
|
|
|
|
public DnsClientRequest Request {
|
|
get;
|
|
}
|
|
|
|
public Int32 Id {
|
|
get => this._response.Id;
|
|
set {
|
|
}
|
|
}
|
|
|
|
public IList<IDnsResourceRecord> AnswerRecords => this._response.AnswerRecords;
|
|
|
|
public IList<IDnsResourceRecord> AuthorityRecords => new ReadOnlyCollection<IDnsResourceRecord>(this._response.AuthorityRecords);
|
|
|
|
public IList<IDnsResourceRecord> AdditionalRecords => new ReadOnlyCollection<IDnsResourceRecord>(this._response.AdditionalRecords);
|
|
|
|
public Boolean IsRecursionAvailable {
|
|
get => this._response.IsRecursionAvailable;
|
|
set {
|
|
}
|
|
}
|
|
|
|
public Boolean IsAuthorativeServer {
|
|
get => this._response.IsAuthorativeServer;
|
|
set {
|
|
}
|
|
}
|
|
|
|
public Boolean IsTruncated {
|
|
get => this._response.IsTruncated;
|
|
set {
|
|
}
|
|
}
|
|
|
|
public DnsOperationCode OperationCode {
|
|
get => this._response.OperationCode;
|
|
set {
|
|
}
|
|
}
|
|
|
|
public DnsResponseCode ResponseCode {
|
|
get => this._response.ResponseCode;
|
|
set {
|
|
}
|
|
}
|
|
|
|
public IList<DnsQuestion> Questions => new ReadOnlyCollection<DnsQuestion>(this._response.Questions);
|
|
|
|
public Int32 Size => this._message.Length;
|
|
|
|
public Byte[] ToArray() => this._message;
|
|
|
|
public override String ToString() => this._response.ToString();
|
|
}
|
|
|
|
public class DnsResponse : IDnsResponse {
|
|
private DnsHeader _header;
|
|
|
|
public DnsResponse(DnsHeader header, IList<DnsQuestion> questions, IList<IDnsResourceRecord> answers, IList<IDnsResourceRecord> authority, IList<IDnsResourceRecord> additional) {
|
|
this._header = header;
|
|
this.Questions = questions;
|
|
this.AnswerRecords = answers;
|
|
this.AuthorityRecords = authority;
|
|
this.AdditionalRecords = additional;
|
|
}
|
|
|
|
public IList<DnsQuestion> Questions {
|
|
get;
|
|
}
|
|
|
|
public IList<IDnsResourceRecord> AnswerRecords {
|
|
get;
|
|
}
|
|
|
|
public IList<IDnsResourceRecord> AuthorityRecords {
|
|
get;
|
|
}
|
|
|
|
public IList<IDnsResourceRecord> AdditionalRecords {
|
|
get;
|
|
}
|
|
|
|
public Int32 Id {
|
|
get => this._header.Id;
|
|
set => this._header.Id = value;
|
|
}
|
|
|
|
public Boolean IsRecursionAvailable {
|
|
get => this._header.RecursionAvailable;
|
|
set => this._header.RecursionAvailable = value;
|
|
}
|
|
|
|
public Boolean IsAuthorativeServer {
|
|
get => this._header.AuthorativeServer;
|
|
set => this._header.AuthorativeServer = value;
|
|
}
|
|
|
|
public Boolean IsTruncated {
|
|
get => this._header.Truncated;
|
|
set => this._header.Truncated = value;
|
|
}
|
|
|
|
public DnsOperationCode OperationCode {
|
|
get => this._header.OperationCode;
|
|
set => this._header.OperationCode = value;
|
|
}
|
|
|
|
public DnsResponseCode ResponseCode {
|
|
get => this._header.ResponseCode;
|
|
set => this._header.ResponseCode = value;
|
|
}
|
|
|
|
public Int32 Size => this._header.Size + this.Questions.Sum(q => q.Size) + this.AnswerRecords.Sum(a => a.Size) + this.AuthorityRecords.Sum(a => a.Size) + this.AdditionalRecords.Sum(a => a.Size);
|
|
|
|
public static DnsResponse FromArray(Byte[] message) {
|
|
DnsHeader header = DnsHeader.FromArray(message);
|
|
Int32 offset = header.Size;
|
|
|
|
if(!header.Response || header.QuestionCount == 0) {
|
|
throw new ArgumentException("Invalid response message");
|
|
}
|
|
|
|
return header.Truncated
|
|
? new DnsResponse(header, DnsQuestion.GetAllFromArray(message, offset, header.QuestionCount), new List<IDnsResourceRecord>(), new List<IDnsResourceRecord>(), new List<IDnsResourceRecord>())
|
|
: new DnsResponse(header, DnsQuestion.GetAllFromArray(message, offset, header.QuestionCount, out offset), DnsResourceRecordFactory.GetAllFromArray(message, offset, header.AnswerRecordCount, out offset), DnsResourceRecordFactory.GetAllFromArray(message, offset, header.AuthorityRecordCount, out offset), DnsResourceRecordFactory.GetAllFromArray(message, offset, header.AdditionalRecordCount, out _));
|
|
}
|
|
|
|
public Byte[] ToArray() {
|
|
this.UpdateHeader();
|
|
MemoryStream result = new MemoryStream(this.Size);
|
|
|
|
_ = result.Append(this._header.ToArray()).Append(this.Questions.Select(q => q.ToArray())).Append(this.AnswerRecords.Select(a => a.ToArray())).Append(this.AuthorityRecords.Select(a => a.ToArray())).Append(this.AdditionalRecords.Select(a => a.ToArray()));
|
|
|
|
return result.ToArray();
|
|
}
|
|
|
|
public override String ToString() {
|
|
this.UpdateHeader();
|
|
|
|
return Json.SerializeOnly(this, true, nameof(this.Questions), nameof(this.AnswerRecords), nameof(this.AuthorityRecords), nameof(this.AdditionalRecords));
|
|
}
|
|
|
|
private void UpdateHeader() {
|
|
this._header.QuestionCount = this.Questions.Count;
|
|
this._header.AnswerRecordCount = this.AnswerRecords.Count;
|
|
this._header.AuthorityRecordCount = this.AuthorityRecords.Count;
|
|
this._header.AdditionalRecordCount = this.AdditionalRecords.Count;
|
|
}
|
|
}
|
|
}
|
|
} |