commit 41079dcefbf4dec47967dcbcc0ab5bf135dc16ce Author: Damian Johnson atagar@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)