Another snapshot so we get a newer announced version number
[tor.git] / contrib / PathDemo.py
blobf3c991e0bf30194051226525d487401d50bde2c9
1 #!/usr/bin/python
3 import TorControl
4 import threading
5 import socket
6 import struct
7 import random
9 circuits = {}
10 streams = {}
12 def runControl(s):
13 pendingEvents = [] #XXX This tric. should become standard
14 TorControl._event_handler = pendingEvents.append
15 TorControl.set_events(s,
16 [TorControl.EVENT_TYPE.CIRCSTATUS,
17 TorControl.EVENT_TYPE.STREAMSTATUS])
18 TorControl.set_option(s,"__LeaveStreamsUnattached 1")
19 while 1:
20 e = pendingEvents[:]
21 del pendingEvents[:]
22 for ev in e:
23 handleEvent(s, ev)
24 _, tp, body = TorControl.receive_message(s)
25 if tp == TorControl.MSG_TYPE.EVENT:
26 handleEvent(s, body)
29 def parsePath(name):
30 assert name.endswith(".path")
31 items = name.split(".")
32 try:
33 n = int(items[-2])
34 except:
35 return None,None
36 path = items[-(2+n):-2]
37 host = items[:-(2+n)]
38 print path,host
39 return path,".".join(host)
41 def handleEvent(s,body):
42 event, args = TorControl.unpack_event(body)
43 if event == TorControl.EVENT_TYPE.STREAMSTATUS:
44 status, ident, target = args
45 print "Got stream event:",TorControl.STREAM_STATUS.nameOf[status],\
46 ident,target
47 if status in (TorControl.STREAM_STATUS.NEW_CONNECT,
48 TorControl.STREAM_STATUS.NEW_RESOLVE):
49 target,port=target.split(":")
50 if not target.endswith(".path"):
51 TorControl.attach_stream(s, ident, 0)
52 else:
53 path,host = parsePath(target)
54 #XXXX Don't launch so many circuits!
55 streams[ident] = path,host
56 circid = TorControl.extend_circuit(s, 0, path)
57 circuits[circid] = path
58 elif status == TorControl.STREAM_STATUS.DETACHED:
59 if not streams.has_key(ident):
60 TorControl.attach_stream(s, ident, 0)
61 else:
62 TorControl.close_stream(s, ident, 1)
63 elif event == TorControl.EVENT_TYPE.CIRCSTATUS:
64 status, ident, path = args
65 print "Got circuit event",TorControl.CIRC_STATUS.nameOf[status],\
66 ident,path
67 if not circuits.has_key(ident):
68 return
69 if status in (TorControl.CIRC_STATUS.CLOSED,
70 TorControl.CIRC_STATUS.FAILED):
71 ok = 0
72 elif status == TorControl.CIRC_STATUS.BUILT:
73 ok = 1
74 else:
75 return
77 ids = [ streamID for (streamID, (path,host)) in streams.items()
78 if path == circuits[ident] ]
80 for streamID in ids:
81 if ok:
82 _,host = streams[streamID]
83 TorControl.redirect_stream(s, streamID, host)
84 TorControl.attach_stream(s, streamID, ident)
85 #XXXX Don't do this twice.
86 else:
87 TorControl.close_stream(s, streamID, 1)
88 if not ok:
89 del circuits[ident]
92 def run():
93 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
94 s.connect(("127.0.0.1", 9051))
95 TorControl.authenticate(s)
96 runControl(s)
98 if __name__ == '__main__':
99 run()