aboutsummaryrefslogtreecommitdiff
path: root/lib/chutney/TorNet.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/chutney/TorNet.py')
-rw-r--r--lib/chutney/TorNet.py159
1 files changed, 74 insertions, 85 deletions
diff --git a/lib/chutney/TorNet.py b/lib/chutney/TorNet.py
index 334615f..82a5fc0 100644
--- a/lib/chutney/TorNet.py
+++ b/lib/chutney/TorNet.py
@@ -35,9 +35,40 @@ import Queue
import chutney.Templating
import chutney.Traffic
+import chutney.Testing
import logging
+DEFAULTS = {
+ 'authority' : False,
+ 'bridgeauthority' : False,
+ 'hasbridgeauth' : False,
+ 'relay' : False,
+ 'bridge' : False,
+ 'hiddenservice' : False,
+ 'hiddenserviceport' : 80,
+ 'hiddenservicetarget' : '127.0.0.1',
+ 'connlimit' : 60,
+ 'net_base_dir' : 'net',
+ 'tor' : 'tor',
+ 'auth_cert_lifetime' : 12,
+ 'ip' : '127.0.0.1',
+ 'ipv6_addr' : None,
+ 'dirserver_flags' : 'no-v2',
+ 'chutney_dir' : '.',
+ 'torrc_fname' : '${dir}/torrc',
+ 'orport_base' : 5000,
+ 'dirport_base' : 7000,
+ 'controlport_base' : 8000,
+ 'socksport_base' : 9000,
+ 'authorities' : "AlternateDirAuthority bleargh bad torrc file!",
+ 'bridges' : "Bridge bleargh bad torrc file!",
+ 'core' : True,
+ 'delay' : 0,
+}
+
+_BASE_ENVIRON = chutney.Templating.Environ(**DEFAULTS)
+
def mkdir_p(d, mode=0777):
"""Create directory 'd' and all of its parents as needed. Unlike
os.makedirs, does not give an error if d already exists.
@@ -49,9 +80,6 @@ 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.
@@ -74,7 +102,6 @@ class Node(object):
self._builder = None
self._controller = None
self._stemcontroller = None
- nodelist.append(self)
@staticmethod
def create(number, kwargs):
@@ -426,7 +453,6 @@ class LocalNodeBuilder(NodeBuilder):
class LocalNodeController(NodeController):
def __init__(self, env):
NodeController.__init__(self, env)
- self._env = env
def getPid(self):
"""Assuming that this node has its pidfile in ${dir}/pid, return
@@ -536,35 +562,6 @@ class LocalNodeController(NodeController):
-
-DEFAULTS = {
- 'authority' : False,
- 'bridgeauthority' : False,
- 'hasbridgeauth' : False,
- 'relay' : False,
- 'bridge' : False,
- 'hiddenservice' : False,
- 'hiddenserviceport' : 80,
- 'hiddenservicetarget' : '127.0.0.1',
- 'connlimit' : 60,
- 'net_base_dir' : 'net',
- 'tor' : 'tor',
- 'auth_cert_lifetime' : 12,
- 'ip' : '127.0.0.1',
- 'ipv6_addr' : None,
- 'dirserver_flags' : 'no-v2',
- 'chutney_dir' : '.',
- 'torrc_fname' : '${dir}/torrc',
- 'orport_base' : 5000,
- 'dirport_base' : 7000,
- 'controlport_base' : 8000,
- 'socksport_base' : 9000,
- 'authorities' : "AlternateDirAuthority bleargh bad torrc file!",
- 'bridges' : "Bridge bleargh bad torrc file!",
- 'core' : True,
- 'delay' : 0,
-}
-
class TorEnviron(chutney.Templating.Environ):
"""Subclass of chutney.Templating.Environ to implement commonly-used
substitutions.
@@ -603,9 +600,12 @@ class TorEnviron(chutney.Templating.Environ):
return my['dirport_base']+my['nodenum']
def _get_dir(self, my):
- return os.path.abspath(os.path.join(my['net_base_dir'],
+ nodenum = my['nodenum']
+ net_base_dir = my['net_base_dir']
+ tag = my['tag']
+ return os.path.abspath(os.path.join(net_base_dir,
"nodes",
- "%03d%s"%(my['nodenum'], my['tag'])))
+ "%03d%s"%(nodenum, tag)))
def _get_nick(self, my):
return "test%03d%s"%(my['nodenum'], my['tag'])
@@ -620,28 +620,43 @@ class TorEnviron(chutney.Templating.Environ):
return [ os.path.join(my['chutney_dir'], 'torrc_templates') ]
-class Network(object):
+class Network(list):
"""A network of Tor nodes, plus functions to manipulate them
"""
- def __init__(self,defaultEnviron):
- self._nodes = []
+ def __init__(self, defaultEnviron=_BASE_ENVIRON):
self._dfltEnv = defaultEnviron
self._nextnodenum = 0
+ def get(self, tag):
+ nodes = []
+
+ for node in self:
+ if node._env["tag"] == tag:
+ nodes.append(node)
+
+ return nodes
+
+ def add(self, nodes):
+ if nodes is Node:
+ self._addNode(nodes)
+ else:
+ for node in nodes:
+ self._addNode(node)
+
def _addNode(self, n):
n.setNodenum(self._nextnodenum)
self._nextnodenum += 1
- self._nodes.append(n)
+ self.append(n)
def _checkConfig(self):
- for n in self._nodes:
+ for n in self:
n.getBuilder().checkConfig(self)
def configure(self):
network = self
altauthlines = []
bridgelines = []
- builders = [ n.getBuilder() for n in self._nodes ]
+ builders = [ n.getBuilder() for n in self ]
self._checkConfig()
@@ -664,10 +679,10 @@ class Network(object):
b.postConfig(network)
def status(self):
- statuses = [ n.getController().check() for n in self._nodes]
+ statuses = [ n.getController().check() for n in self]
n_ok = len([x for x in statuses if x])
- print "%d/%d nodes are running"%(n_ok,len(self._nodes))
- if n_ok != len(self._nodes):
+ print "%d/%d nodes are running"%(n_ok,len(self))
+ if n_ok != len(self):
return False
return True
@@ -682,15 +697,15 @@ class Network(object):
def hup(self):
print "Sending SIGHUP to nodes"
- return all([n.getController().hup() for n in self._nodes])
+ return all([n.getController().hup() for n in self])
def stop(self):
- for n in self._nodes:
+ for n in self:
if n._stemcontroller:
n._stemcontroller.close()
- controllers = [ n.getController() for n in self._nodes ]
+ controllers = [ n.getController() for n in self ]
for sig, desc in [(signal.SIGINT, "SIGINT"),
(signal.SIGINT, "another SIGINT"),
(signal.SIGKILL, "SIGKILL")]:
@@ -728,7 +743,7 @@ class Network(object):
tmpdata = randfp.read(DATALEN)
bind_to = ('127.0.0.1', LISTEN_PORT)
tt = chutney.Traffic.TrafficTester(bind_to, tmpdata, TIMEOUT)
- for op in filter(lambda n: n._env['tag'] == 'c', self._nodes):
+ for op in filter(lambda n: n._env['tag'] == 'c', self):
tt.add(chutney.Traffic.Source(tt, bind_to, tmpdata,
('localhost', int(op._env['socksport']))))
return tt.run()
@@ -739,12 +754,7 @@ def usage(network):
" ".join(x for x in dir(network) if not x.startswith("_")))])
def runConfigFile(verb, f):
- def stop(exitcode=0):
- _THE_NETWORK.stop()
- print("Network stoped, exiting")
- sys.exit(exitcode)
-
- _GLOBALS = dict(_BASE_ENVIRON = _BASE_ENVIRON,
+ _GLOBALS = dict(_BASE_ENVIRON=_BASE_ENVIRON,
Node=Node,
EventType=stem.control.EventType,
time=time,
@@ -753,16 +763,14 @@ def runConfigFile(verb, f):
random=random,
threading=threading,
logging=logging,
- stop=stop,
- _THE_NETWORK=_THE_NETWORK)
+ testing=chutney.Testing)
exec f in _GLOBALS
- network = _GLOBALS['_THE_NETWORK']
+ network = _GLOBALS['network']
- for n in nodelist:
- network._addNode(n)
- if n._env['bridgeauthority']:
- network._dfltEnv['hasbridgeauth'] = True
+ if len(network) is 0:
+ print("ERROR: No nodes")
+ return False;
network._start = _GLOBALS['start']
@@ -773,26 +781,7 @@ def runConfigFile(verb, f):
return getattr(network, verb)()
-def logold(string, show=True):
- output = time.strftime("%b %d %H:%M:%S.000") + " " + str(string)
-
- f = open('log.log', 'w')
- f.write(output)
-
- if show:
- print(output)
-
-def signal_handler(signal, frame):
- _THE_NETWORK.stop()
- print("Network stoped, exiting")
- sys.exit(0)
-
def main():
- global _BASE_ENVIRON
- global _THE_NETWORK
- _BASE_ENVIRON = chutney.Templating.Environ(**DEFAULTS)
- _THE_NETWORK = Network(_BASE_ENVIRON)
-
stem.util.log.get_logger().setLevel(logging.WARN)
logger = logging.getLogger()
@@ -813,7 +802,7 @@ def main():
logger.addHandler(handler)
if len(sys.argv) < 3:
- print usage(_THE_NETWORK)
+ print usage(network)
print "Error: Not enough arguments given."
sys.exit(1)
@@ -823,9 +812,9 @@ def main():
if result is False:
sys.exit(-1)
- if sys.argv[1] == "start":
- signal.signal(signal.SIGINT, signal_handler)
- signal.pause()
+ #if sys.argv[1] == "start":
+ # signal.signal(signal.SIGINT, signal_handler)
+ # signal.pause()
return 0