private void DecodeQuestions(IDnsResponse response, IByteBuffer buffer, int questionCount) { for (int i = questionCount - 1; i > 0; i--) { response.AddRecord(DnsSection.QUESTION, recordDecoder.DecodeQuestion(buffer)); } }
internal ClientDnsResponse(IDnsRequest request, IDnsResponse response, byte[] message) { Request = request; this.message = message; this.response = response; }
internal ClientDnsResponse(IDnsRequest request, IDnsResponse response) { Request = request; this.message = response.ToArray(); this.response = response; }
public async Task <IDnsResponse> Resolve(IDnsRequest request) { using (TcpClient tcp = new TcpClient()) { await tcp.ConnectAsync(dns.Address, dns.Port); Stream stream = tcp.GetStream(); byte[] buffer = request.ToArray(); byte[] length = BitConverter.GetBytes((ushort)buffer.Length); if (BitConverter.IsLittleEndian) { Array.Reverse(length); } await stream.WriteAsync(length, 0, length.Length); await stream.WriteAsync(buffer, 0, buffer.Length); buffer = new byte[2]; await Read(stream, buffer); if (BitConverter.IsLittleEndian) { Array.Reverse(buffer); } buffer = new byte[BitConverter.ToUInt16(buffer, 0)]; await Read(stream, buffer); IDnsResponse response = DefaultDnsResponse.FromArray(buffer); return(new ClientDnsResponse(request, response, buffer)); } }
protected override void Decode(IChannelHandlerContext context, DatagramPacket message, List <object> output) { IByteBuffer buffer = message.Content; IDnsResponse response = NewResponse(message, buffer); bool success = false; try { int questionCount = buffer.ReadUnsignedShort(); int answerCount = buffer.ReadUnsignedShort(); int authorityRecordCount = buffer.ReadUnsignedShort(); int additionalRecordCount = buffer.ReadUnsignedShort(); DecodeQuestions(response, buffer, questionCount); DecodeRecords(response, DnsSection.ANSWER, buffer, answerCount); DecodeRecords(response, DnsSection.AUTHORITY, buffer, authorityRecordCount); DecodeRecords(response, DnsSection.ADDITIONAL, buffer, additionalRecordCount); output.Add(response); success = true; } finally { if (!success) { response.Release(); } } }
/// <summary> /// Resolves this request into a response using the provided DNS information. The given /// request strategy is used to retrieve the response. /// </summary> /// <exception cref="DnsResponseException">Throw if a malformed response is received from the server</exception> /// <exception cref="IOException">Thrown if a IO error occurs</exception> /// <exception cref="SocketException">Thrown if the reading or writing to the socket fails</exception> /// <exception cref="OperationCanceledException">Thrown if reading or writing to the socket timeouts</exception> /// <returns>The response received from server</returns> public async Task <IDnsResponse> Resolve() { try { IDnsResponse response = await resolver.Resolve(this); if (response.Id != this.Id) { throw new DnsResponseException(response, "Mismatching request/response IDs"); } if (response.ResponseCode != DnsResponseCode.NoError) { throw new DnsResponseException(response); } return(response); } catch (ArgumentException e) { throw new DnsResponseException("Invalid response", e); } catch (IndexOutOfRangeException e) { throw new DnsResponseException("Invalid response", e); } }
public async Task<IDnsResponse> Resolve(IDnsRequest request) { IDnsResponse response = null; foreach (IDnsRequestResolver resolver in resolvers) { response = await resolver.Resolve(request); if (response.AnswerRecords.Count > 0) break; } return response; }
public async Task <string> Reverse(IPAddress ip) { IDnsResponse response = await Resolve(Domain.PointerName(ip), DnsRecordType.PTR); IResourceRecord ptr = response.AnswerRecords.FirstOrDefault(r => r.Type == DnsRecordType.PTR); if (ptr == null) { throw new DnsResponseException(response, "No matching records"); } return(((PointerResourceRecord)ptr).PointerDomainName.ToString()); }
private void DecodeRecords(IDnsResponse response, DnsSection section, IByteBuffer buffer, int count) { for (int i = count - 1; i > 0; i--) { IDnsRecord r = recordDecoder.DecodeRecord(buffer); if (r == null) { break; } response.AddRecord(section, r); } }
public DefaultDnsResponse(IDnsResponse response) { this.header = new DnsMessageHeader(); this.questions = new List <DnsQuestion>(response.Questions); this.answers = new List <IResourceRecord>(response.AnswerRecords); this.authority = new List <IResourceRecord>(response.AuthorityRecords); this.additional = new List <IResourceRecord>(response.AdditionalRecords); this.header.Response = true; Id = response.Id; RecursionAvailable = response.RecursionAvailable; AuthorativeServer = response.AuthorativeServer; OperationCode = response.OperationCode; ResponseCode = response.ResponseCode; }
public DnsResponse(IDnsResponse response) { header = new DnsHeader(); Questions = new List <DnsQuestion>(response.Questions); AnswerRecords = new List <IDnsResourceRecord>(response.AnswerRecords); AuthorityRecords = new List <IDnsResourceRecord>(response.AuthorityRecords); AdditionalRecords = new List <IDnsResourceRecord>(response.AdditionalRecords); header.Response = true; Id = response.Id; IsRecursionAvailable = response.IsRecursionAvailable; IsAuthorativeServer = response.IsAuthorativeServer; OperationCode = response.OperationCode; ResponseCode = response.ResponseCode; }
public IDnsResponse Decode(T sender, T recipient, IByteBuffer buffer) { int id = buffer.ReadUnsignedShort(); int flags = buffer.ReadUnsignedShort(); if (flags >> 15 == 0) { throw new CorruptedFrameException("not a response"); } IDnsResponse response = NewResponse( sender, recipient, id, new DnsOpCode((byte)(flags >> 11 & 0xf)), DnsResponseCode.From((flags & 0xf))); response.IsRecursionDesired = (flags >> 8 & 1) == 1; response.IsAuthoritativeAnswer = (flags >> 10 & 1) == 1; response.IsTruncated = (flags >> 9 & 1) == 1; response.IsRecursionAvailable = (flags >> 7 & 1) == 1; response.Z = flags >> 4 & 0x7; bool success = false; try { int questionCount = buffer.ReadUnsignedShort(); int answerCount = buffer.ReadUnsignedShort(); int authorityRecordCount = buffer.ReadUnsignedShort(); int additionalRecordCount = buffer.ReadUnsignedShort(); DecodeQuestions(response, buffer, questionCount); DecodeRecords(response, DnsSection.ANSWER, buffer, answerCount); DecodeRecords(response, DnsSection.AUTHORITY, buffer, authorityRecordCount); DecodeRecords(response, DnsSection.ADDITIONAL, buffer, additionalRecordCount); success = true; return(response); } finally { if (!success) { response.Release(); } } }
public Task <IDnsResponse> Resolve(IDnsRequest request) { IDnsResponse response = DefaultDnsResponse.FromRequest(request); foreach (DnsQuestion question in request.Questions) { IList <IResourceRecord> answers = Get(question); if (answers.Count > 0) { Merge(response.AnswerRecords, answers); } else { response.ResponseCode = DnsResponseCode.NameError; } } return(Task.FromResult(response)); }
public async Task <IList <IPAddress> > Lookup(string domain, DnsRecordType type = DnsRecordType.A) { if (type != DnsRecordType.A && type != DnsRecordType.AAAA) { throw new ArgumentException("Invalid record type " + type); } IDnsResponse response = await Resolve(domain, type); IList <IPAddress> ips = response.AnswerRecords .Where(r => r.Type == type) .Cast <IPAddressResourceRecord>() .Select(r => r.IPAddress) .ToList(); if (ips.Count == 0) { throw new DnsResponseException(response, "No matching records"); } return(ips); }
public DnsResponseException(IDnsResponse response) : this(response, Format(response)) { }
internal static StringBuilder AppendResponseHeader(this StringBuilder builder, IDnsResponse response) { builder.Append(response.GetType().GetTypeInfo().Name) .Append('(') .AppendAddresses(response) .Append(response.Id) .Append(", ") .Append(response.OpCode) .Append(", ") .Append(response.Code) .Append(','); bool hasComma = true; if (response.IsRecursionDesired) { hasComma = false; builder.Append(" RD"); } if (response.IsAuthoritativeAnswer) { hasComma = false; builder.Append(" AA"); } if (response.IsTruncated) { hasComma = false; builder.Append(" TC"); } if (response.IsRecursionAvailable) { hasComma = false; builder.Append(" RA"); } if (response.Z != 0) { if (!hasComma) { builder.Append(','); } builder.Append(" Z: ") .Append(response.Z); } if (hasComma) { builder[builder.Length - 1] = ')'; } else { builder.Append(')'); } return(builder); }
internal static StringBuilder AppendResponse(this StringBuilder builder, IDnsResponse response) { builder.AppendResponseHeader(response) .AppendAllRecords(response); return(builder); }
public DnsResponseException(IDnsResponse response, string message) : base(message) { DnsResponse = response; }
private async void HandleRequest(byte[] data, IPEndPoint remote) { DefaultDnsRequest request = null; try { request = DefaultDnsRequest.FromArray(data); OnRequested(request); IDnsResponse response = await resolver.Resolve(request); OnResponded(request, response); await udp .SendAsync(response.ToArray(), response.Size, remote) .WithCancellationTimeout(UDP_TIMEOUT); } catch (SocketException e) { OnErrored(e); } catch (ArgumentException e) { OnErrored(e); } catch (IndexOutOfRangeException e) { OnErrored(e); } catch (OperationCanceledException e) { OnErrored(e); } catch (IOException e) { OnErrored(e); } catch (ObjectDisposedException e) { OnErrored(e); } catch (DnsResponseException e) { IDnsResponse response = e.DnsResponse; if (response == null) { response = DefaultDnsResponse.FromRequest(request); } try { await udp .SendAsync(response.ToArray(), response.Size, remote) .WithCancellationTimeout(UDP_TIMEOUT); } catch (SocketException) { } catch (OperationCanceledException) { } finally { OnErrored(e); } } }
protected virtual void OnResponded(IDnsRequest request, IDnsResponse response) { RespondedEventHandler handlers = Responded; if (handlers != null) handlers(request, response); }
private static string Format(IDnsResponse response) { return(string.Format("Invalid response received with code {0}", response.ResponseCode)); }
public DnsResponseException(IDnsResponse response, Exception e) : base(Format(response), e) { DnsResponse = response; }