diff --git a/package.json b/package.json index 42de213..25266ad 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "test": "test" }, "scripts": { - "test": "lab -v -m 20000 -p" + "test": "lab -v -m 60000 -p" }, "keywords": [ "traceroute", diff --git a/test/index.js b/test/index.js index 38676a4..932a49c 100644 --- a/test/index.js +++ b/test/index.js @@ -36,4 +36,17 @@ describe('Traceroute', () => { done(); }); }); + + it('traces a fake route and quits after 5 hops in a row', (done) => { + + Traceroute.trace('127.0.0.127', (err, hops) => { + + expect(err).to.not.exist(); + expect(hops).to.exist(); + for (let hop of hops) { + expect(hop).to.equal(false); + } + done(); + }); + }); }); diff --git a/traceroute.js b/traceroute.js index 15414be..81983ae 100644 --- a/traceroute.js +++ b/traceroute.js @@ -8,7 +8,7 @@ const Net = require('net'); const Os = require('os'); const Util = require('util'); - +const defaultMaxNullHops = 5; const internals = {}; @@ -18,10 +18,16 @@ internals.isWin = /^win/.test(Os.platform()); module.exports = internals.Traceroute = {}; -internals.Traceroute.trace = function (host, callback) { +internals.Traceroute.trace = function (host, maxNullHops, callback) { - const Emitter = function () { + if (typeof maxNullHops === 'function' && callback === undefined) { + callback = maxNullHops; + maxNullHops = defaultMaxNullHops; + } else if (maxNullHops === undefined) { + maxNullHops = defaultMaxNullHops; + } + const Emitter = function () { EventEmitter.call(this); }; Util.inherits(Emitter, EventEmitter); @@ -39,6 +45,7 @@ internals.Traceroute.trace = function (host, callback) { const hops = []; let counter = 0; + let nullHops = 0; traceroute.stdout.on('data', (data) => { ++counter; @@ -54,6 +61,18 @@ internals.Traceroute.trace = function (host, callback) { const hop = internals.parseHop(result); hops.push(hop); emitter.emit('hop', hop); + + if (hop === false) { + // count every null hop received + nullHops++; + } else { + // reset nullHops counter when a valid hop is received + nullHops = 0; + } + // send a sigint to kill the traceroute process when it reach $maxNullHops hops in a row + if (maxNullHops && nullHops >= maxNullHops) { + traceroute.kill('SIGINT'); + } }); traceroute.on('close', (code) => {