PathDemo.py 3.1 KB

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