Beispiel #1
0
        protected List <TMessage> EndSendMessage <TMessage>(IAsyncResult ar)
            where TMessage : DnsMessageBase, new()
        {
            DnsClientAsyncState <TMessage> state = (DnsClientAsyncState <TMessage>)ar;

            return(state.Responses);
        }
Beispiel #2
0
        private void TcpBeginConnect <TMessage>(DnsClientAsyncState <TMessage> state, IPAddress server)
            where TMessage : DnsMessageBase, new()
        {
            if (state.EndpointInfoIndex == state.EndpointInfos.Count)
            {
                state.TcpStream = null;
                state.TcpClient = null;
                state.SetCompleted();
                return;
            }

            try
            {
                state.TcpClient     = new TcpClient(server.AddressFamily);
                state.TimedOut      = false;
                state.TimeRemaining = QueryTimeout;

                IAsyncResult asyncResult = state.TcpClient.BeginConnect(server, _port, TcpConnectCompleted <TMessage>, state);
                state.Timer = new Timer(TcpTimedOut <TMessage>, asyncResult, state.TimeRemaining, Timeout.Infinite);
            }
            catch (Exception e)
            {
                Trace.TraceError("Error on dns query: " + e);

                try
                {
                    state.TcpClient.Close();
                    state.Timer.Dispose();
                }
                catch {}

                state.EndpointInfoIndex++;
                TcpBeginConnect(state);
            }
        }
Beispiel #3
0
        private IAsyncResult BeginSendMessage <TMessage>(TMessage message, List <DnsClientEndpointInfo> endpointInfos, AsyncCallback requestCallback, object state)
            where TMessage : DnsMessageBase, new()
        {
            DnsClientAsyncState <TMessage> asyncResult =
                new DnsClientAsyncState <TMessage>
            {
                Query             = message,
                Responses         = new List <TMessage>(),
                UserCallback      = requestCallback,
                AsyncState        = state,
                EndpointInfoIndex = 0
            };

            PrepareMessage(message, out asyncResult.QueryLength, out asyncResult.QueryData, out asyncResult.TSigKeySelector, out asyncResult.TSigOriginalMac);
            asyncResult.EndpointInfos = endpointInfos;

            if ((asyncResult.QueryLength > MaximumQueryMessageSize) || message.IsTcpUsingRequested)
            {
                TcpBeginConnect(asyncResult);
            }
            else
            {
                UdpBeginSend(asyncResult);
            }

            return(asyncResult);
        }
Beispiel #4
0
        private void TcpReceiveLengthCompleted <TMessage>(IAsyncResult ar)
            where TMessage : DnsMessageBase, new()
        {
            DnsClientAsyncState <TMessage> state = (DnsClientAsyncState <TMessage>)ar.AsyncState;

            if (state.Timer != null)
            {
                state.Timer.Dispose();
            }

            if (state.TimedOut)
            {
                state.EndpointInfoIndex++;
                TcpBeginConnect(state);
            }
            else
            {
                try
                {
                    state.TcpBytesToReceive -= state.TcpStream.EndRead(ar);

                    if (state.TcpBytesToReceive > 0)
                    {
                        IAsyncResult asyncResult = state.TcpStream.BeginRead(state.Buffer, 2 - state.TcpBytesToReceive, state.TcpBytesToReceive, TcpReceiveLengthCompleted <TMessage>, state);
                        state.Timer = new Timer(TcpTimedOut <TMessage>, asyncResult, state.TimeRemaining, Timeout.Infinite);
                    }
                    else
                    {
                        int tmp            = 0;
                        int responseLength = DnsMessageBase.ParseUShort(state.Buffer, ref tmp);

                        state.Buffer            = new byte[responseLength];
                        state.TcpBytesToReceive = responseLength;

                        IAsyncResult asyncResult = state.TcpStream.BeginRead(state.Buffer, 0, responseLength, TcpReceiveCompleted <TMessage>, state);
                        state.Timer = new Timer(TcpTimedOut <TMessage>, asyncResult, state.TimeRemaining, Timeout.Infinite);
                    }
                }
                catch (Exception e)
                {
                    Trace.TraceError("Error on dns query: " + e);

                    try
                    {
                        state.TcpClient.Close();
                        state.Timer.Dispose();
                    }
                    catch {}

                    state.EndpointInfoIndex++;
                    TcpBeginConnect(state);
                }
            }
        }
