mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-27 22:03:31 +01:00
Automate checking existing fallbacks
This commit is contained in:
parent
9e8671bb9a
commit
3fd58aa98d
@ -37,17 +37,13 @@ import dateutil.parser
|
|||||||
# bson_lazy provides bson
|
# bson_lazy provides bson
|
||||||
#from bson import json_util
|
#from bson import json_util
|
||||||
import copy
|
import copy
|
||||||
|
import re
|
||||||
|
|
||||||
from stem.descriptor import DocumentHandler
|
from stem.descriptor import DocumentHandler
|
||||||
from stem.descriptor.remote import get_consensus
|
from stem.descriptor.remote import get_consensus
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
# INFO tells you why each relay was included or excluded
|
|
||||||
# WARN tells you about potential misconfigurations and relay detail changes
|
|
||||||
logging.basicConfig(level=logging.WARNING)
|
|
||||||
logging.root.name = ''
|
logging.root.name = ''
|
||||||
# INFO tells you about each consensus download attempt
|
|
||||||
logging.getLogger('stem').setLevel(logging.WARNING)
|
|
||||||
|
|
||||||
HAVE_IPADDRESS = False
|
HAVE_IPADDRESS = False
|
||||||
try:
|
try:
|
||||||
@ -148,6 +144,7 @@ BLACKLIST_EXCLUDES_WHITELIST_ENTRIES = True
|
|||||||
|
|
||||||
WHITELIST_FILE_NAME = 'scripts/maint/fallback.whitelist'
|
WHITELIST_FILE_NAME = 'scripts/maint/fallback.whitelist'
|
||||||
BLACKLIST_FILE_NAME = 'scripts/maint/fallback.blacklist'
|
BLACKLIST_FILE_NAME = 'scripts/maint/fallback.blacklist'
|
||||||
|
FALLBACK_FILE_NAME = 'src/or/fallback_dirs.inc'
|
||||||
|
|
||||||
# The number of bytes we'll read from a filter file before giving up
|
# The number of bytes we'll read from a filter file before giving up
|
||||||
MAX_LIST_FILE_SIZE = 1024 * 1024
|
MAX_LIST_FILE_SIZE = 1024 * 1024
|
||||||
@ -368,6 +365,15 @@ def read_from_file(file_name, max_len):
|
|||||||
)
|
)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def parse_fallback_file(file_name):
|
||||||
|
file_data = read_from_file(file_name, MAX_LIST_FILE_SIZE)
|
||||||
|
file_data = cleanse_unprintable(file_data)
|
||||||
|
file_data = remove_bad_chars(file_data, '\n"\0')
|
||||||
|
file_data = re.sub('/\*.*?\*/', '', file_data)
|
||||||
|
file_data = file_data.replace(',', '\n')
|
||||||
|
file_data = file_data.replace(' weight=10', '')
|
||||||
|
return file_data
|
||||||
|
|
||||||
def load_possibly_compressed_response_json(response):
|
def load_possibly_compressed_response_json(response):
|
||||||
if response.info().get('Content-Encoding') == 'gzip':
|
if response.info().get('Content-Encoding') == 'gzip':
|
||||||
buf = StringIO.StringIO( response.read() )
|
buf = StringIO.StringIO( response.read() )
|
||||||
@ -1431,7 +1437,7 @@ class CandidateList(dict):
|
|||||||
self.fallbacks.sort(key=lambda f: f._data[data_field])
|
self.fallbacks.sort(key=lambda f: f._data[data_field])
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def load_relaylist(file_name):
|
def load_relaylist(file_obj):
|
||||||
""" Read each line in the file, and parse it like a FallbackDir line:
|
""" Read each line in the file, and parse it like a FallbackDir line:
|
||||||
an IPv4 address and optional port:
|
an IPv4 address and optional port:
|
||||||
<IPv4 address>:<port>
|
<IPv4 address>:<port>
|
||||||
@ -1446,8 +1452,9 @@ class CandidateList(dict):
|
|||||||
(of string -> string key/value pairs),
|
(of string -> string key/value pairs),
|
||||||
and these dictionaries are placed in an array.
|
and these dictionaries are placed in an array.
|
||||||
comments start with # and are ignored """
|
comments start with # and are ignored """
|
||||||
|
file_data = file_obj['data']
|
||||||
|
file_name = file_obj['name']
|
||||||
relaylist = []
|
relaylist = []
|
||||||
file_data = read_from_file(file_name, MAX_LIST_FILE_SIZE)
|
|
||||||
if file_data is None:
|
if file_data is None:
|
||||||
return relaylist
|
return relaylist
|
||||||
for line in file_data.split('\n'):
|
for line in file_data.split('\n'):
|
||||||
@ -1488,12 +1495,12 @@ class CandidateList(dict):
|
|||||||
return relaylist
|
return relaylist
|
||||||
|
|
||||||
# apply the fallback whitelist and blacklist
|
# apply the fallback whitelist and blacklist
|
||||||
def apply_filter_lists(self):
|
def apply_filter_lists(self, whitelist_obj, blacklist_obj):
|
||||||
excluded_count = 0
|
excluded_count = 0
|
||||||
logging.debug('Applying whitelist and blacklist.')
|
logging.debug('Applying whitelist and blacklist.')
|
||||||
# parse the whitelist and blacklist
|
# parse the whitelist and blacklist
|
||||||
whitelist = self.load_relaylist(WHITELIST_FILE_NAME)
|
whitelist = self.load_relaylist(whitelist_obj)
|
||||||
blacklist = self.load_relaylist(BLACKLIST_FILE_NAME)
|
blacklist = self.load_relaylist(blacklist_obj)
|
||||||
filtered_fallbacks = []
|
filtered_fallbacks = []
|
||||||
for f in self.fallbacks:
|
for f in self.fallbacks:
|
||||||
in_whitelist = f.is_in_whitelist(whitelist)
|
in_whitelist = f.is_in_whitelist(whitelist)
|
||||||
@ -2064,9 +2071,38 @@ class CandidateList(dict):
|
|||||||
s += 'or setting INCLUDE_UNLISTED_ENTRIES = True.'
|
s += 'or setting INCLUDE_UNLISTED_ENTRIES = True.'
|
||||||
return s
|
return s
|
||||||
|
|
||||||
## Main Function
|
def process_existing():
|
||||||
|
logging.basicConfig(level=logging.INFO)
|
||||||
|
logging.getLogger('stem').setLevel(logging.INFO)
|
||||||
|
whitelist = {'data': parse_fallback_file(FALLBACK_FILE_NAME),
|
||||||
|
'name': FALLBACK_FILE_NAME}
|
||||||
|
blacklist = {'data': read_from_file(BLACKLIST_FILE_NAME, MAX_LIST_FILE_SIZE),
|
||||||
|
'name': BLACKLIST_FILE_NAME}
|
||||||
|
list_fallbacks(whitelist, blacklist)
|
||||||
|
|
||||||
def list_fallbacks():
|
def process_default():
|
||||||
|
logging.basicConfig(level=logging.WARNING)
|
||||||
|
logging.getLogger('stem').setLevel(logging.WARNING)
|
||||||
|
whitelist = {'data': read_from_file(WHITELIST_FILE_NAME, MAX_LIST_FILE_SIZE),
|
||||||
|
'name': WHITELIST_FILE_NAME}
|
||||||
|
blacklist = {'data': read_from_file(BLACKLIST_FILE_NAME, MAX_LIST_FILE_SIZE),
|
||||||
|
'name': BLACKLIST_FILE_NAME}
|
||||||
|
list_fallbacks(whitelist, blacklist)
|
||||||
|
|
||||||
|
## Main Function
|
||||||
|
def main():
|
||||||
|
if get_command() == 'check_existing':
|
||||||
|
process_existing()
|
||||||
|
else:
|
||||||
|
process_default()
|
||||||
|
|
||||||
|
def get_command():
|
||||||
|
if len(sys.argv) == 2:
|
||||||
|
return sys.argv[1]
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
def list_fallbacks(whitelist, blacklist):
|
||||||
""" Fetches required onionoo documents and evaluates the
|
""" Fetches required onionoo documents and evaluates the
|
||||||
fallback directory criteria for each of the relays """
|
fallback directory criteria for each of the relays """
|
||||||
|
|
||||||
@ -2099,7 +2135,7 @@ def list_fallbacks():
|
|||||||
# warning that the details have changed from those in the whitelist.
|
# warning that the details have changed from those in the whitelist.
|
||||||
# instead, there will be an info-level log during the eligibility check.
|
# instead, there will be an info-level log during the eligibility check.
|
||||||
initial_count = len(candidates.fallbacks)
|
initial_count = len(candidates.fallbacks)
|
||||||
excluded_count = candidates.apply_filter_lists()
|
excluded_count = candidates.apply_filter_lists(whitelist, blacklist)
|
||||||
print candidates.summarise_filters(initial_count, excluded_count)
|
print candidates.summarise_filters(initial_count, excluded_count)
|
||||||
eligible_count = len(candidates.fallbacks)
|
eligible_count = len(candidates.fallbacks)
|
||||||
|
|
||||||
@ -2170,4 +2206,4 @@ def list_fallbacks():
|
|||||||
print x.fallbackdir_line(candidates.fallbacks, prefilter_fallbacks)
|
print x.fallbackdir_line(candidates.fallbacks, prefilter_fallbacks)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
list_fallbacks()
|
main()
|
||||||
|
Loading…
Reference in New Issue
Block a user