From a425f873b51e99da8e27ce9f3590c94ebfcf8fe1 Mon Sep 17 00:00:00 2001 From: James Lu Date: Sat, 10 Feb 2018 15:31:12 -0800 Subject: [PATCH] relay, inspircd: move endburst delay code to a private API This is a very specific hack that shouldn't be extended across the protocol module spec. So far, all other protocol modules ignore the endburst_delay option anyways. --- plugins/relay.py | 20 +++++++++++++++----- protocols/inspircd.py | 10 ++++++++-- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/plugins/relay.py b/plugins/relay.py index addbf75..e7af949 100644 --- a/plugins/relay.py +++ b/plugins/relay.py @@ -221,15 +221,25 @@ def spawn_relay_server(irc, remoteirc): """ if irc.connected.is_set(): try: - # ENDBURST is delayed by 3 secs on supported IRCds to prevent - # triggering join-flood protection and the like. suffix = irc.serverdata.get('server_suffix', conf.conf.get('relay', {}).get('server_suffix', 'relay')) - # Strip any leading or trailing .'s suffix = suffix.strip('.') + + # On some IRCds (e.g. InspIRCd), we have to delay endburst to prevent triggering + # join flood protections that are counted locally. + needs_delayed_eob = hasattr(irc, '_endburst_delay') + if needs_delayed_eob: + old_eob_delay = irc._endburst_delay + irc._endburst_delay = 3 + sid = irc.spawn_server('%s.%s' % (remoteirc.name, suffix), - desc="PyLink Relay network - %s" % - (remoteirc.get_full_network_name()), endburst_delay=3) + desc="PyLink Relay network - %s" % + (remoteirc.get_full_network_name())) + + # Set _endburst_delay back to its last value. + if needs_delayed_eob: + irc._endburst_delay = old_eob_delay + except (RuntimeError, ValueError): # Network not initialized yet, or a server name conflict. log.exception('(%s) Failed to spawn server for %r (possible jupe?):', irc.name, remoteirc.name) diff --git a/protocols/inspircd.py b/protocols/inspircd.py index 0365fb4..35ec464 100644 --- a/protocols/inspircd.py +++ b/protocols/inspircd.py @@ -37,6 +37,10 @@ class InspIRCdProtocol(TS6BaseProtocol): # Track the modules supported by the uplink. self._modsupport = set() + # Settable by plugins (e.g. relay) as needed, used to work around +j being triggered + # by bursting users. + self._endburst_delay = 0 + ### Outgoing commands def spawn_client(self, nick, ident='null', host='null', realhost=None, modes=set(), @@ -360,15 +364,17 @@ class InspIRCdProtocol(TS6BaseProtocol): self.servers[sid] = Server(self, uplink, name, internal=True, desc=desc) self._send_with_prefix(uplink, 'SERVER %s * %s %s :%s' % (name, self.servers[sid].hopcount, sid, desc)) + # Endburst delay clutter + def endburstf(): # Delay ENDBURST by X seconds if requested. - if self._aborted.wait(endburst_delay): + if self._aborted.wait(self._endburst_delay): # We managed to catch the abort flag before sending ENDBURST, so break log.debug('(%s) stopping endburstf() for %s as aborted was set', self.name, sid) return self._send_with_prefix(sid, 'ENDBURST') - if endburst_delay: + if self._endburst_delay: t = threading.Thread(target=endburstf, name="protocols/inspircd delayed ENDBURST thread for %s@%s" % (sid, self.name)) t.daemon = True t.start()