Q:

Why is dns.resolveMx always returning an error when called many times?

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
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.
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?

A:

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.
DNS servers typically block clients if too many requests are made in quick succession to avoid DNS amplification attacks. Best approach would be to:

Rate limit DNS requests
Use multiple servers and cycle through them (might still get blocked by ISP or other intermediaries)
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
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);
   });
}

