From 969dff9671797e21659af0f5ff9e6aa3f5e3ad8b Mon Sep 17 00:00:00 2001 From: Christopher Baines Date: Mon, 24 Feb 2014 23:07:50 +0000 Subject: Some things --- lib/chutney/TorNet.py | 93 +++++++++++++++++++++--------------------------- networks/hidden-service | 50 ++++++++++++++++++++++---- torrc_templates/common.i | 1 + 3 files changed, 85 insertions(+), 59 deletions(-) diff --git a/lib/chutney/TorNet.py b/lib/chutney/TorNet.py index 8e3df89..559b635 100644 --- a/lib/chutney/TorNet.py +++ b/lib/chutney/TorNet.py @@ -21,6 +21,8 @@ import re import errno import time +import stem.control + import chutney.Templating import chutney.Traffic @@ -35,6 +37,9 @@ def mkdir_p(d, mode=0777): return raise +global nodelist +nodelist = [] + class Node(object): """A Node represents a Tor node or a set of Tor nodes. It's created in a network configuration file. @@ -56,9 +61,12 @@ class Node(object): self._env = self._createEnviron(parent, kwargs) self._builder = None self._controller = None + self._stemcontroller = None + nodelist.append(self) - def getN(self, N): - return [ Node(self) for _ in xrange(N) ] + @staticmethod + def create(number, args): + return [Node(kwargs = args) for i in range(0, number)] def specialize(self, **kwargs): return Node(parent=self, **kwargs) @@ -83,6 +91,14 @@ class Node(object): self._controller = LocalNodeController(self._env) return self._controller + def getStemController(self): + """Return a NodeController instance to control this node (that is, + to start it, stop it, see if it's running, etc.) + """ + if self._stemcontroller is None: + self._stemcontroller = stem.control.Controller.from_port(port = self._env['controlport']) + return self._stemcontroller + def setNodenum(self, num): """Assign a value to the 'nodenum' element of this node. Each node in a network gets its own nodenum. @@ -466,43 +482,17 @@ class LocalNodeController(NodeController): "--quiet", "-f", torrc, ] - forkPid = -1 - noDelay = isChild = isParent = False - if self._env['delay']: - try: - forkPid = os.fork() - if forkPid == 0: - isChild = True - time.sleep(self._env['delay']) - else: - isParent = True - - except OSError, e: - print "Could not delay launch of %s (%s): %s"%(self._env['nick'], - " ".join(cmdline), - e.strerror()) - return False - else: - noDelay = True - - retval = True - if noDelay or isChild: - p = subprocess.Popen(cmdline) - # XXXX this requires that RunAsDaemon is set. - p.wait() - if p.returncode != 0: - print "Couldn't launch %s (%s): %s"%(self._env['nick'], - " ".join(cmdline), - p.returncode) - retval = True - if isChild: - print "Launching %s after %d seconds" % (self._env['nick'], - self._env['delay']) - sys.exit(retval) - elif isParent: - print "Delaying launch of %s for %d seconds"%(self._env['nick'], - self._env['delay']) - return retval + + p = subprocess.Popen(cmdline) + # XXXX this requires that RunAsDaemon is set. + p.wait() + if p.returncode != 0: + print "Couldn't launch %s (%s): %s"%(self._env['nick'], + " ".join(cmdline), + p.returncode) + return False + + return True def stop(self, sig=signal.SIGINT): @@ -655,9 +645,9 @@ class Network(object): self.start() def start(self): - print "Starting nodes" + print "Starting network" self._dfltEnv['start_time'] = time.time() - return all([n.getController().start() for n in self._nodes]) + return self._start() def hup(self): print "Sending SIGHUP to nodes" @@ -707,34 +697,33 @@ class Network(object): ('localhost', int(op._env['socksport'])))) return tt.run() -def ConfigureNodes(nodelist): - network = _THE_NETWORK - - for n in nodelist: - network._addNode(n) - if n._env['bridgeauthority']: - network._dfltEnv['hasbridgeauth'] = True - def usage(network): return "\n".join(["Usage: chutney {command} {networkfile}", "Known commands are: %s" % ( " ".join(x for x in dir(network) if not x.startswith("_")))]) def runConfigFile(verb, f): - _GLOBALS = dict(_BASE_ENVIRON= _BASE_ENVIRON, + _GLOBALS = dict(_BASE_ENVIRON = _BASE_ENVIRON, Node=Node, - ConfigureNodes=ConfigureNodes, + EventType=stem.control.EventType, _THE_NETWORK=_THE_NETWORK) exec f in _GLOBALS network = _GLOBALS['_THE_NETWORK'] + for n in nodelist: + network._addNode(n) + if n._env['bridgeauthority']: + network._dfltEnv['hasbridgeauth'] = True + + network._start = _GLOBALS['start'] + if not hasattr(network, verb): print usage(network) print "Error: I don't know how to %s." % verb return - return getattr(network,verb)() + return getattr(network, verb)() def main(): global _BASE_ENVIRON diff --git a/networks/hidden-service b/networks/hidden-service index 3f000e1..bcaf0ef 100644 --- a/networks/hidden-service +++ b/networks/hidden-service @@ -1,10 +1,46 @@ -Authority = Node(tag="a", authority=1, relay=1, torrc="authority.tmpl") -Relay = Node(tag="r", relay=1, torrc="intro.tmpl") -Client = Node(tag="c", torrc="client.tmpl") +Authority = Node.create(3, { + "tag": "a", + "authority": 1, + "relay": 1, + "torrc": "authority.tmpl" +}) -HiddenService = Node(tag="h", hiddenservice=1, torrc="hidden-service.tmpl", hiddenservicetarget="127.0.0.1:8081") -DelayedHiddenService = Node(tag="h", hiddenservice=1, torrc="hidden-service.tmpl", delay=60*10, hiddenservicetarget="127.0.0.1:8082") +Relay = Node.create(5, { + "tag": "r", + "relay": 1, + "torrc": "intro.tmpl" +}) -NODES = Authority.getN(3) + Relay.getN(5) + Client.getN(4) + HiddenService.getN(1) + DelayedHiddenService.getN(1) +Client = Node.create(4, { + "tag": "c", + "torrc": "client.tmpl" +}) -ConfigureNodes(NODES) +initialNodes = Authority + Relay + Client + +HiddenService = Node( + tag="h", + hiddenservice=1, + torrc="hidden-service.tmpl", + hiddenservicetarget="127.0.0.1:8081" +) + +initialNodes.append(HiddenService) + +DelayedHiddenService = Node( + tag="h", + hiddenservice=1, + torrc="hidden-service.tmpl", + hiddenservicetarget="127.0.0.1:8082" +) + +def start(): + if not all([ n.getController().start() for n in initialNodes ]): + return False + + def log_listener(logevent): + print(logevent.message) + if "Successfully uploaded v2 rend descriptors" in logevent.message: + DelayedHiddenService.getController().start() + + HiddenService.getStemController().add_event_listener(log_listener, EventType.INFO) diff --git a/torrc_templates/common.i b/torrc_templates/common.i index ff1cf76..32fd0c6 100644 --- a/torrc_templates/common.i +++ b/torrc_templates/common.i @@ -10,5 +10,6 @@ Log info file ${dir}/info.log ProtocolWarnings 1 SafeLogging 0 ${authorities} +ControlPort ${controlport} IntroPointAcceptMutipleConnections 1 -- cgit v1.2.3