public string QueryByIp6(Ip6 ip) { mapLock2.EnterReadLock(); try { if (mapIp6Host.TryGetValue(ip, out var host)) { return(host); } return(null); } finally { mapLock2.ExitReadLock(); } }
private static void ipFilter(IPAddress[] ips, ref uint[] ipLongs, ref Ip6[] ips6) { int count = 0, count6 = 0; for (int i = 0; i < ips.Length; i++) { var cur = ips[i]; if (cur.AddressFamily == AddressFamily.InterNetwork) { count++; } else if (cur.AddressFamily == AddressFamily.InterNetworkV6) { count6++; } } if (count > 0) { ipLongs = new uint[count]; } if (count6 > 0) { ips6 = new Ip6[count6]; } int ipLongsCur = 0; int ips6Cur = 0; for (int i = 0; i < ips.Length; i++) { var cur = ips[i]; if (cur.AddressFamily == AddressFamily.InterNetwork) { ipLongs[ipLongsCur++] = (uint)cur.Address; } else if (cur.AddressFamily == AddressFamily.InterNetworkV6) { ips6[ips6Cur++] = new Ip6(cur); } } }
private IEnumerable <BsonDocument> FindDocByIp6(Ip6 ip, bool old) { return(engine.Find(ColRecords, Query.EQ(old ? "idx_oldips6" : "idx_ips6", ip.ToBytes()))); }
private async Task <IResponse> HandleDnsRequest(IRequest request) { var q = request; var r = Response.FromRequest(request); r.ResponseCode = ResponseCode.ServerFailure; try { var questions = q.Questions; if (questions.Count == 0) { Logger.warning($"id {q.Id} does not contain any questions." + $"\nAdditionalRecords: {string.Join(", ", q.AdditionalRecords)}"); } // var queryNames = new Dictionary <Domain, DnsRequestType>(); foreach (var item in questions) { if (item.Type == RecordType.A || item.Type == RecordType.AAAA) { DnsRequestType type = item.Type == RecordType.A ? DnsRequestType.A : DnsRequestType.AAAA; if (verbose) { Logger.debugForce($"id {q.Id} query: {item}"); } if (!queryNames.ContainsKey(item.Name)) { queryNames.Add(item.Name, type); } else { queryNames[item.Name] |= type; } } else if (item.Type == RecordType.PTR) { } else { Logger.warning("Unsupported DNS record: " + item); } } foreach (var kv in queryNames) { DnsRequestType reqType = kv.Value; bool reqv4 = (reqType & DnsRequestType.A) != 0; bool reqv6 = (reqType & DnsRequestType.AAAA) != 0; var strName = kv.Key.ToString(); IEnumerable <IPAddress> ips = emptyIps; IpRecord val = new IpRecord(); bool exist = cacheDns?.QueryByName(strName, out val) ?? false; var now = DateTime.Now; if (val.expire < now) { val.ipLongs = null; } if (val.expire6 < now) { val.ips6 = null; } var ipLongs = val.ipLongs; var ips6 = val.ips6; if (!exist || (reqv4 && ipLongs == null) || (reqv6 && ips6 == null)) { var startTime = Logging.getRuntime(); var task = StartResolve(reqType, strName, out var newTask); try { try { var resp = await task; if (resp != null) { var iparr = resp.Addresses; ips = iparr; ipFilter(iparr, ref ipLongs, ref ips6); } } catch (Exception e) { if (newTask) { Logger.warning("resolving: " + strName + " (" + reqType + "): " + e.Message + " (" + (Logging.getRuntime() - startTime) + " ms)"); } continue; } if (newTask) { Logger.info("" + strName + " (" + reqType + ") -> " + string.Join("|", ips) + " (" + (Logging.getRuntime() - startTime) + " ms)"); var newExpire = DateTime.Now.AddSeconds(cache_ttl); // If we requested only A records (not AnAAAA) and an empty result returned, then there's // really no A records, so we can cache the empty result: if (reqType == DnsRequestType.A && ipLongs == null) { ipLongs = new uint[0]; } if (ipLongs != null) { val.ipLongs = ipLongs; val.expire = newExpire; } // The same reason: if (reqType == DnsRequestType.AAAA && ips6 == null) { ips6 = new Ip6[0]; } if (ips6 != null) { val.ips6 = ips6; val.expire6 = newExpire; } cacheDns?.Set(strName, ref val); } } finally { if (newTask) { EndResolve(strName, task); } } } if (reqv4 && ipLongs != null) { foreach (var item in ipLongs) { r.AnswerRecords.Add(new ResourceRecord(kv.Key, BitConverter.GetBytes(item), RecordType.A, ttl: TimeSpan.FromSeconds(ttl))); } } if (reqv6 && ips6 != null) { foreach (var item in ips6) { r.AnswerRecords.Add(new ResourceRecord(kv.Key, item.ToBytes(), RecordType.AAAA, ttl: TimeSpan.FromSeconds(ttl))); } } r.ResponseCode = ResponseCode.NoError; } } catch (Exception e) { Logger.exception(e, Logging.Level.Error, "server"); } return(r); }
public string QueryByIp6(Ip6 ip) { return(QueryByIpCore(ip, FindDocByIp6, x => x.ToIPAddress())); }