-
Notifications
You must be signed in to change notification settings - Fork 7
/
fallback_directories.py
executable file
·96 lines (72 loc) · 3.51 KB
/
fallback_directories.py
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
#!/usr/bin/env python
# Copyright 2016-2020, Damian Johnson and The Tor Project
# See LICENSE for licensing information
"""
Report for how many of our fallback directories are unreachable.
"""
import time
import traceback
import stem.descriptor.remote
import stem.directory
import util
log = util.get_logger('fallback_directories')
NOTIFICATION_THRESHOLD = 25 # send notice if this percentage of fallbacks are unusable
EMAIL_SUBJECT = 'Fallback Directory Summary (%i/%i, %i%%)'
SYNOPSIS = '%i/%i (%i%%) fallback directories have become slow or unresponsive...'
downloader = stem.descriptor.remote.DescriptorDownloader(timeout = 30)
def main():
try:
fallback_directories = stem.directory.Fallback.from_remote().values()
log.info('Retrieved %i fallback directories' % len(fallback_directories))
except IOError as exc:
raise IOError("Unable to determine tor's fallback directories: %s" % exc)
issues = []
for relay in fallback_directories:
if not util.is_reachable(relay.address, relay.or_port):
log.info('%s ORPort unreachable' % relay.fingerprint)
issues.append('%s => ORPort is unreachable (%s:%i)' % (relay.fingerprint, relay.address, relay.or_port))
continue
if not util.is_reachable(relay.address, relay.dir_port):
log.info('%s DirPort unreachable' % relay.fingerprint)
issues.append('%s => DirPort is unreachable (%s:%i)' % (relay.fingerprint, relay.address, relay.dir_port))
continue
if relay.orport_v6 and not util.is_reachable(relay.orport_v6[0], relay.orport_v6[1]):
log.info('%s IPv6 ORPort unreachable' % relay.fingerprint)
issues.append('%s => IPv6 ORPort is unreachable (%s:%i)' % (relay.fingerprint, relay.orport_v6[0], relay.orport_v6[1]))
continue
try:
start = time.time()
downloader.get_consensus(endpoints = [(relay.address, relay.dir_port)]).run()
download_time = time.time() - start
log.info('%s download time was %0.1f seconds' % (relay.fingerprint, download_time))
except Exception as exc:
issues.append('%s => Unable to download from DirPort (%s)' % (relay.fingerprint, exc))
continue
if download_time > 15:
issues.append('%s => Downloading the consensus took %0.1f seconds' % (relay.fingerprint, download_time))
issue_percent = 100.0 * len(issues) / len(fallback_directories)
log.info('%i issues found (%i%%)' % (len(issues), issue_percent))
if issue_percent >= NOTIFICATION_THRESHOLD:
log.info('Sending notification')
synopsis = SYNOPSIS % (len(issues), len(fallback_directories), issue_percent)
subject = EMAIL_SUBJECT % (len(issues), len(fallback_directories), issue_percent)
email_body = synopsis + '\n\n' + '\n'.join([' * %s' % issue for issue in issues])
util.send(subject, body = email_body, to = TO_ADDRESSES)
# notification for #tor-bots
irc_lines = [synopsis]
for i, issue in enumerate(issues):
if i < 4:
irc_lines.append(issue)
else:
irc_lines.append('... and %i more' % (len(issues) - i))
break
irc_body = '\n'.join(['[fallback-directories] %s' % line for line in irc_lines])
util.send('Announce or', body = irc_body, to = ['[email protected]'])
if __name__ == '__main__':
try:
main()
except:
msg = "fallback_directories.py failed with:\n\n%s" % traceback.format_exc()
log.error(msg)
util.send("Script Error", body = msg, to = [util.ERROR_ADDRESS])