Beispiel #5
0
        private static void UdpTimedOut <TMessage>(object ar)
            where TMessage : DnsMessageBase, new()
        {
            IAsyncResult asyncResult = (IAsyncResult)ar;

            if (!asyncResult.IsCompleted)
            {
                DnsClientAsyncState <TMessage> state = (DnsClientAsyncState <TMessage>)asyncResult.AsyncState;
                state.TimedOut = true;
                state.UdpClient.Close();
            }
        }
Beispiel #6
0
        private void TcpBeginConnect <TMessage>(DnsClientAsyncState <TMessage> state)
            where TMessage : DnsMessageBase, new()
        {
            if (state.EndpointInfoIndex == state.EndpointInfos.Count)
            {
                state.TcpStream = null;
                state.TcpClient = null;
                state.SetCompleted();
                return;
            }

            TcpBeginConnect(state, state.EndpointInfos[state.EndpointInfoIndex].ServerAddress);
        }
Beispiel #7
0
        private void TcpConnectCompleted <TMessage>(IAsyncResult ar)
            where TMessage : DnsMessageBase, new()
        {
            DnsClientAsyncState <TMessage> state = (DnsClientAsyncState <TMessage>)ar.AsyncState;

            if (state.Timer != null)
            {
                state.Timer.Dispose();
            }

            if (state.TimedOut)
            {
                state.EndpointInfoIndex++;
                TcpBeginConnect(state);
            }
            else
            {
                try
                {
                    state.TcpClient.EndConnect(ar);

                    state.TcpStream = state.TcpClient.GetStream();

                    int tmp = 0;

                    state.Buffer = new byte[2];
                    DnsMessageBase.EncodeUShort(state.Buffer, ref tmp, (ushort)state.QueryLength);

                    IAsyncResult asyncResult = state.TcpStream.BeginWrite(state.Buffer, 0, 2, TcpSendLengthCompleted <TMessage>, state);
                    state.Timer = new Timer(TcpTimedOut <TMessage>, asyncResult, state.TimeRemaining, Timeout.Infinite);
                }
                catch (Exception e)
                {
                    Trace.TraceError("Error on dns query: " + e);

                    try
                    {
                        state.TcpClient.Close();
                        state.Timer.Dispose();
                    }
                    catch {}

                    state.EndpointInfoIndex++;
                    TcpBeginConnect(state);
                }
            }
        }
Beispiel #8
0
        private void UdpSendCompleted <TMessage>(IAsyncResult ar)
            where TMessage : DnsMessageBase, new()
        {
            DnsClientAsyncState <TMessage> state = (DnsClientAsyncState <TMessage>)ar.AsyncState;

            if (state.Timer != null)
            {
                state.Timer.Dispose();
            }

            if (state.TimedOut)
            {
                state.EndpointInfoIndex++;
                UdpBeginSend(state);
            }
            else
            {
                try
                {
                    state.UdpClient.EndSendTo(ar);

                    state.Buffer = new byte[65535];

                    if (state.EndpointInfos[state.EndpointInfoIndex].IsMulticast)
                    {
                        state.UdpEndpoint = new IPEndPoint(state.UdpClient.AddressFamily == AddressFamily.InterNetwork ? IPAddress.Any : IPAddress.IPv6Any, _port);
                    }

                    IAsyncResult asyncResult = state.UdpClient.BeginReceiveFrom(state.Buffer, 0, state.Buffer.Length, SocketFlags.None, ref state.UdpEndpoint, UdpReceiveCompleted <TMessage>, state);
                    state.Timer = new Timer(UdpTimedOut <TMessage>, asyncResult, state.TimeRemaining, Timeout.Infinite);
                }
                catch (Exception e)
                {
                    Trace.TraceError("Error on dns query: " + e);

                    try
                    {
                        state.UdpClient.Close();
                        state.Timer.Dispose();
                    }
                    catch {}

                    state.EndpointInfoIndex++;
                    UdpBeginSend(state);
                }
            }
        }
Beispiel #9
0
        private static void TcpTimedOut <TMessage>(object ar)
            where TMessage : DnsMessageBase, new()
        {
            IAsyncResult asyncResult = (IAsyncResult)ar;

            if (!asyncResult.IsCompleted)
            {
                DnsClientAsyncState <TMessage> state = (DnsClientAsyncState <TMessage>)asyncResult.AsyncState;
                state.PartialMessage = null;
                state.TimedOut       = true;
                if (state.TcpStream != null)
                {
                    state.TcpStream.Close();
                }
                state.TcpClient.Close();
            }
        }
