/usr/lib/python3/dist-packages/onionbalance/instance.py is in onionbalance 0.1.3-3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | # -*- coding: utf-8 -*-
import datetime
import time
import stem.control
from onionbalance import log
from onionbalance import config
logger = log.get_logger()
def fetch_instance_descriptors(controller):
"""
Try fetch fresh descriptors for all HS instances
"""
logger.info("Initiating fetch of descriptors for all service instances.")
# Clear Tor descriptor cache before making fetches by sending NEWNYM
# pylint: disable=no-member
controller.signal(stem.control.Signal.NEWNYM)
time.sleep(5)
for service in config.services:
for instance in service.instances:
instance.fetch_descriptor()
class Instance(object):
"""
Instance represents a back-end load balancing hidden service.
"""
def __init__(self, controller, onion_address, authentication_cookie=None):
"""
Initialise an Instance object.
"""
self.controller = controller
# Onion address for the service instance.
self.onion_address = onion_address
self.authentication_cookie = authentication_cookie
# Store the latest set of introduction points for this instance
self.introduction_points = []
# Timestamp when last received a descriptor for this instance
self.received = None
# Timestamp of the currently loaded descriptor
self.timestamp = None
# Flag this instance with it's introduction points change. A new
# master descriptor will then be published as the introduction
# points have changed.
self.changed_since_published = False
def fetch_descriptor(self):
"""
Try fetch a fresh descriptor for this service instance from the HSDirs
"""
logger.debug("Trying to fetch a descriptor for instance %s.onion.",
self.onion_address)
try:
self.controller.get_hidden_service_descriptor(self.onion_address,
await_result=False)
except stem.DescriptorUnavailable:
# Could not find the descriptor on the HSDir
self.received = None
logger.warning("No descriptor received for instance %s.onion, "
"the instance may be offline.", self.onion_address)
def update_descriptor(self, parsed_descriptor):
"""
Update introduction points when a new HS descriptor is received
Parse the descriptor content and update the set of introduction
points for this HS instance.
"""
self.received = datetime.datetime.utcnow()
logger.debug("Received a descriptor for instance %s.onion.",
self.onion_address)
# Reject descriptor if its timestamp is older than the current
# descriptor. Prevent's HSDir's replaying old, expired descriptors.
if self.timestamp and parsed_descriptor.published < self.timestamp:
logger.error("Received descriptor for instance %s.onion with "
"publication timestamp older than the latest "
"descriptor. Ignoring the descriptor.",
self.onion_address)
return
else:
self.timestamp = parsed_descriptor.published
# Parse the introduction point list, decrypting if necessary
introduction_points = parsed_descriptor.introduction_points(
authentication_cookie=self.authentication_cookie
)
# If the new introduction points are different, flag this instance
# as modified. Compare the set of introduction point identifiers
# (fingerprint of the per IP circuit service key).
if (set(ip.identifier for ip in introduction_points) !=
set(ip.identifier for ip in self.introduction_points)):
logger.info("The introduction point set has changed for instance "
"%s.onion.", self.onion_address)
self.changed_since_published = True
self.introduction_points = introduction_points
else:
logger.debug("Introduction points for instance %s.onion matched "
"the cached set.", self.onion_address)
|