#!/usr/bin/env node /* -*- Mode:js */ /* vim: set expandtab ts=4 sw=4: */ /* * You may redistribute this program and/or modify it under the terms of * the GNU General Public License as published by the Free Software Foundation, * either version 3 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ var Cjdns = require('../contrib/nodejs/cjdnsadmin/cjdnsadmin'); var nThen = require('../contrib/nodejs/cjdnsadmin/nthen'); var Dns = require('dns'); var WAIT_TIME = 5000; var INTERVAL = 1000; var now = function () { return (new Date()).getTime(); }; var nowSeconds = function () { return Math.floor(now() / 1000); }; var IP6_REGEX = new RegExp('^' + new Array(9).join(':[0-9a-f]{1,4}').substring(1) + '$'); var LABEL_REGEX = new RegExp('^' + new Array(5).join('.[0-9a-f]{4}').substring(1) + '$'); var ADDR_REGEX = new RegExp('^v[0-9]+' + new Array(5).join('\\.[0-9a-f]{4}') + '\\.[a-z0-9]{52}\\.k$'); var validTarget = function (target) { if (IP6_REGEX.test(target)) { return true; } if (LABEL_REGEX.test(target)) { return true; } if (ADDR_REGEX.test(target)) { return true; } return false; }; var main = function (argv) { var maxCount = Math.Infinity; var keyPing = (argv.indexOf('-k') !== -1); var switchMode = (argv.indexOf('-s') !== -1) || keyPing; var data = ''; if (argv.indexOf('-d') !== -1) { data = argv[argv.indexOf('-d') + 1]; if (!switchMode) { console.log('-d data flag not possible without -s'); return; } } if (argv.indexOf('-c') !== -1) { maxCount = argv[argv.indexOf('-c') + 1]; } var target = argv[argv.length-1]; var cjdns; nThen(function (waitFor) { Cjdns.connectWithAdminInfo(waitFor(function (c) { cjdns = c; })); if (!validTarget(target)) { Dns.lookup(target, 6, waitFor(function (err, res) { if (err) { throw err; } console.log(target + ' has ip address ' + res); target = res; })); } }).nThen(function (waitFor) { var count = 0; var routerPing = function () { if (count++ >= maxCount) { return; } var startTime = now(); cjdns.RouterModule_pingNode(target, WAIT_TIME, waitFor(function (err, ret) { if (err) { throw err; } if (ret.result === 'timeout') { console.log( nowSeconds() + ' timeout p' + ret.version + ' ' + ret.ms + 'ms'); } else if (ret.result === 'pong') { console.log(nowSeconds() + ' ' + ret.addr + ' ' + ret.ms + 'ms'); } else if (ret.error === 'not_found') { console.log(nowSeconds() + " No route to host"); } else { console.log(ret); } var pingIn = INTERVAL - (now() - startTime); if (pingIn < 0) { pingIn = 0; } setTimeout(waitFor(routerPing), pingIn); })); }; var switchPing = function (keyPing) { if (count++ >= maxCount) { return; } var startTime = now(); cjdns.SwitchPinger_ping(target, WAIT_TIME, keyPing^0, data, waitFor(function (err, ret) { if (err) { throw err; } var out = nowSeconds() + ' switchPing '; if (ret.result === 'timeout') { out += 'timeout ' + ret.ms + 'ms'; } else if (ret.result === 'pong') { out += ret.path + ' p' + ret.version + ' ' + ret.ms + 'ms'; if (ret.key) { out += ' ' + ret.key; } } else { out += JSON.stringify(ret); } console.log(out); var pingIn = INTERVAL - (now() - startTime); if (pingIn < 0) { pingIn = 0; } setTimeout(waitFor(switchPing), pingIn); })); }; if (switchMode) { switchPing(keyPing); } else { routerPing(); } }).nThen(function (waitFor) { cjdns.disconnect(); }); }; main(process.argv);