예제 #1
0
        private void Client_Received(Object sender, ReceivedEventArgs e)
        {
            if (e.Length == 0)
            {
                return;
            }

            var dns = DNSEntity.Read(e.Stream, Client.Local.IsTcp);

            OnReceive(dns);
        }
예제 #2
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);
        }
예제 #3
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);
        }
예제 #4
0
        /// <summary>接收处理</summary>
        /// <param name="session"></param>
        /// <param name="stream"></param>
        protected override void OnReceive(INetSession session, Stream stream)
        {
            var isTcp = session.Session.Local.IsTcp;

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

            var response = Request(session, request);

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

            session.Dispose();
        }
예제 #5
0
        /// <summary>处理响应</summary>
        /// <param name="session"></param>
        /// <param name="request"></param>
        /// <param name="response"></param>
        protected virtual void Response(ISocketSession session, DNSEntity request, DNSEntity response)
        {
            var isTcp = session.Local.IsTcp;

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

            if (session != null && !session.Disposed)
            {
                session.Send(response.GetStream(isTcp));
            }
        }
예제 #6
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));
        }
예제 #7
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);
        }
예제 #8
0
        /// <summary>注册</summary>
        /// <param name="name">名称</param>
        /// <param name="address"></param>
        /// <returns></returns>
        public Boolean Register(String name, IPAddress address)
        {
            //DnsRequest request = new DnsRequest(new Question(EncodeName(name), DnsType.NB, DnsClass.IN));
            var request = new DNSEntity();

            request.Questions[0].Name         = EncodeName(name);
            request.Header.Opcode             = DNSOpcodeType.Registration;
            request.Header.RecursionAvailable = false;
            request.Header.RecursionDesired   = false;
            request.Header.Broadcast          = false;


            var add = new DNS_NB();

            add.Name    = EncodeName(name);
            add.TTL     = new TimeSpan(0, 0, 30);
            add.Address = address;

            request.Additionals = new DNSRecord[] { add };

            var res = Invoke(request, false);

            return(true);
        }
예제 #9
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);
        }
예제 #10
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 (int i = 0; i < cs.Length; i++)
            {
                var task = ts[i];
                if (task.IsOK() && task.Result != null)
                {
                    dic.Add(cs[i], task.Result);
                }
            }

            return(dic);
        }
예제 #11
0
        DNSEntity GetDNS(String key, DNSEntity request)
        {
            // 请求父级代理
            NetUri parent = null;

            Byte[]        data   = null;
            ISocketClient client = null;

            NetUri[] us = null;
            lock (Parents) { us = Parents.ToArray(); }

            foreach (var item in us)
            {
                WriteLog("GetDNS key={0} {1}", key, item);
                client = item.CreateRemote();
                // 如果是PTR请求
                if (request.IsPTR)
                {
                    // 复制一份,防止修改外部
                    request = new DNSEntity().CloneFrom(request);

                    var ptr = request.GetAnswer(true) as DNS_PTR;
                    if (ptr != null)
                    {
                        ptr.Address = item.Address;
                    }
                }

                try
                {
                    client.Timeout = 1000;
                    client.Send(request.GetStream(item.IsTcp));
                    data = client.Receive();

                    if (data != null && data.Length > 0)
                    {
                        parent = item;
                        break;
                    }
                }
                catch { }
            }
            if (data == null || data.Length < 1)
            {
                return(null);
            }

            // 调到第一位
            if (Parents.Count > 1 && Parents[0] != parent)
            {
                lock (Parents)
                {
                    if (Parents.Count > 1 && Parents[0] != parent)
                    {
                        Parents.Remove(parent);
                        Parents.Insert(0, parent);
                    }
                }
            }

            DNSEntity response = null;

            try
            {
                // 解析父级代理返回的数据
                response = DNSEntity.Read(data, parent.IsTcp);

                // 处理,修改
                WriteLog("{0} 返回 {1}", parent, response);
            }
            catch (Exception ex)
            {
                String file = String.Format("dns_{0:MMddHHmmss}.bin", DateTime.Now);
                XTrace.WriteLine("解析父级代理返回数据出错!数据保存于" + file + "。" + ex.Message);
                File.WriteAllBytes(file, data);
            }

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

            return(response);
        }
예제 #12
0
        /// <summary>处理请求</summary>
        /// <param name="session"></param>
        /// <param name="request"></param>
        /// <returns></returns>
        protected virtual DNSEntity Request(ISocketSession session, DNSEntity request)
        {
            var isTcp = session.Local.IsTcp;

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

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

            // 如果是PTR请求
            if (request.IsPTR)
            {
                var ptr = RequestPTR(request);
                if (ptr != null)
                {
                    return(ptr);
                }
            }

            // 读取缓存
            var rs = cache.GetItem <DNSEntity>(request.ToString(), request, GetDNS);

            // 返回给客户端
            if (rs != null)
            {
                // 如果是PTR请求
                if (request.IsPTR && rs.IsPTR)
                {
                    var ptr  = request.Questions[0] as DNS_PTR;
                    var ptr2 = rs.GetAnswer() as DNS_PTR;
                    if (ptr2 != null)
                    {
                        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);
        }
예제 #13
0
파일: NetBIOS.cs 프로젝트: yuyu2you/X_NET40
        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).");
        }
예제 #14
0
파일: NetBIOS.cs 프로젝트: yuyu2you/X_NET40
 DNSEntity Invoke(DNSEntity request) => Invoke(request, true);
예제 #15
0
 DNSEntity Invoke(DNSEntity request)
 {
     return(Invoke(request, true));
 }