[Dnsmail-cvs] dnsmail DnsCache.cs, 1.4, 1.5 DNSAPI.cs, 1.4, 1.5 Erle.DnsMail.csproj, 1.5, 1.6
Brought to you by:
ethem
From: Ethem E. <et...@us...> - 2006-08-07 08:43:45
|
Update of /cvsroot/dnsmail/dnsmail In directory sc8-pr-cvs12.sourceforge.net:/tmp/cvs-serv29902/dnsmail Modified Files: DNSAPI.cs Erle.DnsMail.csproj Added Files: DnsCache.cs Log Message: Put back last commit. DnsCache is a good thing. Index: Erle.DnsMail.csproj =================================================================== RCS file: /cvsroot/dnsmail/dnsmail/Erle.DnsMail.csproj,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** Erle.DnsMail.csproj 4 Aug 2006 15:22:59 -0000 1.5 --- Erle.DnsMail.csproj 7 Aug 2006 08:43:41 -0000 1.6 *************** *** 100,103 **** --- 100,108 ---- /> <File + RelPath = "DnsCache.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File RelPath = "MIME.cs" SubType = "Code" *************** *** 153,155 **** </CSHARP> </VisualStudioProject> - --- 158,159 ---- Index: DNSAPI.cs =================================================================== RCS file: /cvsroot/dnsmail/dnsmail/DNSAPI.cs,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** DNSAPI.cs 4 Aug 2006 15:22:59 -0000 1.4 --- DNSAPI.cs 7 Aug 2006 08:43:41 -0000 1.5 *************** *** 10,18 **** using MxRecord = Erle.DnsMail.MxRecord; using MxRecordComparer = Erle.DnsMail.MxRecordComparer; - using DnsException = Erle.DnsMail.DnsException; public sealed class DNSAPI { private DNSAPI(){} #region LocalHost --- 10,32 ---- using MxRecord = Erle.DnsMail.MxRecord; using MxRecordComparer = Erle.DnsMail.MxRecordComparer; public sealed class DNSAPI { private DNSAPI(){} + static DNSAPI() + { + DnsCache.DeletedAll += new EventHandler(DeletedAll); + } + + #region DeletedAll + private static void DeletedAll(object sender, EventArgs e) + { + dnsServers = null; + localHost = null; + hello = null; + + GC.Collect(); + } + #endregion #region LocalHost *************** *** 87,90 **** --- 101,108 ---- return null; + MxRecord[] cache = DnsCache.GetFromCache(domain); + if (cache != null && cache.Length > 0) + return (cache); // struct-copy + IntPtr pQuery = IntPtr.Zero; UInt32 status = UnsafeNativeMethods.DnsQuery( *************** *** 97,101 **** ); ! if (status == STRUCTURES.SUCCESS && pQuery != IntPtr.Zero) { try --- 115,119 ---- ); ! if (status == STRUCTURES.SUCCESS && pQuery != IntPtr.Zero) { try *************** *** 123,126 **** --- 141,145 ---- // Resolve + bool err = false; for(int i = 0; i < mxs.Length; i++) { *************** *** 130,133 **** --- 149,153 ---- if (ipx == null || ipx.Length == 0) continue; foreach(IPAddress ipadr in ipx) mxs[i] += ipadr; + } catch(SocketException se) *************** *** 136,141 **** continue; // The requested name is valid, but no data of the requested type was found } ! catch {} } tmp.Clear(); return mxs; --- 156,168 ---- continue; // The requested name is valid, but no data of the requested type was found } ! catch ! { ! err = true; ! } } + + if (!err) + DnsCache.AddToCache(domain, mxs); + tmp.Clear(); return mxs; *************** *** 155,224 **** } #endregion - - #region InternalResolve - internal static IPAddress[] InternalResolve(ref string mailHost, ref bool usedMx, ref MxRecord[] mxss) - { - if( mailHost == null || mailHost == String.Empty || - mailHost == "localhost" || mailHost == "127.0.0.1") - mailHost = DNSAPI.LocalHost; - - if (mailHost[0] >= '1' && mailHost[0] <= '9' && IsIp4(mailHost)) - { - usedMx = false; - return new IPAddress[] { IPAddress.Parse(mailHost) }; - } - - if(usedMx) - { - mxss = DNSAPI.GetMxRecords(mailHost); - if (mxss != null && mxss.Length > 0) - { - usedMx = true; - return null; - } - } - - try - { - IPAddress[] addresses = Dns.Resolve(mailHost).AddressList; - if (addresses != null && addresses.Length > 0) - { - usedMx = false; - return addresses; - } - } - catch {} - throw new DnsException(String.Format("No" + - ( (usedMx) ? " MaileXchange (MX) or" : String.Empty ) - + " IP (A) record could be found for {0}.", mailHost)); - } - - private static bool IsIp4(string address) - { - if (address == null || - address == string.Empty || - address.IndexOf('.') == -1) - return false; - - int labelCount = 0, octet; - string[] ips = address.Split(new char[] {'.'}); - for(int i = 0; i < ips.Length; i++) - { - try - { - octet = int.Parse(ips[i]); - if ( ( octet < 0 ) || ( octet > 255 ) ) - return false; - else - labelCount++; - } - catch - { - return false; - } - } - return ( (labelCount > 0) && (labelCount < 5) ); - } - #endregion } }; --- 182,185 ---- --- NEW FILE: DnsCache.cs --- // $Id: DnsCache.cs,v 1.5 2006/08/07 08:43:41 ethem Exp $ namespace Erle { using System; using System.Text; using System.Threading; using System.Collections; using Erle.DnsMail; using System.Net; internal sealed class DnsCache { private DnsCache(){} private const double REMOVECACHEAFTER = 10.0D; private static Hashtable m_CacheTbl = new Hashtable(); private static DateTime m_NextUpdate = NextUpdate(); private static DateTime NextUpdate() { return DateTime.Now.AddMinutes(REMOVECACHEAFTER); } #region CacheEntry private struct CacheEntry { internal CacheEntry(MxRecord[] data) { // It will be deleted 2 minutes later. DeleteTime = unchecked(Environment.TickCount + 120000); RecordObj = data; } internal int DeleteTime; internal MxRecord[] RecordObj; } #endregion internal static MxRecord[] GetFromCache(String domain) { if (m_NextUpdate < DateTime.Now) DeleteAll(); try { object val = m_CacheTbl[domain]; if (val != null) { CacheEntry entry = (CacheEntry)val; if (entry.DeleteTime > Environment.TickCount) return entry.RecordObj; } } catch {} return null; } internal static void AddToCache(String domain, MxRecord[] data) { if ((domain == null) || (data == null)) throw new ArgumentNullException("data || domain"); Monitor.Enter(m_CacheTbl); try { m_CacheTbl[domain] = new CacheEntry(data); } catch{} finally { Monitor.Exit(m_CacheTbl); } } private static void DeleteAll() { m_NextUpdate = NextUpdate(); Monitor.Enter( m_CacheTbl ); try { m_CacheTbl.Clear(); } catch {} finally { Monitor.Exit(m_CacheTbl); } OnDeletedAll(EventArgs.Empty); } private static void OnDeletedAll(EventArgs e) { try { if (DeletedAll != null) DeletedAll(typeof(DnsCache), e); } catch {} } private static bool IsIp4(string address) { if (address == null || address == string.Empty || address.IndexOf('.') == -1) return false; int labelCount = 0, octet; string[] ips = address.Split(new char[] {'.'}); for(int i = 0; i < ips.Length; i++) { try { octet = int.Parse(ips[i]); if ( ( octet < 0 ) || ( octet > 255 ) ) return false; else labelCount++; } catch { return false; } } return ( (labelCount > 0) && (labelCount < 5) ); } internal static event EventHandler DeletedAll; internal static IPAddress[] InternalResolve(ref string mailHost, ref bool usedMx, ref MxRecord[] mxss) { if( mailHost == null || mailHost == String.Empty || mailHost == "localhost" || mailHost == "127.0.0.1") mailHost = DNSAPI.LocalHost; if (mailHost[0] >= '1' && mailHost[0] <= '9' && IsIp4(mailHost)) { usedMx = false; return new IPAddress[] { IPAddress.Parse(mailHost) }; } if(usedMx) { mxss = DNSAPI.GetMxRecords(mailHost); if (mxss != null && mxss.Length > 0) { usedMx = true; return null; } } try { IPAddress[] addresses = Dns.Resolve(mailHost).AddressList; if (addresses != null && addresses.Length > 0) { usedMx = false; return addresses; } } catch {} throw new DnsException(String.Format("No" + ( (usedMx) ? " MaileXchange (MX) or" : String.Empty ) + " IP (A) record could be found for {0}.", mailHost)); } static void Log(String log) { /* FileStream fs = new FileStream(@"C:\log.txt",FileMode.Append,FileAccess.Write); StreamWriter sw = new StreamWriter(fs); sw.AutoFlush = true; sw.Write(DateTime.Now.ToString() + ": " + log + "\r\n"); sw.Close(); fs.Close(); fs = null; sw = null; log =null; */ } internal static void Debug() { if (m_CacheTbl == null) return; CacheEntry ce; String crlf = "\r\n"; StringBuilder sb = new StringBuilder(); sb.Append("<ul>" + crlf); for(IDictionaryEnumerator iex = m_CacheTbl.GetEnumerator();iex.MoveNext();) { ce = (CacheEntry)iex.Value; if (ce.RecordObj != null) { MxRecord[] ht = ce.RecordObj as MxRecord[]; sb.Append("<li><b>" + iex.Key + "</b> (" + ce.DeleteTime + ")" + crlf + " <ul>" + crlf); for(int im = 0; im < ht.Length; im++) { sb.AppendFormat("\t<li>{0} (", ht[im].NameExchange); ArrayList ips = ht[im].IPAddresses; for(int i = 0; i < ips.Count; i++) sb.Append(ips[i].ToString() + ", "); sb.Append(")" + crlf); } sb.Append(" </ul>" + crlf + "</li>" + crlf); } } sb.Append("</ul>" + crlf); System.Web.HttpContext.Current.Response.Write(sb.ToString()); } } }; |