332 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			332 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /**
 | |
|  **      ==============================
 | |
|  **       O           O      O   OOOO
 | |
|  **       O           O     O O  O   O
 | |
|  **       O           O     O O  O   O
 | |
|  **       OOOO   OOOO O     OOO  OOOO
 | |
|  **       O   O       O    O   O O   O
 | |
|  **       O   O       O    O   O O   O
 | |
|  **       OOOO        OOOO O   O OOOO
 | |
|  **      ==============================
 | |
|  **      Dr. Stefan Bosse http://www.bsslab.de
 | |
|  **
 | |
|  **      COPYRIGHT: THIS SOFTWARE, EXECUTABLE AND SOURCE CODE IS OWNED
 | |
|  **                 BY THE AUTHOR(S).
 | |
|  **                 THIS SOURCE CODE MAY NOT BE COPIED, EXTRACTED,
 | |
|  **                 MODIFIED, OR OTHERWISE USED IN A CONTEXT
 | |
|  **                 OUTSIDE OF THE SOFTWARE SYSTEM.
 | |
|  **
 | |
|  **    $AUTHORS:     Stefan Bosse
 | |
|  **    $INITIAL:     (C) 2015 - 2017 bLAB
 | |
|  **    $CREATED:     1-5-15
 | |
|  **    $VERSION:     1.6.3
 | |
|  **
 | |
|  **    $INFO:
 | |
|  **
 | |
|  **  Client Request and Message Broker Server Application (HTTP connection)
 | |
|  **
 | |
|  **    $ENDOFINFO
 | |
|  */
 | |
| 
 | |
| "use strict";
 | |
| var log = 0;
 | |
| var test_trans=false;
 | |
| 
 | |
| 
 | |
| var util = Require('util');
 | |
| var Io = Require('com/io');
 | |
| //Io.trace_open('/tmp/broker.trace');
 | |
| 
 | |
| var Net = Require('dos/network');
 | |
| var Rpc = Require('dos/rpc');
 | |
| var Dns = Require('dos/dns');
 | |
| var Cs = Require('dos/capset');
 | |
| var Dns_srv = Require('dos/dns_srv');
 | |
| var ConnHTTPSrv = Require('dos/connHTTPsrv');
 | |
| var ConnNETSrv = Require('dos/connNETsrv');
 | |
| var ConnUDP = Require('dos/connUDP');
 | |
| var ConnFIFOSrv = Require('dos/connFIFOsrv');
 | |
| var ConnFIFOSrvN = Require('dos/connFIFOsrvN');
 | |
| var FileSrv = Require('dos/filesrv');
 | |
| var Conn = Require('dos/connutils');
 | |
| var Router = Require('dos/router');
 | |
| var Comp = Require('com/compat');
 | |
| var Perv = Comp.pervasives;
 | |
| var Args = Comp.args;
 | |
| var String = Comp.string;
 | |
| var Array = Comp.array;
 | |
| var assert = Comp.assert;
 | |
| var Sch = Require('dos/scheduler');
 | |
| var Fs = Require('fs');
 | |
| var satelize = Require('dos/ext/satelize');
 | |
| var getenv = Require('com/getenv');
 | |
| var Status = Net.Status;
 | |
| var Command = Net.Command;
 | |
| var Rights = Net.Rights;
 | |
| var HostSrv = Require('dos/hostsrv');
 | |
| var GeoIP = Require('geoip/geoip');
 | |
| 
 | |
| var trace = Io.tracing;
 | |
| 
 | |
| 
 | |
| var options = {
 | |
|   bip:'localhost',
 | |
|   bport:3001,
 | |
|   connections:[], // UDP P2P
 | |
|   db:undefined, // GEOIP data base root directory + enable GEOIP service
 | |
|   dip:'localhost',
 | |
|   dports:[],
 | |
|   env: {
 | |
|   },
 | |
|   fdir:'',
 | |
|   findex:'',
 | |
|   fifo:false,
 | |
|   fifodir:'/tmp/broker',
 | |
|   fifonum:2,
 | |
|   fport:3000,   // HTTP Fileserver port
 | |
|   geo:{},       // My GEO location
 | |
|   geoip:undefined,  // GEOIP service
 | |
|   hostname:Io.hostname(),
 | |
|   hport:undefined,    // RPC port
 | |
|   http:true,
 | |
|   keepalive:true,
 | |
|   links:[],     // UDP P2P
 | |
|   myip:'localhost',
 | |
|   monitor:0,
 | |
|   tcpnet:1,
 | |
|   verbose:0
 | |
| }
 | |
