/// <summary> /// Get server IP for each MX entry. The last processed MX entry will add to _dataStorage fully processed /// DomainMx instance /// </summary> /// <param name="entry"></param> /// <returns></returns> private async Task ProcessExchangeAsync(DomainMx.MxEntry entry) { if (_lookup == null) { return; } // find IP of each exchange server try { var result = await _lookup.QueryAsync(entry.Exchange, QueryType.A, QueryClass.IN, _cancellation.Token); entry.Error = result.HasError ? result.ErrorMessage : null; if (entry.Error != null) { return; } var resp = result.Answers.ARecords().First(); entry.ExchangeIp = resp.Address.ToString(); } finally { if (Interlocked.Increment(ref entry.Owner.mxProcessed) == entry.Owner.mxCount) { _dataStorage?.Add(entry.Owner); } } }
/// <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); } } }
private void ProcessExchange(DomainMx.MxEntry entry) => _exchangeTasks.Add(ProcessExchangeAsync(entry));