Пример #1
0
            /// <summary>
            /// Constructor.
            /// </summary>
            /// <param name="request">The DNS request.</param>
            /// <param name="nameServers">The name server IP addresses.</param>
            /// <param name="maxSendCount">
            /// The number of times a request should be sent to a
            /// particular name server.
            /// </param>
            /// <param name="timeout">The timeout to use for each request retry.</param>
            /// <param name="callback">The deleate to be called when the operation completes (or <c>null</c>).</param>
            /// <param name="state">The application defined state (or <c>null</c>).</param>
            /// <remarks>
            /// <para>
            /// Note that a random name server endpoint from the list will be
            /// selected and moved to the head of the list.
            /// </para>
            /// <para>
            /// This initializes <see cref="SendCount" /> to 1 under the assumption
            /// that the first request will be sent out immediately.
            /// </para>
            /// </remarks>
            public DnsRetryAsyncResult(DnsRequest request, IPAddress[] nameServers, int maxSendCount, TimeSpan timeout,
                                       AsyncCallback callback, object state)
                : base(null, callback, state)
            {
                this.NameServers = new List <IPAddress>(nameServers.Length);
                for (int i = 0; i < nameServers.Length; i++)
                {
                    this.NameServers.Add(nameServers[i]);
                }

                this.Request      = request;
                this.Response     = null;
                this.MaxSendCount = maxSendCount;
                this.SendCount    = 1;
                this.Timeout      = timeout;

                RandomizeNameServers();
            }
Пример #2
0
        /// <summary>
        /// Initiates an asynchronous DNS request to a name server.
        /// </summary>
        /// <param name="nameServer">IP address of the name server.</param>
        /// <param name="request">The DNS request.</param>
        /// <param name="timeout">The maximum time to wait for a response.</param>
        /// <param name="callback">The delegate to be called when the operation completes (or <c>null</c>).</param>
        /// <param name="state">Application state to be passed to the callback (or <c>null</c>).</param>
        /// <returns>The IAsyncResult object to be used to track the operation.</returns>
        /// <remarks>
        /// <note>
        /// This DNS resolver does not implement any local caching of DNS
        /// responses.
        /// </note>
        /// <para>
        /// This method in combination with <see cref="EndQuery" /> does not perform any
        /// iterative processing on the request or implement any retry behavior.  It simply
        /// sends a DNS message to the name server and returns the response message or throws a
        /// <see cref="TimeoutException" />.
        /// </para>
        /// <note>
        /// The method will initialize the request's <see cref="DnsMessage.QID" />
        /// property with a unique 16-bit query ID.
        /// </note>
        /// </remarks>
        public static IAsyncResult BeginQuery(IPAddress nameServer, DnsRequest request, TimeSpan timeout,
                                              AsyncCallback callback, object state)
        {
            DnsAsyncResult arDns;

            byte[] packet;
            int    cbPacket;

            lock (syncLock)
            {
                arDns            = PrepareQuery(request, timeout, callback, state);
                packet           = request.FormatPacket(out cbPacket);
                arDns.TimerStart = HiResTimer.Count;

                request.Trace(TraceSubSystem, 0, nameServer, null);
                arDns.DnsSocket.Socket.SendTo(packet, 0, cbPacket, SocketFlags.None, new IPEndPoint(nameServer, NetworkPort.DNS));
                arDns.Started();
            }

            return(arDns);
        }
Пример #3
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="remoteEP">The <see cref="IPEndPoint" /> of the DNS resolver making the request.</param>
 /// <param name="request">The received <see cref="DnsRequest" />.</param>
 internal DnsServerEventArgs(IPEndPoint remoteEP, DnsRequest request)
 {
     this.RemoteEP = remoteEP;
     this.Request  = request;
     this.Response = null;
 }
