commit a91384c90639c71dad3486813f85b9bbf79bf2c4
Author: Tom Ritter <t...@ritter.vg>
Date:   Fri Apr 20 10:30:59 2018 -0500

    Add Clock Skew. Closes #25767
---
 data/consensus.cfg |  3 +++
 utility.py         | 28 +++++++++++++++++++++++++++
 website.py         | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 write_website.py   |  5 ++++-
 4 files changed, 90 insertions(+), 2 deletions(-)

diff --git a/data/consensus.cfg b/data/consensus.cfg
index 02f39b1..e4af54a 100644
--- a/data/consensus.cfg
+++ b/data/consensus.cfg
@@ -9,6 +9,9 @@ graph_logical_min 125
 # do not show values values greater than this on the graph. You can leave this 
high
 graph_logical_max 25000
 
+# we highlight clockskew that is 20 seconds or greater
+clockskew_threshold 20
+
 # recognized tor consensus parameters
 
 known_params bwweightscale
diff --git a/utility.py b/utility.py
old mode 100644
new mode 100755
index 6b2cfae..d4f9a68
--- a/utility.py
+++ b/utility.py
@@ -1,4 +1,7 @@
+#!/usr/bin/env python
+
 import time
+import urllib
 import datetime
 
 import stem.descriptor
@@ -81,6 +84,26 @@ def _get_documents(label, resource):
 
        return documents, issues, runtimes
 
+def get_clockskew():
+       clockskew = {}
+       for (nickname, authority) in get_dirauths().items():
+               authority_address = "http://"; + str(authority.address) + ":" + 
str(authority.dir_port)
+               try:
+                       startTimeStamp = datetime.datetime.utcnow()
+                       startTime = time.time()
+                       f = urllib.urlopen(authority_address)
+                       for h in f.info().headers:
+                               if h.upper().startswith('DATE:'):
+                                       clockskew[nickname] = 
datetime.datetime.strptime(h[6:].strip(), '%a, %d %b %Y %H:%M:%S %Z')
+                       processing = time.time() - startTime
+                       if processing > 5:
+                               clockskew[nickname] -= 
datetime.timedelta(seconds=(processing / 2))
+                       clockskew[nickname] -= startTimeStamp
+                       clockskew[nickname] = 
clockskew[nickname].total_seconds()
+               except:
+                       continue
+       return clockskew
+
 def unix_time(dt):
     return (dt - datetime.datetime.utcfromtimestamp(0)).total_seconds() * 
1000.0
 
@@ -98,3 +121,8 @@ class FileMock():
                pass
        def write(self, str):
                pass
+
+if __name__ == "__main__":
+       skew = get_clockskew()
+       for c in skew:
+               print c, skew[c]
\ No newline at end of file
diff --git a/website.py b/website.py
index 02fbdce..d3fa842 100755
--- a/website.py
+++ b/website.py
@@ -24,6 +24,7 @@ class WebsiteWriter:
        consensus = None
        votes = None
        fallback_dirs = None
+       clockskew = None
        known_authorities = []
        bandwidth_authorities = []
        consensus_expiry = datetime.timedelta(hours=3)
@@ -51,6 +52,7 @@ class WebsiteWriter:
                self._write_recommended_versions()
                self._write_consensus_parameters()
                self._write_authority_keys()
+               self._write_authority_clocks()
                self._write_shared_random()
                self._write_protocols()
                self._write_bandwidth_weights()
@@ -82,6 +84,8 @@ class WebsiteWriter:
                self.known_params = config['known_params']
        def set_fallback_dirs(self, fallback_dirs):
                self.fallback_dirs = fallback_dirs
+       def set_clockskew(self, clockskew):
+               self.clockskew = clockskew
        def get_consensus_time(self):
                return self.consensus.valid_after
        def all_votes_present(self):
@@ -691,6 +695,55 @@ class WebsiteWriter:
                        + "</p>\n")
 
        
