Improve project layout and abstract library from program logic.

Wed, 13 Aug 2014 21:02:03 +0200

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 13 Aug 2014 21:02:03 +0200
changeset 5
ee8de27ff264
parent 4
3de96d11e417
child 6
7d15b0868865

Improve project layout and abstract library from program logic.

src/app.js file | annotate | diff | comparison | revisions
src/bin/fork.js file | annotate | diff | comparison | revisions
src/fork.js file | annotate | diff | comparison | revisions
src/lib/app.js file | annotate | diff | comparison | revisions
     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();
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/src/bin/fork.js	Wed Aug 13 21:02:03 2014 +0200
     2.3 @@ -0,0 +1,66 @@
     2.4 +#! /usr/bin/env nodejs
     2.5 +//
     2.6 +//  mDNSGw - Zero Configuration DNS Gateway for Mesh Networks
     2.7 +//  Copyright © 2014 Michael Schloh von Bennewitz <michael@schloh.com>
     2.8 +//
     2.9 +//  Permission to use, copy, modify, and/or distribute this software for
    2.10 +//  any purpose with or without fee is hereby granted, provided that the
    2.11 +//  above copyright notice and this permission notice appear in all copies.
    2.12 +//
    2.13 +//  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
    2.14 +//  WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
    2.15 +//  WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
    2.16 +//  AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
    2.17 +//  DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
    2.18 +//  PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
    2.19 +//  ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
    2.20 +//  THIS SOFTWARE.
    2.21 +//
    2.22 +//  This file is part of mDNSGw, a Zero configuration DNS gateway
    2.23 +//  which can be found at http://dev.europalab.com/mdnsgw/
    2.24 +//
    2.25 +//  fork.js: ECMA JavaScript implementation
    2.26 +//
    2.27 +
    2.28 +/***********************************************************
    2.29 +|                  ____  _   _ ____   ____                 |
    2.30 +|        _ __ ___ |  _ \| \ | / ___| / ___|_      __       |
    2.31 +|       | '_ ` _ \| | | |  \| \___ \| |  _\ \ /\ / /       |
    2.32 +|       | | | | | | |_| | |\  |___) | |_| |\ V  V /        |
    2.33 +|       |_| |_| |_|____/|_| \_|____/ \____| \_/\_/         |
    2.34 +|                                                          |
    2.35 +| Requirements: Redis server with standard configuration   |
    2.36 +|               NodeJS and NPM modules (see package.json)  |
    2.37 +|                                                          |
    2.38 +| Execute: To start this application, launch it with the   |
    2.39 +|          script named fork.js: $ ./fork.js               |
    2.40 +|                                                          |
    2.41 +| Support: http://list.europalab.com/mailman/mdnsgs/       |
    2.42 +|                                                          |
    2.43 +***********************************************************/
    2.44 +
    2.45 +// import module dependencies
    2.46 +var forkserv = require('forever-monitor');
    2.47 +
    2.48 +
    2.49 +// configure a child process to daemonize
    2.50 +var childproc = new (forkserv.Monitor)('app.js', {
    2.51 +  max: 4,
    2.52 +  silent: true,
    2.53 +  pidFile: '/tmp/mdnsgw.pid',
    2.54 +  logFile: '/tmp/mdnsgw.log',
    2.55 +  outFile: '/tmp/mdnsgw.out',
    2.56 +  errFile: '/tmp/mdnsgw.err',
    2.57 +  options: []
    2.58 +});
    2.59 +
    2.60 +childproc.on('exit', function () {
    2.61 +  console.log('app.js has exited after 4 restarts');
    2.62 +});
    2.63 +
    2.64 +// fork a child
    2.65 +childproc.start();
    2.66 +
    2.67 +//// daemonize by exit
    2.68 +//that doesn't work
    2.69 +//process.exit(0);
     3.1 --- a/src/fork.js	Wed Aug 13 21:01:00 2014 +0200
     3.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.3 @@ -1,66 +0,0 @@
     3.4 -#! /usr/bin/env nodejs
     3.5 -//
     3.6 -//  mDNSGw - Zero Configuration DNS Gateway for Mesh Networks
     3.7 -//  Copyright © 2014 Michael Schloh von Bennewitz <michael@schloh.com>
     3.8 -//
     3.9 -//  Permission to use, copy, modify, and/or distribute this software for
    3.10 -//  any purpose with or without fee is hereby granted, provided that the
    3.11 -//  above copyright notice and this permission notice appear in all copies.
    3.12 -//
    3.13 -//  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
    3.14 -//  WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
    3.15 -//  WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
    3.16 -//  AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
    3.17 -//  DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
    3.18 -//  PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
    3.19 -//  ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
    3.20 -//  THIS SOFTWARE.
    3.21 -//
    3.22 -//  This file is part of mDNSGw, a Zero configuration DNS gateway
    3.23 -//  which can be found at http://dev.europalab.com/mdnsgw/
    3.24 -//
    3.25 -//  fork.js: ECMA JavaScript implementation
    3.26 -//
    3.27 -
    3.28 -/***********************************************************
    3.29 -|                  ____  _   _ ____   ____                 |
    3.30 -|        _ __ ___ |  _ \| \ | / ___| / ___|_      __       |
    3.31 -|       | '_ ` _ \| | | |  \| \___ \| |  _\ \ /\ / /       |
    3.32 -|       | | | | | | |_| | |\  |___) | |_| |\ V  V /        |
    3.33 -|       |_| |_| |_|____/|_| \_|____/ \____| \_/\_/         |
    3.34 -|                                                          |
    3.35 -| Requirements: Redis server with standard configuration   |
    3.36 -|               NodeJS and NPM modules (see package.json)  |
    3.37 -|                                                          |
    3.38 -| Execute: To start this application, launch it with the   |
    3.39 -|          script named fork.js: $ ./fork.js               |
    3.40 -|                                                          |
    3.41 -| Support: http://list.europalab.com/mailman/mdnsgs/       |
    3.42 -|                                                          |
    3.43 -***********************************************************/
    3.44 -
    3.45 -// import module dependencies
    3.46 -var forkserv = require('forever-monitor');
    3.47 -
    3.48 -
    3.49 -// configure a child process to daemonize
    3.50 -var childproc = new (forkserv.Monitor)('app.js', {
    3.51 -  max: 4,
    3.52 -  silent: true,
    3.53 -  pidFile: '/tmp/mdnsgw.pid',
    3.54 -  logFile: '/tmp/mdnsgw.log',
    3.55 -  outFile: '/tmp/mdnsgw.out',
    3.56 -  errFile: '/tmp/mdnsgw.err',
    3.57 -  options: []
    3.58 -});
    3.59 -
    3.60 -childproc.on('exit', function () {
    3.61 -  console.log('app.js has exited after 4 restarts');
    3.62 -});
    3.63 -
    3.64 -// fork a child
    3.65 -childproc.start();
    3.66 -
    3.67 -//// daemonize by exit
    3.68 -//that doesn't work
    3.69 -//process.exit(0);
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/src/lib/app.js	Wed Aug 13 21:02:03 2014 +0200
     4.3 @@ -0,0 +1,212 @@
     4.4 +#! /usr/bin/env nodejs
     4.5 +//
     4.6 +//  mDNSGw - Zero Configuration DNS Gateway for Mesh Networks
     4.7 +//  Copyright © 2014 Michael Schloh von Bennewitz <michael@schloh.com>
     4.8 +//
     4.9 +//  Permission to use, copy, modify, and/or distribute this software for
    4.10 +//  any purpose with or without fee is hereby granted, provided that the
    4.11 +//  above copyright notice and this permission notice appear in all copies.
    4.12 +//
    4.13 +//  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
    4.14 +//  WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
    4.15 +//  WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
    4.16 +//  AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
    4.17 +//  DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
    4.18 +//  PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
    4.19 +//  ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
    4.20 +//  THIS SOFTWARE.
    4.21 +//
    4.22 +//  This file is part of mDNSGw, a Zero configuration DNS gateway
    4.23 +//  which can be found at http://dev.europalab.com/mdnsgw/
    4.24 +//
    4.25 +//  app.js: ECMA JavaScript implementation
    4.26 +//
    4.27 +
    4.28 +/***********************************************************
    4.29 +|                  ____  _   _ ____   ____                 |
    4.30 +|        _ __ ___ |  _ \| \ | / ___| / ___|_      __       |
    4.31 +|       | '_ ` _ \| | | |  \| \___ \| |  _\ \ /\ / /       |
    4.32 +|       | | | | | | |_| | |\  |___) | |_| |\ V  V /        |
    4.33 +|       |_| |_| |_|____/|_| \_|____/ \____| \_/\_/         |
    4.34 +|                                                          |
    4.35 +| Requirements: Redis server with standard configuration   |
    4.36 +|               NodeJS and NPM modules (see package.json)  |
    4.37 +|                                                          |
    4.38 +| Execute: To start this application, launch it with the   |
    4.39 +|          script named fork.js: $ ./fork.js               |
    4.40 +|                                                          |
    4.41 +| Support: http://list.europalab.com/mailman/mdnsgs/       |
    4.42 +|                                                          |
    4.43 +***********************************************************/
    4.44 +
    4.45 +// import module dependencies
    4.46 +var mdnsinst = require('mdns');
    4.47 +var redisdat = require('redis');
    4.48 +var nameinst = require('native-dns');
    4.49 +
    4.50 +
    4.51 +// install POSIX signal handlers
    4.52 +process.on('SIGUSR2', function() {
    4.53 +  console.log('SIGUSR2: Dumping mDNSGw entries at', Date());
    4.54 +  rediscli.hgetall('hostnames', function (error, object) {console.dir(object);});
    4.55 +});
    4.56 +process.on('SIGHUP', function() {
    4.57 +  console.log('SIGHUP: Cleared all database entries at', Date());
    4.58 +  cleardb();
    4.59 +});
    4.60 +
    4.61 +// instantiate a new redis client
    4.62 +// http://www.rediscookbook.org/
    4.63 +var rediscli = redisdat.createClient();
    4.64 +rediscli.on('error', function (error) {
    4.65 +  console.log('Error ' + error);
    4.66 +});
    4.67 +
    4.68 +// clear mDNS service keys
    4.69 +function cleardb () {
    4.70 +  rediscli.del('hostnames');
    4.71 +  // this is not working unfortunately for the loop
    4.72 +  rediscli.keys('*', function (error, replies) {
    4.73 +    replies.forEach(function (reply, ident) {
    4.74 +      rediscli.del(reply, function (error, value) {
    4.75 +        if (error) throw(error);
    4.76 +      });
    4.77 +    });
    4.78 +  });
    4.79 +}
    4.80 +
    4.81 +// scan all advertised mDNS service types
    4.82 +cleardb(); // clear old data first
    4.83 +var browsall = mdnsinst.browseThemAll();
    4.84 +browsall.on('serviceUp', function(service) {
    4.85 +    // iterate through hosts and watch accordingly
    4.86 +    if (service.type.name.match(/^[a-zA-Z0-9\-]+$/)) { // mdns module hack
    4.87 +      if (service.type.protocol == 'tcp') {
    4.88 +        var browserv = mdnsinst.createBrowser(mdnsinst.tcp(service.type.name));
    4.89 +      }
    4.90 +      else if (service.type.protocol == 'udp') {
    4.91 +        var browserv = mdnsinst.createBrowser(mdnsinst.udp(service.type.name));
    4.92 +      }
    4.93 +      else if (service.type.protocol == 'sctp') {
    4.94 +        var browserv = mdnsinst.createBrowser(mdnsinst.sctp(service.type.name));
    4.95 +      }
    4.96 +      else throw(error);
    4.97 +
    4.98 +      // common logic for all transports (TCP, UDP, SCTP, etcetera)
    4.99 +      browserv.on('serviceUp', function(service) {
   4.100 +        //console.log('service up: ', service);
   4.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']}
   4.102 +
   4.103 +        // insert one or more IP addresses for each hostname.local.
   4.104 +        rediscli.hset('hostnames', service.host.replace(/\.$/, ''), service.addresses);
   4.105 +      });
   4.106 +      browserv.on('serviceDown', function(service) {
   4.107 +        console.log('service down: ', service);
   4.108 +        //FIXME: still need to selectively remove hosts
   4.109 +      });
   4.110 +      browserv.on('serviceChanged', function(service) {
   4.111 +        console.log('service changed: ', service);
   4.112 +        //FIXME: still need to selectively update hosts
   4.113 +      });
   4.114 +      browserv.start();
   4.115 +    }
   4.116 +});
   4.117 +browsall.start();
   4.118 +
   4.119 +// instantiate a new DNS server
   4.120 +var nameserv = nameinst.createServer();
   4.121 +
   4.122 +nameserv.on('request', function (request, response) {
   4.123 +  //console.log(request)
   4.124 +
   4.125 +  // ensure that requested hostname is present
   4.126 +  rediscli.hget('hostnames', request.question[0].name, function (error, value) {
   4.127 +    // handle unexpected errors
   4.128 +    if (error) throw(error);
   4.129 +
   4.130 +    if (value) { // the db succeeded in finding a match
   4.131 +      // populate the DNS response with the chosen hostname
   4.132 +      rediscli.hkeys('hostnames', function (error, replies) {
   4.133 +          replies.forEach(function (host, index) {
   4.134 +            if (request.question[0].name == host) {
   4.135 +              rediscli.hget('hostnames', host, function (error, value) {
   4.136 +                // handle unexpected errors
   4.137 +                if (error) throw(error);
   4.138 +
   4.139 +                // FIXME: still must handle multihomed hosts
   4.140 +                //// a host might have more than one address
   4.141 +                //value.forEach(function (addr, iter)
   4.142 +                // set the nameserver address
   4.143 +                response.answer.push(nameinst.A({
   4.144 +                  name: host,
   4.145 +                  address: value,
   4.146 +                  ttl: 600,
   4.147 +                }));
   4.148 +                response.send();
   4.149 +              });
   4.150 +            }
   4.151 +          });
   4.152 +      });
   4.153 +    }
   4.154 +    else {
   4.155 +      response.answer.push(nameinst.A({
   4.156 +      name: request.question[0].name,
   4.157 +      address: '127.0.0.1',
   4.158 +      ttl: 600,
   4.159 +      }));
   4.160 +      response.send();
   4.161 +    }
   4.162 +  });
   4.163 +});
   4.164 +
   4.165 +// DNS error handler logic
   4.166 +nameserv.on('error', function (err, buff, req, res) {
   4.167 +  console.log('DNS problem: ', err.stack);
   4.168 +});
   4.169 +
   4.170 +//// debug process user
   4.171 +//console.log('Start.');
   4.172 +//console.log(process.env.USER);
   4.173 +//console.log(process.env.SUDO_USER);
   4.174 +//console.log('Done.');
   4.175 +//
   4.176 +// <1024 must run privileged
   4.177 +var nudpport = 53; // default DNS
   4.178 +if (nudpport < 1024 && process.getuid() !== 0) {
   4.179 +  //console.log('Serving on port <1024 from an unprivileged user.\nChange to root if using a privileged port number.')
   4.180 +  throw new Error('Serving on port <1024 from an unprivileged user.')
   4.181 +}
   4.182 +
   4.183 +// start the DNS process
   4.184 +nameserv.serve(nudpport, function () {
   4.185 +  try {
   4.186 +    console.log('Starting mDNSGw on', Date());
   4.187 +    process.stdout.write('Old UID: ' + process.getuid() + ', Old GID: ' + process.getgid() + '... ');
   4.188 +    process.umask('0644');
   4.189 +    process.setgid('daemon');
   4.190 +    if (process.env.SUDO_USER)
   4.191 +      process.setuid(process.env.SUDO_USER);
   4.192 +    else
   4.193 +      process.setuid('daemon');
   4.194 +    console.log('New UID: ' + process.getuid() + ', New GID: ' + process.getgid());
   4.195 +  } catch (err) {
   4.196 +    console.log('Cowardly refusing to keep the process alive as root.');
   4.197 +    process.exit(1);
   4.198 +  }
   4.199 +});
   4.200 +
   4.201 +//// debug print all key and value database entries
   4.202 +//rediscli.hgetall('hostnames', function (error, object) {console.dir(object);});
   4.203 +
   4.204 +//// display stored mDNS service data entries
   4.205 +//rediscli.hkeys('hostnames', function (error, replies) {
   4.206 +//  console.log(replies.length + ' replies:');
   4.207 +//  replies.forEach(function (reply, ident) {
   4.208 +//    console.log('    ' + ident + ': ' + reply);
   4.209 +//  });
   4.210 +//});
   4.211 +
   4.212 +//// block executes on program termination
   4.213 +//rediscli.quit();  // cleanup db connection
   4.214 +//browserv.stop();  // zombie scope too bad
   4.215 +//browsall.stop();

mercurial