# HG changeset patch # User Michael Schloh von Bennewitz # Date 1407861160 -7200 # Node ID eb6d4ce6fd78960b330e9577e87490fa950cf43b Import initial revisions of new project mDNSGw. diff -r 000000000000 -r eb6d4ce6fd78 .hgignore --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.hgignore Tue Aug 12 18:32:40 2014 +0200 @@ -0,0 +1,22 @@ +syntax: glob +*.orig +*.rej +*.swp +*.o +*~ + +# custom paths +old +proto + +# files too big to track +graphics/ubudesktop.xcf + +syntax: regexp +.*\#.*\#$ + +# ignore all but text or sav (saved not forgotton) extensions +doc/(?!.*\.sav$|.*\.txt$|.*\.f?odt$).+ + +# ignore all but most important design files +design/(?!.*\.graffle$).+ diff -r 000000000000 -r eb6d4ce6fd78 doc/authors.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/authors.txt Tue Aug 12 18:32:40 2014 +0200 @@ -0,0 +1,4 @@ +Design, Implementation +Michael Schloh von Bennewitz +http://michael.schloh.com/ +michael@schloh.com diff -r 000000000000 -r eb6d4ce6fd78 doc/changelog.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/changelog.txt Tue Aug 12 18:32:40 2014 +0200 @@ -0,0 +1,11 @@ +Change log in reverse cron order + +00000000 Release version 1.0.0 + +20140812 Release version 0.7.0 + Implement main program logic + Develop build framework + +20140811 Release prototype 0.6.0 + +20140810 Project creation diff -r 000000000000 -r eb6d4ce6fd78 doc/license.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/license.txt Tue Aug 12 18:32:40 2014 +0200 @@ -0,0 +1,11 @@ +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED “AS IS” AND ISC DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY +SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff -r 000000000000 -r eb6d4ce6fd78 doc/readme.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/readme.txt Tue Aug 12 18:32:40 2014 +0200 @@ -0,0 +1,41 @@ + ____ _ _ ____ ____ + _ __ ___ | _ \| \ | / ___| / ___|_ __ + | '_ ` _ \| | | | \| \___ \| | _\ \ /\ / / + | | | | | | |_| | |\ |___) | |_| |\ V V / + |_| |_| |_|____/|_| \_|____/ \____| \_/\_/ + + mDNSGw - Zero Configuration DNS Gateway for Mesh Networks + Version 0.7.0 (14-Aug-2014) + + ABSTRACT + + Mesh networks consisting of independent subnets and nodes benefit + from a enhanced degree of zero configuration operation. A robust + network serves the interests of consumers of such applications as + found in the Internet of Things for example, where independent nodes + communicate with one another over a self maintaining autonomous + Internet platform. + + COPYRIGHT AND LICENSE + + Copyright (c) 2014 Michael Schloh von Bennewitz + + Permission to use, copy, modify, and/or distribute this software for + any purpose with or without fee is hereby granted, provided that the + above copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF + THIS SOFTWARE. + + HOME AND DOCUMENTATION + + Documentation and releases are located at + + o http://dev.europalab.com/mdnsgw/ + o ftp://ftp.europalab.com//pub/sfw/mdnsgw/ diff -r 000000000000 -r eb6d4ce6fd78 doc/todo.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/todo.txt Tue Aug 12 18:32:40 2014 +0200 @@ -0,0 +1,19 @@ +Unmet requirements + +Milestone release 1.2.0 (secondary enhancements) + Hardcore ::1 for all AAAA requests. + +Milestone release 1.1.0 (primary enhancements) + Reloop when a service goes down. + Remove hostnames not in use. + +Milestone release 1.0.0 (testing complete) + Test multiple addresses in redis. + Include redis quit() and mdns stop(). + +Milestone release 0.9.0 (code complete) + Remove servinames redis logic. + Use forever or similar to daemonize. + +Unscheduled items + None. diff -r 000000000000 -r eb6d4ce6fd78 package.json --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/package.json Tue Aug 12 18:32:40 2014 +0200 @@ -0,0 +1,54 @@ +{ + "name": "mdnsgate", + "version": "0.7.0", + "description": "MDNS gateway for DNS clients", + "main": "src/fork.js", + "directories": {"doc": "doc", "src": "src"}, + "bin": {"mdnsgw": "bin/fork.js"}, + "man": { + "name": "mdnsgw", + "version": "0.7.0", + "description": "A zeroconf DNS gateway", + "main": "fork.js", + "man": "man/mdnsgw.8" + }, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [ + "dns", + "mdns", + "gateway", + "server" + ], + "dependencies": { + "redis": "*", + "mdns": "*", + "native-dns": "*", + "forever-monitor": "*" + }, + "devDependencies": {}, + "bundleDependencies": [], + "engines": { + "node": ">= 0.6.0", + "npm": ">= 1.0.0" + }, + "author": { + "name": "Michael Schloh von Bennewitz", + "email": "michael@schloh.com", + "url": "http://michael.schloh.com/" + }, + "maintainers": [{ + "name": "Arthur Fonzarelli", + "email": "arthur@thefonz.it", + "web": "http://www.thefonz.it/" + }], + "homepage": "http://dev.europalab.com/mdnsgw/", + "bugs": {"email": "mdnsgw@europalab.com"}, + "repository": { + "type": "mercurial", + "url": "https://scm.europalab.com/mdnsgw/" + }, + "license": "ISC", + "private": true +} diff -r 000000000000 -r eb6d4ce6fd78 src/app.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/app.js Tue Aug 12 18:32:40 2014 +0200 @@ -0,0 +1,166 @@ +#! /usr/bin/env nodejs +// +// mDNSGw - Zero Configuration DNS Gateway for Mesh Networks +// Copyright © 2014 Michael Schloh von Bennewitz +// +// Permission to use, copy, modify, and/or distribute this software for +// any purpose with or without fee is hereby granted, provided that the +// above copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +// AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +// DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +// PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +// ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +// THIS SOFTWARE. +// +// This file is part of mDNSGw, a Zero configuration DNS gateway +// which can be found at http://dev.europalab.com/mdnsgw/ +// +// app.js: ECMA JavaScript implementation +// + +/*********************************************************** +| ____ _ _ ____ ____ | +| _ __ ___ | _ \| \ | / ___| / ___|_ __ | +| | '_ ` _ \| | | | \| \___ \| | _\ \ /\ / / | +| | | | | | | |_| | |\ |___) | |_| |\ V V / | +| |_| |_| |_|____/|_| \_|____/ \____| \_/\_/ | +| | +| Requirements: Redis server with standard configuration | +| NodeJS and NPM modules (see package.json) | +| | +| Execute: To start this application, launch it with the | +| script named fork.js: $ ./fork.js | +| | +| Support: http://list.europalab.com/mailman/mdnsgs/ | +| | +***********************************************************/ + +// import module dependencies +var mdnsinst = require('mdns'); +var redisdat = require('redis'); +var nameinst = require('native-dns'); + + +// instantiate a new redis client +// http://www.rediscookbook.org/ +var rediscli = redisdat.createClient(); +rediscli.on('error', function (error) { + console.log('Error ' + error); +}); + +// clear mDNS service keys +rediscli.del('hostnames'); +// this is not working unfortunately for the loop +rediscli.keys('*', function (error, replies) { + replies.forEach(function (reply, ident) { + rediscli.del(reply, function (error, value) { + if (error) throw(error); + }); + }); +}); + +// scan all advertised mDNS service types +var browsall = mdnsinst.browseThemAll(); +browsall.on('serviceUp', function(service) { + // iterate through hosts and watch accordingly + if (service.type.name.match(/^[a-zA-Z0-9\-]+$/)) { // mdns module hack + if (service.type.protocol == 'tcp') { + var browserv = mdnsinst.createBrowser(mdnsinst.tcp(service.type.name)); + } + else if (service.type.protocol == 'udp') { + var browserv = mdnsinst.createBrowser(mdnsinst.udp(service.type.name)); + } + else if (service.type.protocol == 'sctp') { + var browserv = mdnsinst.createBrowser(mdnsinst.sctp(service.type.name)); + } + else throw(error); + + // common logic for all transports (TCP, UDP, SCTP, etcetera) + browserv.on('serviceUp', function(service) { + //console.log('service up: ', service); + //{interfaceIndex: 2, type: {name: 'ssh', protocol: 'tcp', subtypes: [], fullyQualified: true}, replyDomain: 'local.', flags: 2, name: 'hostname-mich', networkInterface: 'eth0', fullname: 'hostname-mich._ssh._tcp.local.', host: 'hostname-mich.local.', port: 22, addresses: ['192.168.1.50']} + + // insert one or more IP addresses for each hostname.local. + rediscli.hset('hostnames', service.host.replace(/\.$/, ''), service.addresses); + }); + browserv.on('serviceDown', function(service) { + //console.log('service down: ', service); + //FIXME: still need to selectively remove hosts + }); + browserv.start(); + } +}); +browsall.start(); + +// instantiate a new DNS server +var nameserv = nameinst.createServer(); + +nameserv.on('request', function (request, response) { + //console.log(request) + + // ensure that requested hostname is present + rediscli.hget('hostnames', request.question[0].name, function (error, value) { + // handle unexpected errors + if (error) throw(error); + + if (value) { // the db succeeded in finding a match + // populate the DNS response with the chosen hostname + rediscli.hkeys('hostnames', function (error, replies) { + replies.forEach(function (host, index) { + if (request.question[0].name == host) { + rediscli.hget('hostnames', host, function (error, value) { + // handle unexpected errors + if (error) throw(error); + + // FIXME: still must handle multihomed hosts + //// a host might have more than one address + //value.forEach(function (addr, iter) + // set the nameserver address + response.answer.push(nameinst.A({ + name: host, + address: value, + ttl: 600, + })); + response.send(); + }); + } + }); + }); + } + else { + response.answer.push(nameinst.A({ + name: request.question[0].name, + address: '127.0.0.1', + ttl: 600, + })); + response.send(); + } + }); +}); + +// DNS error handler logic +nameserv.on('error', function (err, buff, req, res) { + console.log('DNS problem: ', err.stack); +}); + +nameserv.serve(15353); + +//// debug print all key and value database entries +//rediscli.hgetall('hostnames', function (error, object) {console.dir(object);}); + +//// display stored mDNS service data entries +//rediscli.hkeys('hostnames', function (error, replies) { +// console.log(replies.length + ' replies:'); +// replies.forEach(function (reply, ident) { +// console.log(' ' + ident + ': ' + reply); +// }); +//}); + +//// block executes on program termination +//rediscli.quit(); // cleanup db connection +//browserv.stop(); // zombie scope too bad +//browsall.stop(); diff -r 000000000000 -r eb6d4ce6fd78 src/fork.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/fork.js Tue Aug 12 18:32:40 2014 +0200 @@ -0,0 +1,62 @@ +#! /usr/bin/env nodejs +// +// mDNSGw - Zero Configuration DNS Gateway for Mesh Networks +// Copyright © 2014 Michael Schloh von Bennewitz +// +// Permission to use, copy, modify, and/or distribute this software for +// any purpose with or without fee is hereby granted, provided that the +// above copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +// AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +// DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +// PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +// ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +// THIS SOFTWARE. +// +// This file is part of mDNSGw, a Zero configuration DNS gateway +// which can be found at http://dev.europalab.com/mdnsgw/ +// +// fork.js: ECMA JavaScript implementation +// + +/*********************************************************** +| ____ _ _ ____ ____ | +| _ __ ___ | _ \| \ | / ___| / ___|_ __ | +| | '_ ` _ \| | | | \| \___ \| | _\ \ /\ / / | +| | | | | | | |_| | |\ |___) | |_| |\ V V / | +| |_| |_| |_|____/|_| \_|____/ \____| \_/\_/ | +| | +| Requirements: Redis server with standard configuration | +| NodeJS and NPM modules (see package.json) | +| | +| Execute: To start this application, launch it with the | +| script named fork.js: $ ./fork.js | +| | +| Support: http://list.europalab.com/mailman/mdnsgs/ | +| | +***********************************************************/ + +// import module dependencies +var forkserv = require('forever-monitor'); + + +// configure a child process to daemonize +var childproc = new (forkserv.Monitor)('app.js', { + max: 4, + silent: true, + pidFile: 'mdnsgw.pid', + logFile: 'mdnsgw.log', + outFile: 'mdnsgw.out', + errFile: 'mdnsgw.err', + options: [] +}); + +childproc.on('exit', function () { + console.log('app.js has exited after 4 restarts'); +}); + +// fork a child +childproc.start();