From 10d18d4a87da4289bea198a1714288f8208dd56d Mon Sep 17 00:00:00 2001 From: Dirk Engling Date: Tue, 3 Nov 2026 11:47:30 +0100 Subject: Refuse to start on a livesync.cluster.group that is not one --- tests/integration/test_livesync.py | 59 +++++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 20 deletions(-) (limited to 'tests/integration') diff --git a/tests/integration/test_livesync.py b/tests/integration/test_livesync.py index 52e871f..f4cb2db 100644 --- a/tests/integration/test_livesync.py +++ b/tests/integration/test_livesync.py @@ -10,7 +10,7 @@ import struct import subprocess import unittest -from harness import TRACKER, TrackerTestCase +from harness import TRACKER, Tracker, TrackerTestCase # enum { OT_SYNC_PEER4, OT_SYNC_PEER6 } in src/ot_livesync.c SYNC_PEER4 = 0 @@ -168,6 +168,13 @@ class LiveSyncUnconfigured(TrackerTestCase): # RFC 2365 sets 239.192.0.0/14 aside for exactly this kind of use OWN_GROUP = "239.192.0.7" +# A group nothing in this suite ever joins. Deliberately not the default one: +# other trackers here do join that, on ports the harness picks at random, and +# a socket bound to the wildcard address shares a port's multicast traffic +# with anything else on the host that has joined the group it is addressed +# to. Two clusters sharing a host and a port is pathological in the field but +# routine in a test suite. +UNJOINED_GROUP = "239.192.0.99" @unittest.skipUnless(has_livesync(), "this build has no WANT_SYNC_LIVE") @@ -182,27 +189,39 @@ class LiveSyncGroup(TrackerTestCase): group=OWN_GROUP) self.assertTrue(self.tracker.wait_until(lambda: self.tracker.torrent_count() == 1)) - def test_the_default_group_is_left_alone(self): - """A cluster that picked its own group should not hear the one every - other opentracker is on.""" + def test_another_group_is_left_alone(self): + """A cluster that picked its own group hears nothing from the others.""" info_hash = self.hash_for("not-our-group") - self.tracker.livesync_send(packet(SYNC_PEER4, [(info_hash, peer4("10.1.3.2", 6881, FLAG_SEEDING))])) + self.tracker.livesync_send(packet(SYNC_PEER4, [(info_hash, peer4("10.1.3.2", 6881, FLAG_SEEDING))]), + group=UNJOINED_GROUP) self.assertFalse(self.tracker.wait_until(lambda: self.tracker.torrent_count() != 0, timeout=1)) @unittest.skipUnless(has_livesync(), "this build has no WANT_SYNC_LIVE") -class LiveSyncGroupRefused(TrackerTestCase): - """A unicast address is not a group. The line is refused like any other - bad config line, which leaves the default standing.""" - - config = ("livesync.cluster.group 10.0.0.1\n" - "livesync.cluster.listen 127.0.0.1:{livesync_port}\n" - "livesync.cluster.node_ip 127.0.0.1\n") - - def test_the_line_is_refused(self): - self.assertIn("Parse error", self.tracker.output()) - - def test_and_the_default_group_still_works(self): - info_hash = self.hash_for("fallback-group") - self.tracker.livesync_send(packet(SYNC_PEER4, [(info_hash, peer4("10.1.3.3", 6881, FLAG_SEEDING))])) - self.assertTrue(self.tracker.wait_until(lambda: self.tracker.torrent_count() == 1)) +class LiveSyncGroupRefused(unittest.TestCase): + """A cluster that asked for a group of its own must not quietly end up on + the one every other opentracker is on, so a line that does not name a + group stops the tracker rather than falling back.""" + + def start_with(self, group): + return Tracker("livesync.cluster.group %s\n" + "livesync.cluster.listen 127.0.0.1:{livesync_port}\n" + "livesync.cluster.node_ip 127.0.0.1\n" % group) + + def test_a_unicast_address_stops_the_tracker(self): + with self.assertRaises(AssertionError) as caught: + self.start_with("10.0.0.1") + self.assertIn("multicast address", str(caught.exception)) + + def test_so_does_something_that_is_not_an_address(self): + with self.assertRaises(AssertionError) as caught: + self.start_with("not-an-address") + self.assertIn("multicast address", str(caught.exception)) + + def test_a_group_at_either_end_of_the_range_is_taken(self): + for group in ("224.0.0.1", "239.255.255.255"): + tracker = self.start_with(group) + try: + self.assertEqual(tracker.torrent_count(), 0) + finally: + tracker.stop() -- cgit v1.3