1.1 --- a/src/app.js Wed Aug 13 21:01:00 2014 +0200 1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 1.3 @@ -1,212 +0,0 @@ 1.4 -#! /usr/bin/env nodejs 1.5 -// 1.6 -// mDNSGw - Zero Configuration DNS Gateway for Mesh Networks 1.7 -// Copyright © 2014 Michael Schloh von Bennewitz <michael@schloh.com> 1.8 -// 1.9 -// Permission to use, copy, modify, and/or distribute this software for 1.10 -// any purpose with or without fee is hereby granted, provided that the 1.11 -// above copyright notice and this permission notice appear in all copies. 1.12 -// 1.13 -// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 1.14 -// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 1.15 -// WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 1.16 -// AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 1.17 -// DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 1.18 -// PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS 1.19 -// ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF 1.20 -// THIS SOFTWARE. 1.21 -// 1.22 -// This file is part of mDNSGw, a Zero configuration DNS gateway 1.23 -// which can be found at http://dev.europalab.com/mdnsgw/ 1.24 -// 1.25 -// app.js: ECMA JavaScript implementation 1.26 -// 1.27 - 1.28 -/*********************************************************** 1.29 -| ____ _ _ ____ ____ | 1.30 -| _ __ ___ | _ \| \ | / ___| / ___|_ __ | 1.31 -| | '_ ` _ \| | | | \| \___ \| | _\ \ /\ / / | 1.32 -| | | | | | | |_| | |\ |___) | |_| |\ V V / | 1.33 -| |_| |_| |_|____/|_| \_|____/ \____| \_/\_/ | 1.34 -| | 1.35 -| Requirements: Redis server with standard configuration | 1.36 -| NodeJS and NPM modules (see package.json) | 1.37 -| | 1.38 -| Execute: To start this application, launch it with the | 1.39 -| script named fork.js: $ ./fork.js | 1.40 -| | 1.41 -| Support: http://list.europalab.com/mailman/mdnsgs/ | 1.42 -| | 1.43 -***********************************************************/ 1.44 - 1.45 -// import module dependencies 1.46 -var mdnsinst = require('mdns'); 1.47 -var redisdat = require('redis'); 1.48 -var nameinst = require('native-dns'); 1.49 - 1.50 - 1.51 -// install POSIX signal handlers 1.52 -process.on('SIGUSR2', function() { 1.53 - console.log('SIGUSR2: Dumping mDNSGw entries at', Date()); 1.54 - rediscli.hgetall('hostnames', function (error, object) {console.dir(object);}); 1.55 -}); 1.56 -process.on('SIGHUP', function() { 1.57 - console.log('SIGHUP: Cleared all database entries at', Date()); 1.58 - cleardb(); 1.59 -}); 1.60 - 1.61 -// instantiate a new redis client 1.62 -// http://www.rediscookbook.org/ 1.63 -var rediscli = redisdat.createClient(); 1.64 -rediscli.on('error', function (error) { 1.65 - console.log('Error ' + error); 1.66 -}); 1.67 - 1.68 -// clear mDNS service keys 1.69 -function cleardb () { 1.70 - rediscli.del('hostnames'); 1.71 - // this is not working unfortunately for the loop 1.72 - rediscli.keys('*', function (error, replies) { 1.73 - replies.forEach(function (reply, ident) { 1.74 - rediscli.del(reply, function (error, value) { 1.75 - if (error) throw(error); 1.76 - }); 1.77 - }); 1.78 - }); 1.79 -} 1.80 - 1.81 -// scan all advertised mDNS service types 1.82 -cleardb(); // clear old data first 1.83 -var browsall = mdnsinst.browseThemAll(); 1.84 -browsall.on('serviceUp', function(service) { 1.85 - // iterate through hosts and watch accordingly 1.86 - if (service.type.name.match(/^[a-zA-Z0-9\-]+$/)) { // mdns module hack 1.87 - if (service.type.protocol == 'tcp') { 1.88 - var browserv = mdnsinst.createBrowser(mdnsinst.tcp(service.type.name)); 1.89 - } 1.90 - else if (service.type.protocol == 'udp') { 1.91 - var browserv = mdnsinst.createBrowser(mdnsinst.udp(service.type.name)); 1.92 - } 1.93 - else if (service.type.protocol == 'sctp') { 1.94 - var browserv = mdnsinst.createBrowser(mdnsinst.sctp(service.type.name)); 1.95 - } 1.96 - else throw(error); 1.97 - 1.98 - // common logic for all transports (TCP, UDP, SCTP, etcetera) 1.99 - browserv.on('serviceUp', function(service) { 1.100 - //console.log('service up: ', service); 1.101 - //{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']} 1.102 - 1.103 - // insert one or more IP addresses for each hostname.local. 1.104 - rediscli.hset('hostnames', service.host.replace(/\.$/, ''), service.addresses); 1.105 - }); 1.106 - browserv.on('serviceDown', function(service) { 1.107 - console.log('service down: ', service); 1.108 - //FIXME: still need to selectively remove hosts 1.109 - }); 1.110 - browserv.on('serviceChanged', function(service) { 1.111 - console.log('service changed: ', service); 1.112 - //FIXME: still need to selectively update hosts 1.113 - }); 1.114 - browserv.start(); 1.115 - } 1.116 -}); 1.117 -browsall.start(); 1.118 - 1.119 -// instantiate a new DNS server 1.120 -var nameserv = nameinst.createServer(); 1.121 - 1.122 -nameserv.on('request', function (request, response) { 1.123 - //console.log(request) 1.124 - 1.125 - // ensure that requested hostname is present 1.126 - rediscli.hget('hostnames', request.question[0].name, function (error, value) { 1.127 - // handle unexpected errors 1.128 - if (error) throw(error); 1.129 - 1.130 - if (value) { // the db succeeded in finding a match 1.131 - // populate the DNS response with the chosen hostname 1.132 - rediscli.hkeys('hostnames', function (error, replies) { 1.133 - replies.forEach(function (host, index) { 1.134 - if (request.question[0].name == host) { 1.135 - rediscli.hget('hostnames', host, function (error, value) { 1.136 - // handle unexpected errors 1.137 - if (error) throw(error); 1.138 - 1.139 - // FIXME: still must handle multihomed hosts 1.140 - //// a host might have more than one address 1.141 - //value.forEach(function (addr, iter) 1.142 - // set the nameserver address 1.143 - response.answer.push(nameinst.A({ 1.144 - name: host, 1.145 - address: value, 1.146 - ttl: 600, 1.147 - })); 1.148 - response.send(); 1.149 - }); 1.150 - } 1.151 - }); 1.152 - }); 1.153 - } 1.154 - else { 1.155 - response.answer.push(nameinst.A({ 1.156 - name: request.question[0].name, 1.157 - address: '127.0.0.1', 1.158 - ttl: 600, 1.159 - })); 1.160 - response.send(); 1.161 - } 1.162 - }); 1.163 -}); 1.164 - 1.165 -// DNS error handler logic 1.166 -nameserv.on('error', function (err, buff, req, res) { 1.167 - console.log('DNS problem: ', err.stack); 1.168 -}); 1.169 - 1.170 -//// debug process user 1.171 -//console.log('Start.'); 1.172 -//console.log(process.env.USER); 1.173 -//console.log(process.env.SUDO_USER); 1.174 -//console.log('Done.'); 1.175 -// 1.176 -// <1024 must run privileged 1.177 -var nudpport = 53; // default DNS 1.178 -if (nudpport < 1024 && process.getuid() !== 0) { 1.179 - //console.log('Serving on port <1024 from an unprivileged user.\nChange to root if using a privileged port number.') 1.180 - throw new Error('Serving on port <1024 from an unprivileged user.') 1.181 -} 1.182 - 1.183 -// start the DNS process 1.184 -nameserv.serve(nudpport, function () { 1.185 - try { 1.186 - console.log('Starting mDNSGw on', Date()); 1.187 - process.stdout.write('Old UID: ' + process.getuid() + ', Old GID: ' + process.getgid() + '... '); 1.188 - process.umask('0644'); 1.189 - process.setgid('daemon'); 1.190 - if (process.env.SUDO_USER) 1.191 - process.setuid(process.env.SUDO_USER); 1.192 - else 1.193 - process.setuid('daemon'); 1.194 - console.log('New UID: ' + process.getuid() + ', New GID: ' + process.getgid()); 1.195 - } catch (err) { 1.196 - console.log('Cowardly refusing to keep the process alive as root.'); 1.197 - process.exit(1); 1.198 - } 1.199 -}); 1.200 - 1.201 -//// debug print all key and value database entries 1.202 -//rediscli.hgetall('hostnames', function (error, object) {console.dir(object);}); 1.203 - 1.204 -//// display stored mDNS service data entries 1.205 -//rediscli.hkeys('hostnames', function (error, replies) { 1.206 -// console.log(replies.length + ' replies:'); 1.207 -// replies.forEach(function (reply, ident) { 1.208 -// console.log(' ' + ident + ': ' + reply); 1.209 -// }); 1.210 -//}); 1.211 - 1.212 -//// block executes on program termination 1.213 -//rediscli.quit(); // cleanup db connection 1.214 -//browserv.stop(); // zombie scope too bad 1.215 -//browsall.stop();