123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- #!/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()
|