Beispiel #10
0
        private void TcpSendCompleted <TMessage>(IAsyncResult ar)
            where TMessage : DnsMessageBase, new()
        {
            DnsClientAsyncState <TMessage> state = (DnsClientAsyncState <TMessage>)ar.AsyncState;

            if (state.Timer != null)
            {
                state.Timer.Dispose();
            }

            if (state.TimedOut)
            {
                state.EndpointInfoIndex++;
                TcpBeginConnect(state);
            }
            else
            {
                try
                {
                    state.TcpStream.EndWrite(ar);

                    state.TcpBytesToReceive = 2;

                    IAsyncResult asyncResult = state.TcpStream.BeginRead(state.Buffer, 0, 2, TcpReceiveLengthCompleted <TMessage>, state);
                    state.Timer = new Timer(TcpTimedOut <TMessage>, asyncResult, state.TimeRemaining, Timeout.Infinite);
                }
                catch (Exception e)
                {
                    Trace.TraceError("Error on dns query: " + e);

                    try
                    {
                        state.TcpClient.Close();
                        state.Timer.Dispose();
                    }
                    catch {}

                    state.EndpointInfoIndex++;
                    TcpBeginConnect(state);
                }
            }
        }
Beispiel #11
0
        private void UdpBeginSend <TMessage>(DnsClientAsyncState <TMessage> state)
            where TMessage : DnsMessageBase, new()
        {
            if (state.EndpointInfoIndex == state.EndpointInfos.Count)
            {
                state.UdpClient   = null;
                state.UdpEndpoint = null;
                state.SetCompleted();
                return;
            }

            try
            {
                DnsClientEndpointInfo endpointInfo = state.EndpointInfos[state.EndpointInfoIndex];

                state.UdpEndpoint = new IPEndPoint(endpointInfo.ServerAddress, _port);

                state.UdpClient = new System.Net.Sockets.Socket(state.UdpEndpoint.AddressFamily, SocketType.Dgram, ProtocolType.Udp);

                PrepareAndBindUdpSocket(endpointInfo, state.UdpClient);

                state.TimedOut      = false;
                state.TimeRemaining = QueryTimeout;

                IAsyncResult asyncResult = state.UdpClient.BeginSendTo(state.QueryData, 0, state.QueryLength, SocketFlags.None, state.UdpEndpoint, UdpSendCompleted <TMessage>, state);
                state.Timer = new Timer(UdpTimedOut <TMessage>, asyncResult, state.TimeRemaining, Timeout.Infinite);
            }
            catch (Exception e)
            {
                Trace.TraceError("Error on dns query: " + e);

                try
                {
                    state.UdpClient.Close();
                    state.Timer.Dispose();
                }
                catch {}

                state.EndpointInfoIndex++;
                UdpBeginSend(state);
            }
        }