| 
 | |
| var help=false;
 | |
| var shift='';
 | |
| var argv = Io.getargs();
 | |
| 
 | |
| function getip(str) {
 | |
|     var tokens = String.split(':',str);
 | |
|     if (tokens.length==2) return tokens[0];
 | |
|     else if (tokens.length==1) return 'localhost';
 | |
|     else return '';
 | |
| 
 | |
| }
 | |
| 
 | |
| function getipport(str) {
 | |
|     var tokens = String.split(':', str);
 | |
|     if (tokens.length == 2) return Perv.int_of_string(tokens[1]);
 | |
|     else if (tokens.length == 1) return Perv.int_of_string(tokens[0]);
 | |
|     else return '';
 | |
| 
 | |
| }
 | |
| Args.parse(argv, [
 | |
|     [['-h','-help'],0, function() {help=true;}],
 | |
|     [['-v','-verbose'],0, function() {options.verbose++;}],
 | |
|     ['-db',1,function(val) {options.db=val;}],
 | |
|     ['-file',1,function(val) {options.fdir=val;}],
 | |
|     ['-fifo',1,function(val) {options.fifodir=val;}],
 | |
|     ['-fifonum',1,function(val) {options.fifonum=Perv.int_of_string(val);}],
 | |
|     ['-index',1,function(val) {options.findex=val;}],
 | |
|     [['-bport','-bp'],1,function(val) {options.bport=Perv.int_of_string(val);}],
 | |
|     ['-fport',1,function(val) {options.fsport=Perv.int_of_string(val);}],
 | |
|     ['-hport',1,function(val) {options.hport=Perv.int_of_string(val);}],
 | |
|     ['-D',1,function(val){options.dports.push(Perv.int_of_string(val))}],
 | |
|     ['-L',2,function(val1,val2){options.links.push([Perv.int_of_string(val1),getip(val2),getipport(val2)])}],
 | |
|     ['-monitor',0,function(val){options.monitor++;}],
 | |
|     ['-nokeepalive',0,function(val){options.keepalive=false;}],
 | |
|     ['--T',0,function(val){options.tcpnet=0;}],
 | |
|     ['-T',0,function(val){options.tcpnet=1;}],
 | |
|     ['-T2',0,function(val){options.tcpnet=2;}],
 | |
|     ['--H',0,function(val){options.http=false;}],
 | |
|     ['-H',0,function(val){options.http=true;}],
 | |
|     ['-F',0,function(val){options.fifo=true}]
 | |
| ]);
 | |
| 
 | |
| options.privhostport = Net.port_name('broker'+options.hostname+options.bport);
 | |
| options.pubhostport = Net.prv2pub(options.privhostport);
 | |
| options.hport=options.hport||options.privhostport;
 | |
| 
 | |
| if (help) {
 | |
|     Io.out('usage: '+process.argv[0]+' '+process.argv[1]);
 | |
|     Io.out('  [-h -help -v -verbose -monitor]');
 | |
|     Io.out('  [--H --T -H -F]  Disable/Enable connection service');
 | |
|     Io.out('    T: TCPIP, auto mode (1-chan, 2-chan, keepalive)');
 | |
|     Io.out('    H: bport, T: bport+100');
 | |
|     Io.out('    F: FS FIFO');
 | |
|     Io.out('    (Default: -T, -H)');
 | |
|     Io.out('  [-D <port>] UDP Server Port');
 | |
|     Io.out('  [-L <src port> <dst [address:]port] UDP P2P Connection');
 | |
|     Io.out('  [-db  <Data base directory>]  Enable GEOIP service (Default: disabled)');
 | |
|     Io.out('  [-file  <HTTP File server directory>]  (Default: disabled)');
 | |
|     Io.out('  [-index  <HTTP File server default index file>]  (Default: '+(options.findex==''?'index.html':options.findex)+')');
 | |
|     Io.out('  [-bport | -bp <HTTP/TCPNET+100 Broker server port>] (Default: HTTP '+options.bport+' TCPNET '+(options.bport+100)+')');
 | |
|     Io.out('  [-fport <HTTP Fileserver port>]  (Default : '+options.fport+')');
 | |
|     Io.out('  [-hport <Private RPC host server port>] (Default: '+Net.Print.port(options.hport)+')');
 | |
|     Io.out('  [-fifo <FIFO path and basename>] (Default: '+options.fifodir+')');
 | |
|     Io.out('  [-fifonum <Number of FIFO channels>] (Default: '+options.fifonum+')');
 | |
|     return;
 | |
| }
 | |