Пример #4
0
        /// <summary>
        /// Handles received packets.
        /// </summary>
        /// <param name="ar">The <see cref="IAsyncResult" /> instance.</param>
        private void OnReceive(IAsyncResult ar)
        {
            DnsRequest request = null;
            int        cbRecv;
            IPEndPoint ep;

            try
            {
                cbRecv = ((EnhancedSocket)ar.AsyncState).EndReceiveFrom(ar, ref remoteEP);
            }
            catch
            {
                cbRecv = 0;
            }

            if (sock == null)
            {
                return; // The server has stopped
            }
            if (cbRecv != 0)
            {
                // Parse the request packet

                try
                {
                    request = new DnsRequest();
                    request.ParsePacket(recvBuf, cbRecv);
                }
                catch (Exception e)
                {
                    SysLog.LogException(e);
                }
            }

            // Save the remote EP and then initiate another async
            // packet receive.

            ep       = (IPEndPoint)remoteEP;
            remoteEP = new IPEndPoint(IPAddress.Any, 0);

            sock.BeginReceiveFrom(recvBuf, 0, recvBuf.Length, SocketFlags.None, ref remoteEP, onReceive, sock);

            // Process the request and transmit the response (if there is one).

            if (request != null && RequestEvent != null)
            {
                var args = new DnsServerEventArgs(ep, request);

                RequestEvent(this, args);
                if (args.Response != null)
                {
                    byte[] sendBuf;
                    int    cbSend;

                    // $todo(jeff.lill):
                    //
                    // Remove this exception code after figuring out why the
                    // response's QName field is sometimes NULL.

                    try
                    {
                        sendBuf = args.Response.FormatPacket(out cbSend);
                    }
                    catch
                    {
                        SysLog.LogError("DNS Formatting Error:\r\n\r\n" +
                                        args.Request.GetTraceDetails(ep.Address) +
                                        "\r\n" +
                                        args.Response.GetTraceDetails(ep.Address));
                        throw;
                    }

                    lock (syncLock)
                    {
                        if (sock != null)
                        {
                            sock.SendTo(sendBuf, cbSend, SocketFlags.None, args.RemoteEP);
                        }
                    }
                }
            }
        }
Пример #5
0
        /// <summary>
        /// Performs a more advanced query that load balances against a set of
        /// DNS server endpoints and also implements retry behaviors.
        /// </summary>
        /// <param name="nameServers">The set of name server IP addresses.</param>
        /// <param name="request">The DNS request.</param>
        /// <param name="timeout">The timeout to use for the initial request as well as the retries.</param>
        /// <param name="maxSendCount">The maximum number of requests to send to any single name server.</param>
        /// <returns>The received DNS response message.</returns>
        /// <remarks>
        /// <note>
        /// This DNS resolver does not implement any local caching of DNS
        /// responses.
        /// </note>
        /// </remarks>
        public static DnsResponse QueryWithRetry(IPAddress[] nameServers, DnsRequest request, TimeSpan timeout, int maxSendCount)
        {
            var ar = BeginQueryWithRetry(nameServers, request, timeout, maxSendCount, null, null);

            return(EndQueryWithRetry(ar));
        }
Пример #6
0
        /// <summary>
        /// Transmits a DNS request to a name server and then waits for and
        /// then returns the response.
        /// </summary>
        /// <param name="nameServer">IP address of the name server.</param>
        /// <param name="request">The DNS request.</param>
        /// <param name="timeout">The maximum time to wait for a response.</param>
        /// <returns>The query response.</returns>
        /// <remarks>
        /// <note>
        /// This DNS resolver does not implement any local caching of DNS
        /// responses.
        /// </note>
        /// <para>
        /// This method does not perform any iterative processing on the request
        /// or implement any retry behavior.  It simply sends a DNS message to the
        /// name server and returns the response message or throws a
        /// <see cref="TimeoutException" />.
        /// </para>
        /// <note>
        /// The method will initialize the request's <see cref="DnsMessage.QID" />
        /// property with a unique 16-bit query ID.
        /// </note>
        /// <note>
        /// This method performs no checks to verify that the
        /// response returned actually answers the question posed in the
        /// request.  The only validation performed is to verify that the
        /// message is a valid response and that its QID matches that
        /// of the request.
        /// </note>
        /// </remarks>
        public static DnsResponse Query(IPAddress nameServer, DnsRequest request, TimeSpan timeout)
        {
            var arDns = BeginQuery(nameServer, request, timeout, null, null);

            return(EndQuery(arDns));
        }