diff --git a/contrib/PathDemo.py b/contrib/PathDemo.py new file mode 100644 index 0000000000..f3c991e0bf --- /dev/null +++ b/contrib/PathDemo.py @@ -0,0 +1,99 @@ +#!/usr/bin/python + +import TorControl +import threading +import socket +import struct +import random + +circuits = {} +streams = {} + +def runControl(s): + pendingEvents = [] #XXX This tric. should become standard + TorControl._event_handler = pendingEvents.append + TorControl.set_events(s, + [TorControl.EVENT_TYPE.CIRCSTATUS, + TorControl.EVENT_TYPE.STREAMSTATUS]) + TorControl.set_option(s,"__LeaveStreamsUnattached 1") + while 1: + e = pendingEvents[:] + del pendingEvents[:] + for ev in e: + handleEvent(s, ev) + _, tp, body = TorControl.receive_message(s) + if tp == TorControl.MSG_TYPE.EVENT: + handleEvent(s, body) + + +def parsePath(name): + assert name.endswith(".path") + items = name.split(".") + try: + n = int(items[-2]) + except: + return None,None + path = items[-(2+n):-2] + host = items[:-(2+n)] + print path,host + return path,".".join(host) + +def handleEvent(s,body): + event, args = TorControl.unpack_event(body) + if event == TorControl.EVENT_TYPE.STREAMSTATUS: + status, ident, target = args + print "Got stream event:",TorControl.STREAM_STATUS.nameOf[status],\ + ident,target + if status in (TorControl.STREAM_STATUS.NEW_CONNECT, + TorControl.STREAM_STATUS.NEW_RESOLVE): + target,port=target.split(":") + if not target.endswith(".path"): + TorControl.attach_stream(s, ident, 0) + else: + path,host = parsePath(target) + #XXXX Don't launch so many circuits! + streams[ident] = path,host + circid = TorControl.extend_circuit(s, 0, path) + circuits[circid] = path + elif status == TorControl.STREAM_STATUS.DETACHED: + if not streams.has_key(ident): + TorControl.attach_stream(s, ident, 0) + else: + TorControl.close_stream(s, ident, 1) + elif event == TorControl.EVENT_TYPE.CIRCSTATUS: + status, ident, path = args + print "Got circuit event",TorControl.CIRC_STATUS.nameOf[status],\ + ident,path + if not circuits.has_key(ident): + return + if status in (TorControl.CIRC_STATUS.CLOSED, + TorControl.CIRC_STATUS.FAILED): + ok = 0 + elif status == TorControl.CIRC_STATUS.BUILT: + ok = 1 + else: + return + + ids = [ streamID for (streamID, (path,host)) in streams.items() + if path == circuits[ident] ] + + for streamID in ids: + if ok: + _,host = streams[streamID] + TorControl.redirect_stream(s, streamID, host) + TorControl.attach_stream(s, streamID, ident) + #XXXX Don't do this twice. + else: + TorControl.close_stream(s, streamID, 1) + if not ok: + del circuits[ident] + + +def run(): + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + s.connect(("127.0.0.1", 9051)) + TorControl.authenticate(s) + runControl(s) + +if __name__ == '__main__': + run() diff --git a/contrib/TorControl.py b/contrib/TorControl.py index 815ceecc83..b7ccbfc5e7 100755 --- a/contrib/TorControl.py +++ b/contrib/TorControl.py @@ -314,6 +314,16 @@ def attach_stream(s, streamid, circid): send_message(s,MSG_TYPE.ATTACHSTREAM,msg) tp,body = receive_reply(s,[MSG_TYPE.DONE]) +def close_stream(s, streamid, reason=0, flags=0): + msg = struct.pack("!LBB",streamid,reason,flags) + send_message(s,MSG_TYPE.CLOSESTREAM,msg) + tp,body = receive_reply(s,[MSG_TYPE.DONE]) + +def close_circuit(s, circid, flags=0): + msg = struct.pack("!LB",circid,flags) + send_message(s,MSG_TYPE.CLOSECIRCUIT,msg) + tp,body = receive_reply(s,[MSG_TYPE.DONE]) + def _unterminate(s): if s[-1] == '\0': return s[:-1] diff --git a/contrib/package_nsis.sh b/contrib/package_nsis.sh index 479dd43381..fcc62fbbd1 100644 --- a/contrib/package_nsis.sh +++ b/contrib/package_nsis.sh @@ -28,7 +28,7 @@ clean_newlines() { } clean_localstatedir() { - perl -pe 'BEGIN {undef $/;} s/^\n$/\r\n/mg; s/([^\r])\n$/\1\r\n/mg; s{\@LOCALSTATEDIR\@/(lib|log)/tor/}{\\Application Data\\Tor\\}' $1 >$2 + perl -pe 'BEGIN {undef $/;} s/^\n$/\r\n/mg; s/([^\r])\n$/\1\r\n/mg; s{\@LOCALSTATEDIR\@/(lib|log)/tor/}{C:\\Documents and Settings\\Application Data\\Tor\\}' $1 >$2 } for fn in CLIENTS tor-spec.txt HACKING rend-spec.txt control-spec.txt \