Beispiel #1
0
        /// <summary>复制</summary>
        /// <param name="entity"></param>
        public virtual DNSEntity CloneFrom(DNSEntity entity)
        {
            var de = this;

            de.Header      = entity.Header;
            de.Questions   = entity.Questions;
            de.Answers     = entity.Answers;
            de.Authoritis  = entity.Authoritis;
            de.Additionals = entity.Additionals;

            return(de);
        }
Beispiel #2
0
        private void Client_Received(Object sender, ReceivedEventArgs e)
        {
            var pk = e.Packet;

            if (pk.Total == 0)
            {
                return;
            }

            var dns = DNSEntity.Read(pk.GetStream(), Client.Local.IsTcp);

            OnReceive(dns);
        }
Beispiel #3
0
        /// <summary>接收处理</summary>
        /// <param name="session"></param>
        /// <param name="pk"></param>
        protected override void OnReceive(INetSession session, Packet pk)
        {
            var isTcp = session.Session.Local.IsTcp;

            // 解析
            var request = DNSEntity.Read(pk.GetStream(), isTcp);

            var response = Request(session, request);

            if (response != null)
            {
                response.Header.ID = request.Header.ID;
                Response(session, request, response);
            }

            session.Dispose();
        }
Beispiel #4
0
        /// <summary>处理响应</summary>
        /// <param name="session"></param>
        /// <param name="request"></param>
        /// <param name="response"></param>
        protected virtual void Response(INetSession session, DNSEntity request, DNSEntity response)
        {
            var ss = session?.Session;

            if (ss == null)
            {
                return;
            }

            var isTcp = ss.Local.IsTcp;

            if (OnResponse != null)
            {
                var e = new DNSEventArgs {
                    Request = request, Response = response, Session = ss
                };
                OnResponse(this, e);
            }

            session?.Send(response.GetStream(isTcp));
        }
Beispiel #5
0
        /// <summary>异步查询解析</summary>
        /// <param name="dns"></param>
        /// <returns></returns>
        public virtual async Task <DNSEntity> QueryAsync(DNSEntity dns)
        {
            if (!Open())
            {
                return(null);
            }

            var nc = Client;

            var tcs = new TaskCompletionSource <DNSEntity>();

            _recv = tcs;

            // 发送请求
            var ms = dns.GetStream(nc.Local.IsTcp);

            nc.Send(ms.ReadBytes());

            Total++;

            return(await tcs.Task);
        }
Beispiel #6
0
        /// <summary>处理请求</summary>
        /// <param name="session"></param>
        /// <param name="request"></param>
        /// <returns></returns>
        protected virtual DNSEntity Request(INetSession session, DNSEntity request)
        {
            var local = session.Session.Local;
            var isTcp = local.IsTcp;

            // 处理,修改
            WriteLog("{0} 请求 {1}", session.Session.Remote, request);

            // 请求事件,如果第二参数有值,则直接返回
            // 结合数据库缓存,可以在这里进行返回
            if (OnRequest != null)
            {
                var e = new DNSEventArgs
                {
                    Request = request
                };
                OnRequest(this, e);
                if (e.Response != null)
                {
                    return(e.Response);
                }
            }

            // 如果是PTR请求
            var rq = request.Questions[0];

            if (rq.Type == DNSQueryType.PTR)
            {
                var ptr = RequestPTR(request);
                if (ptr != null)
                {
                    return(ptr);
                }
            }

            // 读取缓存
            //var rs = cache.GetItem(request.ToString(), k => GetDNS(k, request));
            var key = request.ToString();
            var rs  = cache[key];

            if (rs == null)
            {
                cache[key] = rs = GetDNS(key, request);
            }

            // 返回给客户端
            if (rs != null)
            {
                // 如果是PTR请求
                if (rq.Type == DNSQueryType.PTR && rs.Questions[0].Type == DNSQueryType.PTR)
                {
                    var ptr = rq as DNS_PTR;
                    if (rs.GetAnswer() is DNS_PTR ptr2)
                    {
                        ptr2.Name       = ptr.Name;
                        ptr2.DomainName = DomainName;
                    }
                    if (rs.Answers != null && rs.Answers.Length > 0)
                    {
                        foreach (var item in rs.Answers)
                        {
                            if (item.Type == DNSQueryType.PTR)
                            {
                                item.Name = ptr.Name;
                            }
                        }
                    }
                }
            }

            return(rs);
        }
Beispiel #7
0
        internal DNSEntity Invoke(DNSEntity request, Boolean isQuery)
        {
            var attempts = 0;

            while (attempts <= _maxRetryAttemps)
            {
                var bytes = request.GetStream(false).ReadBytes();

                if (bytes.Length > 512)
                {
                    throw new ArgumentException("RFC 1035 2.3.4 states that the maximum size of a UDP datagram is 512 octets (bytes).");
                }

                Socket socket = null;

                try
                {
                    socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)
                    {
                        ReceiveTimeout = 300
                    };
                    //socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 300);

                    socket.SendTo(bytes, bytes.Length, SocketFlags.None, new IPEndPoint(IPAddress.Parse("192.168.178.255"), 137));

                    if (!isQuery)
                    {
                        return(null);
                    }

                    // Messages carried by UDP are restricted to 512 bytes (not counting the IP
                    // or UDP headers).  Longer messages are truncated and the TC bit is set in
                    // the header. (RFC 1035 4.2.1)
                    var responseMessage = new Byte[512];

                    //int numBytes = socket.Receive(responseMessage);

                    var ep       = (EndPoint) new IPEndPoint(new IPAddress(4294967295), 137);
                    var numBytes = socket.ReceiveFrom(responseMessage, ref ep);

                    if (numBytes == 0 || numBytes > 512)
                    {
                        throw new Exception("RFC 1035 2.3.4 states that the maximum size of a UDP datagram is 512 octets (bytes).");
                    }

                    //DnsReader br = new DnsReader(responseMessage);
                    //DnsResponse res = new DnsResponse(br);
                    var rs = DNSEntity.Read(responseMessage, false);

                    if (request.Header.ID == rs.Header.ID)
                    {
                        return(rs);
                    }

                    attempts++;
                }
                catch
                {
                    attempts++;
                }
                finally
                {
                    socket.Close();
                    socket = null;
                }
            }

            throw new Exception("Could not resolve the query (" + attempts + " attempts).");
        }
Beispiel #8
0
 DNSEntity Invoke(DNSEntity request) => Invoke(request, true);
Beispiel #9
0
        /// <summary>使用一批DNS客户端发起请求</summary>
        /// <param name="clients"></param>
        /// <param name="dns"></param>
        /// <param name="msTimeout"></param>
        /// <returns></returns>
        public static IDictionary <DNSClient, DNSEntity> QueryAll(IEnumerable <DNSClient> clients, DNSEntity dns, Int32 msTimeout = 1000)
        {
            DNSClient[] cs = null;
            lock (clients) { cs = clients.ToArray(); }

            // 所有客户端同时发出请求
            var ts = new List <Task <DNSEntity> >();

            foreach (var client in cs)
            {
                var task = client.QueryAsync(dns);
                ts.Add(task);
            }

            // 等待所有客户端响应,或者超时
            Task.WaitAll(ts.ToArray(), msTimeout);

            // 获取结果
            var dic = new Dictionary <DNSClient, DNSEntity>();

            for (var i = 0; i < cs.Length; i++)
            {
                var rs = ts[i].Result;
                if (rs != null)
                {
                    dic.Add(cs[i], rs);
                }
            }

            return(dic);
        }