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