/// <summary> /// Process domain MX query, start new tasks for each of received MX entry /// </summary> /// <param name="domainMx"></param> /// <returns></returns> private async Task ProcessDomainAsync(DomainMx domainMx) { if (_lookup == null) { return; } int mxCount = 0; var wasException = false; try { var result = await _lookup.QueryAsync(domainMx.Domain, QueryType.MX, QueryClass.IN, _cancellation.Token); domainMx.Error = result.HasError ? result.ErrorMessage : null; // result.Answers.Count may be different than real MX records count in the case of redirection var mxs = result.Answers.MxRecords(); mxCount = mxs.Count(); if (mxCount != result.Answers.Count) { domainMx.Error = $@"Bad number ({mxCount}\{result.Answers.Count}) of received MX records. Probably redirects occurred."; } domainMx.mxCount = mxCount; domainMx.MxArray = new DomainMx.MxEntry[mxCount]; if (Settings.Sort) { mxs = mxs.OrderBy(mx => mx.Preference); } var i = 0; foreach (var mx in mxs) { var entry = new DomainMx.MxEntry(domainMx, mx.Exchange, mx.Preference); ProcessExchange(entry); domainMx.MxArray[i++] = entry; } } catch (Exception e) { domainMx.Error = e.Message; wasException = true; } finally { // log info about Domain even without MX (for reporting purposes) if (mxCount == 0 || wasException) { _dataStorage?.Add(domainMx); } } }
/// <summary> /// Initialize internal _domainsDict dictionary with all domains. Depending on configuration this method can /// start tasks for processing domains immediately or process can be executed on request. /// </summary> /// <param name="domains">domains to be processed</param> /// <returns>unique domains number</returns> private int InitializeEachDomain(IEnumerable <string> domains) { var count = 0; var tasks = new List <Task>(); Func <string, DomainMx> domainsValFactory; if (Settings.Process) { domainsValFactory = k => { count++; var dmx = new DomainMx(k); tasks.Add(ProcessDomainAsync(dmx)); return(dmx); } } ; else { domainsValFactory = k => { count++; return(new DomainMx(k)); } }; foreach (var d in domains) { // filter duplicates _domainsDict.GetOrAdd(d.ToLower(), domainsValFactory); } if (Settings.Process) { _domainsTasks = WhenAllOrError(tasks); } return(count); }
public MxEntry(DomainMx owner, string exchange, ushort preference) { Owner = owner; Exchange = exchange; Preference = preference; }