Beispiel #1
0
 public string QueryByIp6(Ip6 ip)
 {
     mapLock2.EnterReadLock();
     try {
         if (mapIp6Host.TryGetValue(ip, out var host))
         {
             return(host);
         }
         return(null);
     } finally {
         mapLock2.ExitReadLock();
     }
 }
Beispiel #2
0
        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);
                }
            }
        }
Beispiel #3
0
 private IEnumerable <BsonDocument> FindDocByIp6(Ip6 ip, bool old)
 {
     return(engine.Find(ColRecords, Query.EQ(old ? "idx_oldips6" : "idx_ips6", ip.ToBytes())));
 }
Beispiel #4
0
        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);
        }
Beispiel #5
0
 public string QueryByIp6(Ip6 ip)
 {
     return(QueryByIpCore(ip, FindDocByIp6, x => x.ToIPAddress()));
 }