为什么dns.resolveMx在多次调用时总是返回错误?

时间:2022-05-10 23:56:48

I am trying to validate a list of email addresses (to get rid of spammy ones e.g. asdasdas@waqwqasd.com) by looking up MX records with Node.JS

我试图通过使用Node.JS查找MX记录来验证电子邮件地址列表(以摆脱垃圾邮件地址,例如asdasdas@waqwqasd.com)

My code works on one email address but when I'm calling it a lot of times I get an error from dns.resolveMx with either ETIMEOUT or ECONNREFUSED.

我的代码在一个电子邮件地址上工作,但是当我多次调用它时,我从dns.resolveMx收到ETIMEOUT或ECONNREFUSED的错误。

Here's the relevant bits:

这是相关的位:

This test code works:

此测试代码有效:

(function() {
  var dns = require('dns'); 
  var email = "test@yahoo.co.uk"
   var emailDomain;
    try
    {
      emailDomain = email.split('@')[1];

      console.log('Checking Domain ' + emailDomain);
    }
    catch(e)
    {
      return false;
    }
  dns.resolveMx("yahoo.co.uk", function (err, addresses) {
      if(err)
      {
        console.log(err);
      }
      else
      {
        console.log('Found addresses ' + JSON.stringify(addresses));  
        return true;
      }
    }
  );
})();

This code doesn't:

此代码不:

(function() {

  var dns = require('dns');
  var fs = require('fs');
  var Sync = require('sync');

  var validEmails = [];
  var invalidEmails = [];
  var validDomains = [];

  var checkEmails = function()
  {
    var fileData = fs.readFileSync('emails_only-full.txt').toString().split('\n');

    console.log(fileData.length);
    testValidEmailDomains(fileData);
  }

  var finished = function()
  {
    console.log('Finished parsing database');
    console.log('Found ' + validEmails.length + ' valid emails');
    console.log('Found ' + invalidEmails.length + ' invalid emails');    
  };

  var testValidEmailDomains = function(emails, index)
  {
    if(emails.length == 0)
    {
      finished();
      return;
    }

    var email = emails.pop();
    var emailDomain;
    try
    {
      emailDomain = email.split('@')[1];
      if(validDomains.indexOf(emailDomain) != -1)
      {
        validEmails.push(email);
        return;
      }
    }
    catch(e)
    {
      invalidEmails.push(email);
      return;
    }
    console.log('Checking Domain ' + emailDomain);    
    dns.resolveMx(emailDomain, function (err, addresses) {
      if(err)
      {
        console.log(err);
        invalidEmails.push(email);
      }
      else
      {
        validDomains.push(emailDomain);
        validEmails.push(email);
        console.log('Found addresses ' + JSON.stringify(addresses));  
      }
      testValidEmailDomains(emails.slice(index), index + 1);
    });
  }
  checkEmails();
})();

I was thinking it was to do with calling too many times at once but using Sync/fibers to sleep the thread doesn't seem to work either. Any ideas?

我当时认为它是同时调用太多次,但使用Sync /光纤来休眠线程似乎也不起作用。有任何想法吗?

1 个解决方案

#1


3  

Edit: Appears stable branch (0.10.x) does not support dns.setServers. Use https://github.com/tjfontaine/node-dns instead for dns requests in this case. See the dns.Request method. It lets you manually set the dns server in each request.

编辑:出现稳定分支(0.10.x)不支持dns.setServers。在这种情况下,请使用https://github.com/tjfontaine/node-dns代替dns请求。请参阅dns.Request方法。它允许您在每个请求中手动设置DNS服务器。

DNS servers typically block clients if too many requests are made in quick succession to avoid DNS amplification attacks. Best approach would be to:

如果快速连续发出太多请求以避免DNS放大攻击,DNS服务器通常会阻止客户端。最好的方法是:

  • Rate limit DNS requests
  • 限制DNS请求
  • Use multiple servers and cycle through them (might still get blocked by ISP or other intermediaries)
  • 使用多个服务器并循环使用它们(可能仍被ISP或其他中介阻止)
  • Cache domains that have already been checked to avoid duplicate requests
  • 缓存已经过检查的域以避免重复请求

There's a good list of DNS servers here: http://pcsupport.about.com/od/tipstricks/a/free-public-dns-servers.htm

这里有一个很好的DNS服务器列表:http://pcsupport.about.com/od/tipstricks/a/free-public-dns-servers.htm

Sample code for cycling through multiple servers:

循环访问多个服务器的示例代码:

// static list of DNS servers to use from the list above
var SERVERS = ['8.8.8.8', ...];
var SERVERS_LENGTH = servers.length;

var dns = require('dns');

// function to resolve mx records   
// loops through emails and launches parallel requests - rate limit as required
function resolve(emails, fn) {
   emails.forEach(function(email, index) {
       var nextServer = SERVERS[index % SERVERS_LENGTH];
       dns.setServers([nextServer]);
       dns.resolveMx(email, fn);
   });
}

#1


3  

Edit: Appears stable branch (0.10.x) does not support dns.setServers. Use https://github.com/tjfontaine/node-dns instead for dns requests in this case. See the dns.Request method. It lets you manually set the dns server in each request.

编辑:出现稳定分支(0.10.x)不支持dns.setServers。在这种情况下,请使用https://github.com/tjfontaine/node-dns代替dns请求。请参阅dns.Request方法。它允许您在每个请求中手动设置DNS服务器。

DNS servers typically block clients if too many requests are made in quick succession to avoid DNS amplification attacks. Best approach would be to:

如果快速连续发出太多请求以避免DNS放大攻击,DNS服务器通常会阻止客户端。最好的方法是:

  • Rate limit DNS requests
  • 限制DNS请求
  • Use multiple servers and cycle through them (might still get blocked by ISP or other intermediaries)
  • 使用多个服务器并循环使用它们(可能仍被ISP或其他中介阻止)
  • Cache domains that have already been checked to avoid duplicate requests
  • 缓存已经过检查的域以避免重复请求

There's a good list of DNS servers here: http://pcsupport.about.com/od/tipstricks/a/free-public-dns-servers.htm

这里有一个很好的DNS服务器列表:http://pcsupport.about.com/od/tipstricks/a/free-public-dns-servers.htm

Sample code for cycling through multiple servers:

循环访问多个服务器的示例代码:

// static list of DNS servers to use from the list above
var SERVERS = ['8.8.8.8', ...];
var SERVERS_LENGTH = servers.length;

var dns = require('dns');

// function to resolve mx records   
// loops through emails and launches parallel requests - rate limit as required
function resolve(emails, fn) {
   emails.forEach(function(email, index) {
       var nextServer = SERVERS[index % SERVERS_LENGTH];
       dns.setServers([nextServer]);
       dns.resolveMx(email, fn);
   });
}