Beispiel #12
0
        private void UdpReceiveCompleted <TMessage>(IAsyncResult ar)
            where TMessage : DnsMessageBase, new()
        {
            DnsClientAsyncState <TMessage> state = (DnsClientAsyncState <TMessage>)ar.AsyncState;

            if (state.Timer != null)
            {
                state.Timer.Dispose();
            }

            if (state.TimedOut)
            {
                state.EndpointInfoIndex++;
                UdpBeginSend(state);
            }
            else
            {
                try
                {
                    int    length       = state.UdpClient.EndReceiveFrom(ar, ref state.UdpEndpoint);
                    byte[] responseData = new byte[length];
                    Buffer.BlockCopy(state.Buffer, 0, responseData, 0, length);

                    TMessage response = DnsMessageBase.Parse <TMessage>(responseData, state.TSigKeySelector, state.TSigOriginalMac);

                    if (AreMultipleResponsesAllowedInParallelMode)
                    {
                        if (ValidateResponse(state.Query, response))
                        {
                            if (response.IsTcpResendingRequested)
                            {
                                TcpBeginConnect <TMessage>(state.CreateTcpCloneWithoutCallback(), ((IPEndPoint)state.UdpEndpoint).Address);
                            }
                            else
                            {
                                state.Responses.Add(response);
                            }
                        }

                        state.Buffer = new byte[65535];

                        if (state.EndpointInfos[state.EndpointInfoIndex].IsMulticast)
                        {
                            state.UdpEndpoint = new IPEndPoint(state.UdpClient.AddressFamily == AddressFamily.InterNetwork ? IPAddress.Any : IPAddress.IPv6Any, _port);
                        }

                        IAsyncResult asyncResult = state.UdpClient.BeginReceiveFrom(state.Buffer, 0, state.Buffer.Length, SocketFlags.None, ref state.UdpEndpoint, UdpReceiveCompleted <TMessage>, state);
                        state.Timer = new Timer(UdpTimedOut <TMessage>, asyncResult, state.TimeRemaining, Timeout.Infinite);
                    }
                    else
                    {
                        state.UdpClient.Close();
                        state.UdpClient   = null;
                        state.UdpEndpoint = null;

                        if (!ValidateResponse(state.Query, response) || (response.ReturnCode == ReturnCode.ServerFailure))
                        {
                            state.EndpointInfoIndex++;
                            UdpBeginSend(state);
                        }
                        else
                        {
                            if (response.IsTcpResendingRequested)
                            {
                                TcpBeginConnect <TMessage>(state, ((IPEndPoint)state.UdpEndpoint).Address);
                            }
                            else
                            {
                                state.Responses.Add(response);
                                state.SetCompleted();
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    Trace.TraceError("Error on dns query: " + e);

                    try
                    {
                        state.UdpClient.Close();
                        state.Timer.Dispose();
                    }
                    catch {}

                    state.EndpointInfoIndex++;
                    UdpBeginSend(state);
                }
            }
        }
Beispiel #13
0
        private void TcpReceiveCompleted <TMessage>(IAsyncResult ar)
            where TMessage : DnsMessageBase, new()
        {
            DnsClientAsyncState <TMessage> state = (DnsClientAsyncState <TMessage>)ar.AsyncState;

            if (state.Timer != null)
            {
                state.Timer.Dispose();
            }

            if (state.TimedOut)
            {
                state.EndpointInfoIndex++;
                TcpBeginConnect(state);
            }
            else
            {
                try
                {
                    state.TcpBytesToReceive -= state.TcpStream.EndRead(ar);

                    if (state.TcpBytesToReceive > 0)
                    {
                        IAsyncResult asyncResult = state.TcpStream.BeginRead(state.Buffer, state.Buffer.Length - state.TcpBytesToReceive, state.TcpBytesToReceive, TcpReceiveCompleted <TMessage>, state);
                        state.Timer = new Timer(TcpTimedOut <TMessage>, asyncResult, state.TimeRemaining, Timeout.Infinite);
                    }
                    else
                    {
                        byte[] buffer = state.Buffer;
                        state.Buffer = null;

                        TMessage response = DnsMessageBase.Parse <TMessage>(buffer, state.TSigKeySelector, state.TSigOriginalMac);

                        if (!ValidateResponse(state.Query, response) || (response.ReturnCode == ReturnCode.ServerFailure))
                        {
                            state.EndpointInfoIndex++;
                            state.PartialMessage = null;
                            state.TcpStream.Close();
                            state.TcpClient.Close();
                            state.TcpStream = null;
                            state.TcpClient = null;
                            TcpBeginConnect(state);
                        }
                        else
                        {
                            bool isSubsequentResponseMessage = (state.PartialMessage != null);

                            if (isSubsequentResponseMessage)
                            {
                                state.PartialMessage.AnswerRecords.AddRange(response.AnswerRecords);
                            }
                            else
                            {
                                state.PartialMessage = response;
                            }

                            if (response.IsTcpNextMessageWaiting(isSubsequentResponseMessage))
                            {
                                state.TcpBytesToReceive = 2;
                                state.Buffer            = new byte[2];

                                IAsyncResult asyncResult = state.TcpStream.BeginRead(state.Buffer, 0, 2, TcpReceiveLengthCompleted <TMessage>, state);
                                state.Timer = new Timer(TcpTimedOut <TMessage>, asyncResult, state.TimeRemaining, Timeout.Infinite);
                            }
                            else
                            {
                                state.TcpStream.Close();
                                state.TcpClient.Close();
                                state.TcpStream = null;
                                state.TcpClient = null;

                                state.Responses.Add(state.PartialMessage);
                                state.SetCompleted();
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    Trace.TraceError("Error on dns query: " + e);

                    try
                    {
                        state.TcpClient.Close();
                        state.Timer.Dispose();
                    }
                    catch {}

                    state.EndpointInfoIndex++;
                    TcpBeginConnect(state);
                }
            }
        }