public void CleanupCache() { // remove everythign older than 15 minutes DateTime AgeLimit = DateTime.Now.AddMinutes(-15); foreach (IPAddress remoteAddress in ReverseDnsCache.Keys.ToList()) { ReverseDnsEntry value = ReverseDnsCache[remoteAddress]; if (value.TimeStamp < AgeLimit) { ReverseDnsCache.Remove(remoteAddress); } } }
public bool LookupHostName(IPAddress remoteAddress, object target, Action <object, string, NameSources> setter) { if (remoteAddress.Equals(IPAddress.Any) || remoteAddress.Equals(IPAddress.IPv6Any)) { return(true); } if (remoteAddress.Equals(IPAddress.Loopback) || remoteAddress.Equals(IPAddress.IPv6Loopback)) { return(true); } ReverseDnsEntry Entry = null; if (ReverseDnsCache.TryGetValue(remoteAddress, out Entry)) { if ((Entry.TimeStamp + (5 * 60 * 1000) >= MiscFunc.GetCurTick())) { if (Entry.HostName != null) { setter(target, Entry.HostName, NameSources.ReverseDNS); } return(true); } } if (Entry == null) { Entry = new ReverseDnsEntry(); ReverseDnsCache.Add(remoteAddress, Entry); } if (Entry.PendingJobs == null) { Entry.PendingJobs = new List <HostLookupJob>(); //AppLog.Debug("reverse looking up : {0}", remoteAddress.ToString()); // todo: use matibe api to save oin dns queries Dns.BeginGetHostEntry(remoteAddress, (x) => { // WARNING: this function is called from the worker thread //x.AsyncState IPHostEntry hostInfo = null; try { hostInfo = Dns.EndGetHostEntry(x); } catch { } App.engine?.RunInEngineThread(() => { // Note: this happens in the engine thread Entry.TimeStamp = MiscFunc.GetCurTick(); if (hostInfo != null) { Entry.HostName = hostInfo.HostName; } if (Entry.HostName != null) { foreach (var job in Entry.PendingJobs) { job.SetHostName(Entry.HostName, NameSources.ReverseDNS); } } Entry.PendingJobs = null; }); }, null); } Entry.PendingJobs.Add(new HostLookupJob() { target = new WeakReference(target), setter = setter }); return(false); }
public List <HostNameEntry> ResolveHostNames(IPAddress remoteAddress) { if (remoteAddress.Equals(IPAddress.Any) || remoteAddress.Equals(IPAddress.IPv6Any)) { return(new List <HostNameEntry>()); } if (remoteAddress.Equals(IPAddress.Loopback) || remoteAddress.Equals(IPAddress.IPv6Loopback)) { return new List <HostNameEntry>() { new HostNameEntry() { HostName = "localhost", TimeStamp = DateTime.Now } } } ; ReverseDnsEntry Entry = null; if (ReverseDnsCache.TryGetValue(remoteAddress, out Entry)) { if (Entry.HostNames.Count > 0) { List <HostNameEntry> List = new List <HostNameEntry>(); foreach (string HostName in Entry.HostNames) { List.Add(new HostNameEntry() { HostName = HostName, TimeStamp = Entry.TimeStamp }); } return(List); } else if (Entry.Pending) { return(null); } else if ((Entry.TimeStamp.AddMinutes(1) > DateTime.Now)) { return(new List <HostNameEntry>()); // dont re query if teh last query failed } } if (Entry == null) { Entry = new ReverseDnsEntry(); Entry.Pending = true; ReverseDnsCache.Add(remoteAddress, Entry); } AppLog.Debug("reverse looking up : {0}", remoteAddress.ToString()); Thread task = new Thread(() => { // WARNING: this function is called from the worker thread string AddressReverse = Address2RevDnsHost(remoteAddress); List <string> HostNames = new List <string>(); try { var resultPtr = IntPtr.Zero; if (DnsApi.DnsQuery(AddressReverse, DnsApi.DnsRecordType.PTR, DnsApi.DnsQueryType.DNS_QUERY_NO_HOSTS_FILE, IntPtr.Zero, ref resultPtr, IntPtr.Zero) == DnsApi.ERROR_SUCCESS) { for (var recordIndexPtr = resultPtr; recordIndexPtr != IntPtr.Zero;) { var record = (DnsApi.DnsRecord)Marshal.PtrToStructure(recordIndexPtr, typeof(DnsApi.DnsRecord)); int offset = Marshal.OffsetOf(typeof(DnsApi.DnsRecord), "Data").ToInt32(); IntPtr data = recordIndexPtr + offset; recordIndexPtr = record.Next; if (record.Type != DnsApi.DnsRecordType.PTR) { continue; } var ptr = (DnsApi.DnsPTRRecord)Marshal.PtrToStructure(data, typeof(DnsApi.DnsPTRRecord)); HostNames.Add(ptr.NameHost); } if (resultPtr != IntPtr.Zero) { DnsApi.DnsRecordListFree(resultPtr, DnsApi.DnsFreeType.DnsFreeRecordList); } } } catch (Exception err) { AppLog.Exception(err); } App.engine?.RunInEngineThread(() => { // Note: this happens in the engine thread Entry.TimeStamp = DateTime.Now; Entry.HostNames = HostNames; Entry.Pending = false; HostNameResolved?.Invoke(this, new DnsEvent() { RemoteAddress = remoteAddress, HostNames = HostNames /*, TimeStamp = Entry.TimeStamp*/ }); }); }); task.Start(); return(null); }