| 
 | |
| satelize.satelize({}, function(err, geoData) {
 | |
|     // process err
 | |
|     if (err != undefined) {
 | |
|         Io.out('[BRO] GEO Location failed: '+err)
 | |
|     } else if (geoData) {
 | |
|       try {
 | |
|         var obj = JSON.parse(geoData);
 | |
|         Io.out('[BRO] GEO Location (lati=' + obj.lat + ', long=' + obj.lon + ')');
 | |
|         options.geo=obj;
 | |
|         if (hostsrv) hostsrv.set_geo(obj);
 | |
|       } catch (e) {
 | |
|         if (options.verbose>1) Io.out('GEO Location failed: '+e+',\n'+geoData);
 | |
|         else Io.out('[BRO] GEO Location not available: '+e);
 | |
|       }
 | |
|     }
 | |
| });
 | |
| 
 | |
| 
 | |
| var scheduler = Sch.TaskScheduler();
 | |
| var router = Router.RpcRouter(options.pubhostport,options);
 | |
| router.monitor=options.monitor;
 | |
| //router.verbose=options.verbose;
 | |
| var rpc = Rpc.RpcInt(router);
 | |
| scheduler.Init();
 | |
| scheduler.Run();
 | |
| router.init();
 | |
| router.start(100);
 | |
| 
 | |
| for (var i in options.dports) {
 | |
|     var dport = options.dports[i];
 | |
|     var create = function (dport) {
 | |
|         var vlc = ConnUDP.Connection({
 | |
|           conn_port:Net.uniqport(),
 | |
|           rcv_ip:options.dip,
 | |
|           rcv_ipport:dport,
 | |
|           snd_ip:undefined,
 | |
|           snd_ipport:undefined,
 | |
|           router:router,
 | |
|           verbose:options.verbose
 | |
|         });
 | |
|         vlc.init();
 | |
|         vlc.start(function (stat) {
 | |
|             if(stat==Status.STD_OK) {
 | |
|                 // Something to connect to ?
 | |
|                 var connectit = Array.find(options.links,function (link) {return link[0]==dport;});
 | |
|                 if (connectit != undefined) {
 | |
|                     vlc.link(connectit[1],connectit[2]);
 | |
|                     vlc.watchdog(true);
 | |
|                 }
 | |
|             }
 | |
|         });
 | |
|         return vlc;
 | |
|     };
 | |
|     options.connections.push(create(dport));
 | |
| }
 | |
| 
 | |
| 
 | |
| var hostsrv = HostSrv.HostServer(
 | |
|   scheduler,rpc,
 | |
|   options,
 | |
|   'BROKER.'+options.hostname,
 | |
|   options.env);
 | |
| 
 | |
| var dns = Dns.DnsInt(rpc);
 | |
| var cs = Cs.CsInt(rpc);
 | |
| scheduler.Init();
 | |
| scheduler.Run();
 | |
| 
 | |
| 
 | |
| /*
 | |
| ** Publish local servers...
 | |
|  */
 | |
| var stat=Status.STD_UNKNOWN;
 | |
| var rootcs = hostsrv.dns.rootdir;
 | |
| 
 | |
| 
 | |
| /*
 | |
| **
 | |
| ** Standalone HTTP Brokerage Server
 | |
| ** with capability based DNS service
 | |
| **  /hosts/vm1 vm2 ...
 | |
| **  /domains/dom1/vm1 vm2 ...
 | |
| **  /agents/a1 a2 ..
 | |
| */
 | |
