[tor-commits] [nyx/master] Fetch address at a fixed rate

atagar at torproject.org atagar at torproject.org
Tue Oct 17 18:51:21 UTC 2017


commit 41079dcefbf4dec47967dcbcc0ab5bf135dc16ce
Author: Damian Johnson <atagar at torproject.org>
Date:   Wed Oct 11 11:07:05 2017 -0700

    Fetch address at a fixed rate
    
    Stem transparently caches immutable information but our address is a rather
    strange critter. It can change but hardly ever does, and is used quite a bit.
    
    Nyx forced Stem to treat this as being cachable but when our address is
    unavailable this still accounted for numerous requests. Instead fetching
    the our address at a fixed rate of once a minute.
    
    This provides two benefits...
    
    * Avoid pointless requests while there's no network available.
    * This way we'll evenually update our address if it changes while running.
---
 nyx/__init__.py         | 24 +++++++++++++++++++++---
 nyx/panel/connection.py |  5 ++---
 nyx/panel/header.py     |  4 ++--
 nyx/tracker.py          |  7 +++----
 4 files changed, 28 insertions(+), 12 deletions(-)

diff --git a/nyx/__init__.py b/nyx/__init__.py
index c326cd3..89a24c7 100644
--- a/nyx/__init__.py
+++ b/nyx/__init__.py
@@ -9,6 +9,7 @@ Tor curses monitoring application.
   nyx_interface - nyx interface singleton
   tor_controller - tor connection singleton
   cache - provides our application cache
+  our_address - provides our ip address
 
   show_message - shows a message to the user
   input_prompt - prompts the user for text input
@@ -104,9 +105,9 @@ CACHE = None
 CHROOT = None
 BASE_DIR = os.path.sep.join(__file__.split(os.path.sep)[:-1])
 
-# technically can change but we use this query a *lot* so needs to be cached
-
-stem.control.CACHEABLE_GETINFO_PARAMS = list(stem.control.CACHEABLE_GETINFO_PARAMS) + ['address']
+CACHED_ADDRESS = None
+ADDRESS_FETCHED = None
+ADDRESS_FETCH_RATE = 60
 
 # disable trace level messages about cache hits
 
@@ -250,6 +251,23 @@ def cache():
   return CACHE
 
 
+def our_address(default = None):
+  """
+  Provides our ip address.
+
+  :param str default: response if address is unavailable
+
+  :returns: **str** with our address
+  """
+
+  global CACHED_ADDRESS, ADDRESS_FETCHED
+
+  if ADDRESS_FETCHED is None or (time.time() - ADDRESS_FETCHED) > ADDRESS_FETCH_RATE:
+    CACHED_ADDRESS = tor_controller().get_info('address', None)
+    ADDRESS_FETCHED = time.time()
+
+  return CACHED_ADDRESS if CACHED_ADDRESS is not None else default
+
 def show_message(message = None, *attr, **kwargs):
   """
   Shows a message in our header.
diff --git a/nyx/panel/connection.py b/nyx/panel/connection.py
index c172908..8e5873d 100644
--- a/nyx/panel/connection.py
+++ b/nyx/panel/connection.py
@@ -16,7 +16,7 @@ import nyx.panel
 import nyx.popups
 import nyx.tracker
 
-from nyx import PAUSE_TIME, nyx_interface, tor_controller
+from nyx import PAUSE_TIME, nyx_interface, tor_controller, our_address
 from nyx.curses import WHITE, NORMAL, BOLD, HIGHLIGHT
 from nyx.menu import MenuItem, Submenu, RadioMenuItem, RadioGroup
 
@@ -571,8 +571,7 @@ def _draw_line(subwindow, x, y, line, is_selected, width, current_time):
 
 
 def _draw_address_column(subwindow, x, y, line, attr):
-  src = tor_controller().get_info('address', line.connection.local_address)
-  src += ':%s' % line.connection.local_port if line.line_type == LineType.CONNECTION else ''
+  src = '%s:%s' % (our_address(line.connection.local_address), line.connection.local_port if line.line_type == LineType.CONNECTION else '')
 
   if line.line_type == LineType.CIRCUIT_HEADER and line.circuit.status != 'BUILT':
     dst = 'Building...'
diff --git a/nyx/panel/header.py b/nyx/panel/header.py
index b1cbfbf..3751d56 100644
--- a/nyx/panel/header.py
+++ b/nyx/panel/header.py
@@ -23,7 +23,7 @@ import nyx.popups
 import nyx.tracker
 
 from stem.util import conf, log
-from nyx import nyx_interface, tor_controller
+from nyx import nyx_interface, tor_controller, our_address
 
 from nyx.curses import RED, GREEN, YELLOW, CYAN, WHITE, BOLD, HIGHLIGHT
 
@@ -268,7 +268,7 @@ class Sampling(object):
       'version': str(controller.get_version('Unknown')).split()[0],
       'version_status': controller.get_info('status/version/current', 'Unknown'),
 
-      'address': or_listeners[0][0] if (or_listeners and or_listeners[0][0] != '0.0.0.0') else controller.get_info('address', 'Unknown'),
+      'address': or_listeners[0][0] if (or_listeners and or_listeners[0][0] != '0.0.0.0') else our_address('Unknown'),
       'or_port': or_listeners[0][1] if or_listeners else '',
       'dir_port': controller.get_conf('DirPort', '0'),
       'control_port': str(control_listeners[0][1]) if control_listeners else None,
diff --git a/nyx/tracker.py b/nyx/tracker.py
index b2190fe..c41fdad 100644
--- a/nyx/tracker.py
+++ b/nyx/tracker.py
@@ -60,7 +60,7 @@ import stem.control
 import stem.descriptor.router_status_entry
 import stem.util.log
 
-from nyx import PAUSE_TIME, tor_controller
+from nyx import PAUSE_TIME, tor_controller, our_address
 from stem.util import conf, connection, enum, proc, str_tools, system
 
 CONFIG = conf.config_dict('nyx', {
@@ -902,7 +902,7 @@ class ConsensusTracker(object):
 
     controller = tor_controller()
 
-    if address == controller.get_info('address', None):
+    if our_address() == address:
       fingerprint = controller.get_info('fingerprint', None)
       ports = controller.get_ports(stem.control.Listener.OR, None)
 
@@ -923,10 +923,9 @@ class ConsensusTracker(object):
     controller = tor_controller()
 
     if fingerprint == controller.get_info('fingerprint', None):
-      my_address = controller.get_info('address', None)
       my_or_ports = controller.get_ports(stem.control.Listener.OR, [])
 
-      if my_address and len(my_or_ports) == 1:
+      if our_address() and len(my_or_ports) == 1:
         return (my_address, my_or_ports[0])
 
     return nyx.cache().relay_address(fingerprint, default)





More information about the tor-commits mailing list