Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: master
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

executable file 131 lines (114 sloc) 3.982 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
#!/usr/bin/env python
import socket, sys, time, subprocess, threading, signal, fcntl, os
import TorCtl.TorCtl

# TODO: track things on the hidden service side as well

TORLOC = '/usr/sbin/tor'
LOGFILE = 'torperf2.log'
HIDDEN = 'http://pevf7ega6sg6elzr.onion:9081/'
PUBLIC = 'http://torperf.tor2web.org:9081/'
HOST = '127.0.0.1'
PORT = 10951

shared = dict(
  torprocess = None,
  torlock = threading.Lock()
)

TORRC = """\
SocksListenAddress %s
SocksPort %d
ControlPort %d
CookieAuthentication 1
RunAsDaemon 0
Log info file logfile
DataDir .tor
""" % (HOST, PORT, PORT+1)

def nukedir(dirname):
    if os.path.exists(dirname):
        for fn in os.listdir(dirname):
            os.unlink(dirname + os.path.sep + fn)
        os.rmdir(dirname)

def start_tor():
    global TORPROCESS
    file('torrc', 'w').write(TORRC)
    shared['torprocess'] = subprocess.Popen([TORLOC, '-f', 'torrc'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    shared['torlock'].acquire()

def end_tor(signum=None, frame=None):
    if shared['torprocess']: shared['torprocess'].kill()
signal.signal(signal.SIGTERM, end_tor)

triggers = dict(
    GOT_TOR = 'Bootstrapped 100%: Done.',
    GOT_REQUEST = 'Got a hidden service request for ID',
    START_FETCH = 'Sending fetch request for v2 descriptor',
    END_FETCH = 'Successfully fetched v2 rendezvous descriptor.',
    START_RENDCIRC = 'Sending an ESTABLISH_RENDEZVOUS cell',
    GOT_RENDCIRC = 'Got rendezvous ack. This circuit is now ready for rendezvous.',
    GOT_INTROCIRC = 'introcirc is open',
    # SEND_INTRODUCE1
    GOT_RENDEZVOUS2 = 'Got RENDEZVOUS2 cell from hidden service'
)

class EventHandler(TorCtl.TorCtl.DebugEventHandler):
    def __init__(self, host, port, fh):
        self.host = host
        self.port = port
        self.fh = fh
        self.last_event = None
        TorCtl.TorCtl.DebugEventHandler.__init__(self)
    
    def declare(self, declaration):
        self.fh.write(declaration+'\n')
        self.fh.flush()
    
    def log(self, event):
        now = time.time()
        self.fh.write('%f %s ' % (now, event))
        if self.last_event:
            self.fh.write('(%.2f seconds)' % (now-self.last_event))
        self.fh.write('\n')
        self.fh.flush()
        self.last_event = now
    
    def msg_event(self, log_event):
        for k in triggers:
            if triggers[k] in log_event.msg:
                self.log(k)
                if k == 'GOT_TOR': shared['torlock'].release()
                break

def grab_page(h, url, bucket):
    h.last_event = None
    h.declare('GET %s %s' % (url, bucket))
    h.log('START_REQUEST')
    p = subprocess.Popen(['curl', '-sN', '--socks4a', h.host + ':%d' % (h.port-1),
     url], bufsize=0, stdout=subprocess.PIPE)
    b = ''
    while not b: b = p.stdout.read(1)
    h.log('GOT_FIRST_BYTE')
    while b: b = p.stdout.read()
    h.log('GOT_LAST_BYTE')
    h.log('END_REQUEST')

def main(host, port, fn, fh):
    handler = EventHandler(host, port+1, fh)
    handler.log('START_TOR')
    start_tor()
    time.sleep(2)
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((host, port+1))
    c = TorCtl.TorCtl.Connection(s)
    c.set_event_handler(handler)
    c.authenticate()
    EVT = TorCtl.TorCtl.EVENT_TYPE
    c.set_events([EVT.INFO, EVT.NOTICE])
    shared['torlock'].acquire()

    grab_page(handler, HIDDEN + fn, 'hidden|%s|cold'%fn)
    if fn == '50kbfile':
        grab_page(handler, HIDDEN + fn, 'hidden|%s|warm'%fn)
    grab_page(handler, PUBLIC + fn, 'public|%s|cold'%fn)
    if fn == '50kbfile':
        grab_page(handler, HIDDEN + fn, 'hidden|%s|lukewarm'%fn)
    handler.log('END_TOR')

if __name__ == "__main__":
    fh = None
    try:
        os.chdir(os.path.sep.join(sys.argv[0].split(os.path.sep)[:-1]))
        nukedir('.tor')
        fh = file(LOGFILE, 'a')
        fcntl.lockf(fh, fcntl.LOCK_EX)
        main(HOST, PORT, sys.argv[1], fh)
    finally:
        end_tor()
        if fh: fcntl.lockf(fh, fcntl.LOCK_UN)
Something went wrong with that request. Please try again.