Skip to content
This repository has been archived by the owner on Jul 14, 2020. It is now read-only.

Commit

Permalink
Merge pull request #51 from DonnchaC/deduplicate-instance-fetches
Browse files Browse the repository at this point in the history
Fetch each unique instance descriptor once per round
  • Loading branch information
DonnchaC authored Feb 21, 2017
2 parents f498afe + 3f49b70 commit 2c3378b
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 22 deletions.
18 changes: 10 additions & 8 deletions onionbalance/descriptor.py
Original file line number Diff line number Diff line change
Expand Up @@ -254,14 +254,16 @@ def descriptor_received(descriptor_content):
parsed_descriptor.permanent_key)
descriptor_onion_address = util.calc_onion_address(permanent_key)

# Find the HS instance for this descriptor
known_descriptor = False
for service in config.services:
for instance in service.instances:
if instance.onion_address == descriptor_onion_address:
# Update the descriptor
instance.update_descriptor(parsed_descriptor)
known_descriptor = True
known_descriptor, instance_changed = False, False
for instance in [instance for service in config.services for
instance in service.instances]:
if instance.onion_address == descriptor_onion_address:
instance_changed |= instance.update_descriptor(parsed_descriptor)
known_descriptor = True

if instance_changed:
logger.info("The introduction point set has changed for instance "
"%s.onion.", descriptor_onion_address)

if not known_descriptor:
# No matching service instance was found for the descriptor
Expand Down
52 changes: 38 additions & 14 deletions onionbalance/instance.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,25 @@ def fetch_instance_descriptors(controller):
else:
break

for service in config.services:
for instance in service.instances:
while True:
try:
instance.fetch_descriptor()
except stem.SocketClosed:
logger.error("Failed to fecth descriptor, socket "
"is closed")
util.reauthenticate(controller, logger)
else:
break
unique_instances = set(instance for service in config.services
for instance in service.instances)

# Only try to retrieve the descriptor once for each unique instance
# address. An instance may be configured under multiple master
# addressed. We do not want to request the same instance descriptor
# multiple times.
# OnionBalance will update all of the matching instances when a
# descriptor is received.
for instance in unique_instances:
while True:
try:
instance.fetch_descriptor()
except stem.SocketClosed:
logger.error("Failed to fecth descriptor, socket "
"is closed")
util.reauthenticate(controller, logger)
else:
break


class Instance(object):
Expand Down Expand Up @@ -98,7 +106,8 @@ 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.
points for this HS instance. Returns True if the introduction
point set has changed, False otherwise.`
"""

self.received = datetime.datetime.utcnow()
Expand Down Expand Up @@ -127,11 +136,26 @@ def update_descriptor(self, parsed_descriptor):
# (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
return True

else:
logger.debug("Introduction points for instance %s.onion matched "
"the cached set.", self.onion_address)
return False

def __eq__(self, other):
"""
Instance objects are equal if they have the same onion address.
"""
if isinstance(other, Instance):
return self.onion_address == other.onion_address
else:
return False

def __hash__(self):
"""
Define __hash__ method allowing for set comparison between instances.
"""
return hash(self.onion_address)

0 comments on commit 2c3378b

Please sign in to comment.