| 
 | |
| 
 | |
| if (options.verbose) Io.out('[BRO] Host port: '+Net.Print.port(options.pubhostport));
 | |
| 
 | |
| var connectionserver1,connectionserver2,connectionserver3;
 | |
| if (options.http) connectionserver1 = ConnHTTPSrv.Server({hostport:options.pubhostport,srv_ip:options.myip,srv_ipport:options.bport,
 | |
|                                                           router:router,verbose:options.verbose,env:options.env});
 | |
| if (options.tcpnet) connectionserver2 = ConnNETSrv.Server({hostport:options.pubhostport,srv_ip:options.myip,srv_ipport:(options.bport+100),
 | |
|                                                            router:router,verbose:options.verbose,env:options.env,
 | |
|                                                            mode:(options.tcpnet==1?Conn.Mode.ONECHAN:Conn.Mode.TWOCHAN),
 | |
|                                                            keepalive:options.keepalive});                          
 | |
| 
 | |
| if (options.fifo && options.fifonum <=2) connectionserver3 = ConnFIFOSrv.Server({hostport:options.pubhostport,router:router,
 | |
|                                                           path:options.fifodir,
 | |
|                                                           channels:options.fifonum,
 | |
|                                                           verbose:options.verbose,env:options.env});
 | |
| if (options.fifo && options.fifonum >2) connectionserver3 = ConnFIFOSrvN.Server({hostport:options.pubhostport,router:router,
 | |
|                                                           path:options.fifodir,
 | |
|                                                           channels:options.fifonum,
 | |
|                                                           verbose:options.verbose,env:options.env});
 | |
| 
 | |
| if (connectionserver1) {
 | |
|   router.add_event(Sch.Bind(connectionserver1,connectionserver1.schedule));
 | |
|   router.add_conn(connectionserver1.rpccon);
 | |
|   connectionserver1.init();
 | |
|   connectionserver1.start();
 | |
| }
 | |
| if (connectionserver2) {
 | |
|   router.add_event(Sch.Bind(connectionserver2,connectionserver2.schedule));
 | |
|   router.add_conn(connectionserver2.rpccon);
 | |
|   connectionserver2.init();
 | |
|   connectionserver2.start();
 | |
| }
 | |
| if (connectionserver3) {
 | |
|   router.add_event(Sch.Bind(connectionserver3,connectionserver3.schedule));
 | |
|   router.add_conn(connectionserver3.rpccon);
 | |
|   connectionserver3.init();
 | |
|   connectionserver3.start();
 | |
| }
 | |
| 
 | |
| if (!String.empty(options.fdir)) {
 | |
|     var fileserver = FileSrv.File({
 | |
|       srv_ip:options.myip,
 | |
|       srv_ipport:options.fport,
 | |
|       dir:options.fdir,
 | |
|       verbose:options.verbose,
 | |
|       index:options.findex
 | |
|     });
 | |
|     fileserver.init();
 | |
|     fileserver.start();
 | |
| }
 | |
| 
 | |
| if (options.db) {
 | |
|   GeoIP.dir=options.db;
 | |
|   options.geoip=GeoIP.load(function () {
 | |
|     if (options.geo.query) {
 | |
|       options.myip=options.geo.query;
 | |
|       Io.out('[GEOIP] Validating my location '+options.myip+' ..');
 | |
|       var loc = GeoIP.lookup(options.myip);
 | |
|       if (loc) {
 | |
|         options.geo = loc;        
 | |
|         Io.out('[GEOIP] Found: '+JSON.stringify(loc));
 | |
|         if (hostsrv) hostsrv.set_geo(loc);
 | |
|       }
 | |
|       var mem = Io.mem();
 | |
|       Io.out('[BRO] Allocated memory is '+((mem.data/1024)|0)+' MB');  
 | |
|     }
 | |
|   });  
 | |
| }
 | |
| 
 | |
| function stop() {
 | |
|   if (connectionserver3) connectionserver3.stop();
 | |
|   process.exit(2);
 | |
| }
 | |
| 
 | |
| process.on('SIGINT',stop);
 | |
| 
 | |
| module.exports = {
 | |
|   stop: stop
 | |
| }
 | |
| 
 |