How to prevent DOS attacks on my http server which written in node.js?

Problem

using node.js, the net module for building a tcp server which can hande http requests.

I would like to prevent dos attacks so what I have done is somthing like this:

if (status.numOfCurrentRequests + 1 >= MAX_NUM_OF_CONNECTIONS) {
    socket.end();
    return; 
}

I was wondering if it is better to use :

socket.destroy();

from the API :

socket.destroy() # Ensures that no more I/O activity happens on this socket. Only necessary in case of errors (parse error or so).

what are the differences and benefits?

Problem courtesy of: 0x90

Solution

A DOS attack really shouldn't be handled by your HTTP server. Once a request has reached it the attacker has 'won' by taking up a connection (no matter how short). Even if they are short they can just slam it with thousands/sec and prevent anyone else from connecting. Also, they might not attempt to 'connect' via TCP and just flood the server with all sorts of requests.

Block/detect DOS attacks at a lower level or via a firewall, which I'm sure many software and hardware versions support some basic types of DOS detection and prevention.

Solution courtesy of: Ryan Doherty

Discussion

from the API if it helps anyone, should be used smartly :

 server.pause(msecs)

Stop accepting connections for the given number of milliseconds (default is one second). This could be useful for throttling new connections against DoS attacks or other oversubscription.

Discussion courtesy of: 0x90

Total.js Framework: https://github.com/totaljs/modules/blob/master/ddos/ddos.js

var counter = 0;
var ip = {};
var ban = {};
var ban_length = 0;
var interval = 0;
exports.install = function () {
    framework.onRequest = function (req, res) {
        if (ban_length > 0 && ban[req.ip]) {
            req.connection.destroy();
            return true
        }
        var count = (ip[req.ip] || 0) + 1;
        ip[req.ip] = count;
        if (count === 1) counter++;
        if (count < exports.options.maximum) return false;
        ban[req.ip] = exports.options.minutes + 1;
        ban_length++;
        return true
    };
    setInterval(function () {
        interval++;
        var keys;
        var length;
        var count;
        if (ban_length > 0 && interval % 60 === 0) {
            keys = Object.keys(ban);
            length = keys.length;
            count = 0;
            for (var i = 0; i < length; i++) {
                var key = keys[i];
                if (ban[key]-- > 0) continue;
                ban_length--;
                delete ban[key]
            }
            if (ban_length < 0) ban_length = 0
        }
        if (counter <= 0) return;
        keys = Object.keys(ip);
        length = keys.length;
        counter = length;
        for (var i = 0; i < length; i++) {
            var key = keys[i];
            var count = ip[key]--;
            if (count > 0) continue;
            counter--;
            delete ip[key]
        }
        if (counter < 0) counter = 0
    }, 1e3)
};
exports.usage = function () {
    return {
        bans: ban_length
    }
};
exports.options = {
    maximum: 1e3,
    minutes: 5
};
Discussion courtesy of: user1796855

This recipe can be found in it's original form on Stack Over Flow.