#-----------------------------------------------------------------------------------------
+       def _write_authority_clocks(self):
+               """
+               Write authority clock skew
+               """
+               self.site.write("<br>\n\n\n"
+               + " <!-- 
================================================================= -->"
+               + "<a name=\"authorityclocks\">\n"
+               + "<h3><a href=\"#authorityclocks\" class=\"anchor\">"
+               + "Authority Clock Skew</a></h3>\n"
+               + "<br>\n"
+               + "<table border=\"0\" cellpadding=\"4\" cellspacing=\"0\" 
summary=\"\">\n"
+               + "  <colgroup>\n"
+               + "    <col width=\"160\">\n"
+               + "    <col width=\"640\">\n"
+               + "  </colgroup>\n"
+               + "  <tr>\n"
+               + "    <th>Name</th>"
+               + "    <th>Approximate Clock Skew</th>"
+               + "  </tr>\n")
+
+               if not self.clockskew:
+                       self.site.write("  <tr><td>(No clock skew 
data.)</td><td></td></tr>\n")
+               else:
+                       for dirauth_nickname in self.known_authorities:
+                               if dirauth_nickname in self.clockskew:
+                                       clock = self.clockskew[dirauth_nickname]
+
+                                       if clock > 
self.config['clockskew_threshold']:
+                                               self.site.write("  <tr>\n"
+                                               + "    <td class=\"oiv\">" + 
dirauth_nickname + "</td>\n"
+                                               + "    <td class=\"oiv\">"
+                                               + str(clock) + " seconds</td>\n 
 </tr>\n")
+                                       else:
+                                               self.site.write("  <tr>\n"
+                                               + "    <td>" + dirauth_nickname 
+ "</td>\n"
+                                               + "    <td>"
+                                               + str(clock) + " seconds</td>\n 
 </tr>\n")
+                               else:
+                                       self.site.write("  <tr>\n"
+                                       + "    <td>" + dirauth_nickname + 
"</td>\n"
+                                       + "    <td><span class=\"oiv\">Could 
not query authority<span></td>\n"
+                                       + "  </tr>\n")
+
+                       self.site.write("</table>\n"
+                       + "<br>\n"
+                       + "<p><i>Times are roughly accurate, anything below a 
couple seconds should be fine. Please use this table as a guide rather than an 
authoritative source.</i>"
+                       + "</p>\n")
+
+       
#-----------------------------------------------------------------------------------------
        def sharedRandomToStr(self, sr):
                s = "["
                s += "V:" + str(sr.version) + " "
@@ -1632,7 +1685,8 @@ if __name__ == '__main__':
                                     'known_params': [],
                                     'ignore_fallback_authorities': False,
                                     'graph_logical_min': 125,
-                                    'graph_logical_max': 25000
+                                    'graph_logical_max': 25000,
+                                    'clockskew_threshold': 0,
                                     })
        config = stem.util.conf.get_config("consensus")
        config.load(os.path.join(os.path.dirname(__file__), 'data', 
'consensus.cfg'))
diff --git a/write_website.py b/write_website.py
index d8d3e3f..f79e2c3 100755
--- a/write_website.py
+++ b/write_website.py
@@ -48,7 +48,8 @@ CONFIG = stem.util.conf.config_dict('consensus', {
        'known_params': [],
        'ignore_fallback_authorities' : False,
        'graph_logical_min' : 125,
-       'graph_logical_max' : 25000
+       'graph_logical_max' : 25000,
+       'clockskew_threshold': 0,
 })
 
 def main():
@@ -58,6 +59,7 @@ def main():
 
        consensuses, consensus_fetching_issues, consensus_fetching_runtimes = 
get_consensuses()
        votes, vote_fetching_issues, vote_fetching_runtimes = get_votes()
+       clockskew = get_clockskew()
 
        # updates the download statistics file
        f = open(os.path.join(os.path.dirname(__file__), 'out', 
'download-stats.csv'), 'a')
@@ -299,6 +301,7 @@ def main():
        w.set_consensuses(consensuses)
        w.set_votes(votes)
        w.set_fallback_dirs(fallback_dirs)
+       w.set_clockskew(clockskew)
        w.write_website(os.path.join(os.path.dirname(__file__), 'out', 
'consensus-health.html'), \
                True, os.path.join(os.path.dirname(__file__), 'out', 
'relay-indexes.txt'))
        w.write_website(os.path.join(os.path.dirname(__file__), 'out', 
'index.html'), False)

_______________________________________________
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits

Reply via email to