/// <summary> /// Gets MX record collection. /// Each string is a single record formatted as "Priority,Host,TTL" /// If Null then no MX servers where found. /// </summary> /// <param name="domain">The domain to get MXs for.</param> /// <returns>See description.</returns> /// <throws>Win32 Exception. (123)</throws> internal static string[] GetMXRecords(string domain) { // Pointer to the first DNS result. IntPtr ptrFirstRecord = IntPtr.Zero; ArrayList results = new ArrayList(); try { // Do the DNS query. int retVal = dnsapi.DnsQuery_W(ref domain, QueryTypes.DNS_TYPE_MX, QueryOptions.DNS_QUERY_STANDARD, 0, ref ptrFirstRecord, 0); // If the retVal isn't 0 then something went wrong if (retVal != 0) { // There are no DNS records of type MX. if (retVal == 9003 || retVal == 9501) { return(null); } else if (retVal == 123) { throw new DNSDomainNotFoundException(); } else { //throw new Win32Exception(retVal); System.Diagnostics.Trace.WriteLine("DNS_API:" + domain + " (" + retVal + ")"); return(null); } } MXRecord recMx = (MXRecord)Marshal.PtrToStructure(ptrFirstRecord, typeof(MXRecord));; IntPtr ptrCurrentRecord = IntPtr.Zero; for (ptrCurrentRecord = ptrFirstRecord; !ptrCurrentRecord.Equals(IntPtr.Zero); ptrCurrentRecord = recMx.pNext) { recMx = (MXRecord)Marshal.PtrToStructure(ptrCurrentRecord, typeof(MXRecord)); if (recMx.wType == 15) { string line = recMx.wPreference.ToString() + "," + Marshal.PtrToStringAuto(recMx.pNameExchange) + "," + recMx.dwTtl.ToString(); results.Add(line); } } } finally { // Always cleanup. DnsRecordListFree(ptrFirstRecord, 0); } return((string[])results.ToArray(typeof(string))); }
/// <summary> /// Gets an Array of MX Records for the specified domain. If none found returns null. /// </summary> /// <param name="domain"></param> /// <returns></returns> public static MXRecord[] GetMXRecords(string domain) { // Make sure the domain is all lower. domain = domain.ToLower(); // This is what we'll be returning. MXRecord[] mxRecords = null; // Try and get DNS from internal cache. if (DNSManager._Records.TryGetValue(domain, out mxRecords)) { // Found cached records. // Make sure they haven't expired. if (mxRecords.Count((MXRecord mx) => mx.Dead) < 1) { return(mxRecords); } } string[] records = null; try { // Get the records from DNS records = dnsapi.GetMXRecords(domain); } catch (DNSDomainNotFoundException) { // Ensure records is null. records = null; } // No MX records for domain. if (records == null) { // If there are no MX records use the hostname as per SMTP RFC. MXRecord[] mxs = new MXRecord[] { new MXRecord(domain, 10, 300u, MxRecordSrc.A) }; _Records.AddOrUpdate(domain, mxs, (string key, MXRecord[] existing) => mxs); return(mxs); } mxRecords = new MXRecord[records.Length]; for (int i = 0; i < mxRecords.Length; i++) { string[] split = records[i].Split(new char[] { ',' }); if (split.Length == 3) { mxRecords[i] = new MXRecord(split[1], int.Parse(split[0]), uint.Parse(split[2]), MxRecordSrc.MX); } } // Order by preferance mxRecords = ( from mx in mxRecords where mx != null orderby mx.Preference select mx).ToArray <MXRecord>(); DNSManager._Records.TryAdd(domain, mxRecords); return(mxRecords); }