internal ClientDnsResponse(IDnsRequest request, IDnsResponse response)
        {
            Request = request;

            this.message  = response.ToArray();
            this.response = 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);
                }
            }
        }