/// <summary> /// 响应一个没有记录 /// </summary> /// <param name="dnsPack">原始数据</param> /// <param name="client">客户端节点</param> private void ResponsenNonDomain(DnsPack dnsPack, EndPoint client) { //标记为响应 dnsPack.QR = 1; //标记位未找到 dnsPack.Rcode = 3; //响应客户端 server.SendTo(dnsPack.ToBytes(), client); }
/// <summary> /// 响应一个没有记录 /// </summary> /// <param name="dnsPack">原始数据</param> /// <param name="client">客户端节点</param> private void ResponsenNonDomain(byte[] dnsPack, EndPoint client) { DnsPack dnsPack_ = new DnsPack(dnsPack); //标记为响应 dnsPack_.QR = 1; //标记位未找到 dnsPack_.Rcode = 3; //响应客户端 server.SendTo(dnsPack_.ToBytes(), client); }
/// <summary> /// 响应DNS请求 /// </summary> /// <param name="DnsPack">响应数据</param> /// <param name="client">客户端节点</param> private void Response(DnsPack dnsPack, EndPoint client) { //响应并记录缓存 server.SendTo(dnsPack.ToBytes(), client); //如果有解析到记录,则缓存数据 //实际应该针对每条资源的TLL缓存,这里直接缓存了整个数据包 if (dnsPack.Rcode == 0) { if (dnsPack.ResouceRecords.Count > 0 || dnsPack.GrantResouces.Count > 0 || dnsPack.AdditResouces.Count > 0) { dataBase.WriteCache(dnsPack); } } //触发事件,修改统计数值 RelaySum++; SumChanged(this, EventArgs.Empty); }
/// <summary> /// 域名解析过程 /// </summary> /// <param name="data"></param> private void Working(WorkingData data) { DnsPack dnsPack = new DnsPack(data.dnsPack); EndPoint client = data.client; //本机PTR指针 if (dnsPack.QR == 0 && dnsPack.Opcode == 0 && dnsPack.QueryRecords.Count >= 1) { if (dnsPack.QueryRecords[0].QueryType == QueryType.PTR) { string hostName = Dns.GetHostName(); IPAddress[] localhost = Dns.GetHostAddresses(hostName); foreach (IPAddress IP in localhost) { if (IP.AddressFamily == AddressFamily.InterNetwork) { byte[] ip = IP.GetAddressBytes(); string ptrstr = string.Format("{3}.{2}.{1}.{0}.{4}", ip[0], ip[1], ip[2], ip[3], @"in-addr.arpa"); if (dnsPack.QueryRecords[0].QueryName == ptrstr || dnsPack.QueryRecords[0].QueryName == @"1.0.0.127.in-addr.arpa") { dnsPack.QR = 1; dnsPack.RA = 1; dnsPack.RD = 1; dnsPack.ResouceRecords = new List <ResouceRecord> { new ResouceRecord { Point = IPAddress.HostToNetworkOrder(BitConverter.ToInt16(new byte[] { 192, 12 }, 0)), Datas = dnsPack.getNameByts(SeaFish.Settings.Custom.ServerName), TTL = 100, QueryClass = 1, QueryType = QueryType.PTR, } }; Response(dnsPack.ToBytes(), client); return; } } } } else if (dnsPack.QueryRecords[0].QueryType == QueryType.A) { if (dnsPack.QueryRecords[0].QueryName == SeaFish.Settings.Custom.ServerName) { dnsPack.QR = 1; dnsPack.RA = 1; dnsPack.RD = 1; dnsPack.ResouceRecords = new List <ResouceRecord> { new ResouceRecord { Point = IPAddress.HostToNetworkOrder(BitConverter.ToInt16(new byte[] { 192, 12 }, 0)), Datas = new byte[] { 127, 0, 0, 1 }, TTL = 100, QueryClass = 1, QueryType = QueryType.A, } }; Response(dnsPack.ToBytes(), client); return; } } } byte[] cache; if (dataBase.ReadHost(dnsPack, out cache)) { //如果存在host Response(cache, client); } else if (dataBase.ReadCache(dnsPack, out cache)) { //如果存在缓存数据 DnsPack dnsCache = new DnsPack(cache) { //这里需要修改识别标识 Sign = dnsPack.Sign, }; Response(dnsCache.ToBytes(), client); } else { //无缓存则直接转发 RelayDNS(data.dnsPack, client); } }
/// <summary> /// 转发DNS包 /// </summary> /// <param name="buff">包内容字节数组</param> /// <param name="read">包大小</param> private void RelayDNS(byte[] buff, EndPoint client) { List <Task> taskList = new List <Task>(); bool isResponse = false; DnsPack[] dnsPacks; IPEndPoint[] server = new IPEndPoint[4]; server[0] = new IPEndPoint(SeaFish.Settings.Custom.Server1, 53); //公共DNS服务器IP server[1] = new IPEndPoint(SeaFish.Settings.Custom.Server2, 53); //公共DNS服务器IP server[2] = new IPEndPoint(SeaFish.Settings.Custom.Server3, 53); //公共DNS服务器IP server[3] = new IPEndPoint(SeaFish.Settings.Custom.Server4, 53); //公共DNS服务器IP int Relay = SeaFish.Settings.Custom.Relay; switch (Relay) { case 0: //国内优先 //首先用境内DNS解析,如果解析到境外IP,则使用境外DNS再次解析 ResponsenNonDomain(buff, client); break; case 1: //国际优先 //首先用境外DNS解析,如果解析到境内IP,则使用境内DNS再次解析 ResponsenNonDomain(buff, client); break; case 2: //仅国内 RelayDns(false); break; case 3: //仅国际 RelayDns(true); break; default: ResponsenNonDomain(buff, client); return; } void RelayDns(bool inter) { //同时转发给两台服务器 int index = (inter) ? 2 : 0; int Count = 0; dnsPacks = new DnsPack[2]; for (int i = 0; i <= 1; i++) { TaskFactory taskfactory = new TaskFactory(); taskList.Add(taskfactory.StartNew(new Action <object>(t => { int index_ = int.Parse(t.ToString()); dnsPacks[index_] = new DnsPack(SendUDP(server[index + index_], buff)); dnsPacks[index_].Tag = index_; }), i).ContinueWith(m => { Count++; if (!isResponse) { foreach (DnsPack dns in dnsPacks) { if (!dns.Success) { continue; } if (dns.Rcode != 0) { continue; } if (dns.ResouceRecords.Count >= 1 || dns.GrantResouces.Count >= 1 || dns.AdditResouces.Count >= 1) { foreach (ResouceRecord dnsr in dns.ResouceRecords) { if (dnsr.QueryClass == 1 && dnsr.QueryType == QueryType.A) { Debug.WriteLine("数据来源:{0}\t中国地址:{1}\t解析值:{3}\t问题:{2}", server[index + dns.Tag], IPinChina(dnsr.Datas), dns.QueryRecords[0].QueryName, new IPAddress(dnsr.Datas).ToString()); } } Response(dns, client); isResponse = true; return; } } } if (Count >= 2) { //所有服务器响应,但没有结果 ResponsenNonDomain(buff, client); } })); } } bool IPinChina(byte[] IPadd) { try { String IPAddres = new IPAddress(IPadd).ToString(); string nettexts = SeaFish.Extend.ReadFile(basePaht).Replace("\r\n", "\n"); string[] networks = nettexts.Split((char)10); foreach (string net in networks) { if (SeaFish.Extend.IP_IN_Nework(IPAddres, net)) { return(true); } } } catch {} return(false); } }