private void Client_Received(Object sender, ReceivedEventArgs e) { if (e.Length == 0) { return; } var dns = DNSEntity.Read(e.Stream, Client.Local.IsTcp); OnReceive(dns); }
/// <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); }
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); }
/// <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(); }
/// <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)); } }
/// <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)); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
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); }
/// <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); }
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)."); }
DNSEntity Invoke(DNSEntity request) => Invoke(request, true);
DNSEntity Invoke(DNSEntity request) { return(Invoke(request, true)); }