3
0
mirror of https://github.com/jlu5/PyLink.git synced 2025-02-03 08:04:07 +01:00

relay: various cleanup

- Raise desync-related state checks to warning
- Rename get_remote_sid to get_relay_server_sid - it's less ambiguous
- Clarify and add some missing function docstrings
This commit is contained in:
James Lu 2017-09-23 20:40:54 -07:00
parent 6cbb6617ef
commit b52082ed05

View File

@ -218,6 +218,9 @@ def get_prefix_modes(irc, remoteirc, channel, user, mlist=None):
return modes return modes
def spawn_relay_server(irc, remoteirc): def spawn_relay_server(irc, remoteirc):
"""
Spawns a relay server representing "remoteirc" on "irc".
"""
if irc.connected.is_set(): if irc.connected.is_set():
try: try:
# ENDBURST is delayed by 3 secs on supported IRCds to prevent # ENDBURST is delayed by 3 secs on supported IRCds to prevent
@ -249,9 +252,11 @@ def spawn_relay_server(irc, remoteirc):
log.debug('(%s) spawn_relay_server: current thread is %s', log.debug('(%s) spawn_relay_server: current thread is %s',
irc.name, threading.current_thread().name) irc.name, threading.current_thread().name)
def get_remote_sid(irc, remoteirc, spawn_if_missing=True): def get_relay_server_sid(irc, remoteirc, spawn_if_missing=True):
"""Gets the remote server SID representing remoteirc on irc, spawning """
it if it doesn't exist (and spawn_if_missing is enabled).""" Fetches the relay server SID representing remoteirc on irc, spawning
a new server if it doesn't exist and spawn_if_missing is enabled.
"""
log.debug('(%s) Grabbing spawnlocks_servers[%s] from thread %r in function %r', irc.name, irc.name, log.debug('(%s) Grabbing spawnlocks_servers[%s] from thread %r in function %r', irc.name, irc.name,
threading.current_thread().name, inspect.currentframe().f_code.co_name) threading.current_thread().name, inspect.currentframe().f_code.co_name)
@ -260,28 +265,31 @@ def get_remote_sid(irc, remoteirc, spawn_if_missing=True):
sid = relayservers[irc.name][remoteirc.name] sid = relayservers[irc.name][remoteirc.name]
except KeyError: except KeyError:
if not spawn_if_missing: if not spawn_if_missing:
log.debug('(%s) get_remote_sid: %s.relay doesn\'t have a known SID, ignoring.', irc.name, remoteirc.name) log.debug('(%s) get_relay_server_sid: %s.relay doesn\'t have a known SID, ignoring.', irc.name, remoteirc.name)
spawnlocks_servers[irc.name].release() spawnlocks_servers[irc.name].release()
return return
log.debug('(%s) get_remote_sid: %s.relay doesn\'t have a known SID, spawning.', irc.name, remoteirc.name) log.debug('(%s) get_relay_server_sid: %s.relay doesn\'t have a known SID, spawning.', irc.name, remoteirc.name)
sid = spawn_relay_server(irc, remoteirc) sid = spawn_relay_server(irc, remoteirc)
log.debug('(%s) get_remote_sid: got %s for %s.relay', irc.name, sid, remoteirc.name) log.debug('(%s) get_relay_server_sid: got %s for %s.relay', irc.name, sid, remoteirc.name)
if sid not in irc.servers: if sid not in irc.servers:
log.debug('(%s) get_remote_sid: SID %s for %s.relay doesn\'t exist, respawning', irc.name, sid, remoteirc.name) log.warning('(%s) Possible desync? SID %s for %s.relay doesn\'t exist anymore', irc.name, sid, remoteirc.name)
# Our stored server doesn't exist anymore. This state is probably a holdover from a netsplit, # Our stored server doesn't exist anymore. This state is probably a holdover from a netsplit,
# so let's refresh it. # so let's refresh it.
sid = spawn_relay_server(irc, remoteirc) sid = spawn_relay_server(irc, remoteirc)
elif sid in irc.servers and irc.servers[sid].remote != remoteirc.name: elif sid in irc.servers and irc.servers[sid].remote != remoteirc.name:
log.debug('(%s) get_remote_sid: %s.relay != %s.relay, respawning', irc.name, irc.servers[sid].remote, remoteirc.name) log.debug('(%s) Possible desync? SID %s for %s.relay doesn\'t exist anymore is mismatched (got %s.relay)', irc.name, irc.servers[sid].remote, remoteirc.name)
sid = spawn_relay_server(irc, remoteirc) sid = spawn_relay_server(irc, remoteirc)
log.debug('(%s) get_remote_sid: got %s for %s.relay (round 2)', irc.name, sid, remoteirc.name) log.debug('(%s) get_relay_server_sid: got %s for %s.relay (round 2)', irc.name, sid, remoteirc.name)
spawnlocks_servers[irc.name].release() spawnlocks_servers[irc.name].release()
return sid return sid
def spawn_relay_user(irc, remoteirc, user, times_tagged=0): def spawn_relay_user(irc, remoteirc, user, times_tagged=0):
"""
Spawns a relay user representing "user" from "irc" (the local network) on remoteirc (the target network).
"""
userobj = irc.users.get(user) userobj = irc.users.get(user)
if userobj is None: if userobj is None:
# The query wasn't actually a valid user, or the network hasn't # The query wasn't actually a valid user, or the network hasn't
@ -318,7 +326,7 @@ def spawn_relay_user(irc, remoteirc, user, times_tagged=0):
if hideoper_mode and use_hideoper: if hideoper_mode and use_hideoper:
modes.add((hideoper_mode, None)) modes.add((hideoper_mode, None))
rsid = get_remote_sid(remoteirc, irc) rsid = get_relay_server_sid(remoteirc, irc)
if not rsid: if not rsid:
log.error('(%s) spawn_relay_user: aborting user spawn for %s/%s @ %s (failed to retrieve a ' log.error('(%s) spawn_relay_user: aborting user spawn for %s/%s @ %s (failed to retrieve a '
'working SID).', irc.name, user, nick, remoteirc.name) 'working SID).', irc.name, user, nick, remoteirc.name)
@ -355,8 +363,9 @@ def spawn_relay_user(irc, remoteirc, user, times_tagged=0):
def get_remote_user(irc, remoteirc, user, spawn_if_missing=True, times_tagged=0): def get_remote_user(irc, remoteirc, user, spawn_if_missing=True, times_tagged=0):
""" """
Gets the UID of the relay client requested on the target network (remoteirc), Fetches and returns the relay client UID representing "user" on the remote network "remoteirc",
spawning one if it doesn't exist and spawn_if_missing is True.""" spawning a new user if one doesn't exist and spawn_if_missing is True.
"""
# Wait until the network is working before trying to spawn anything. # Wait until the network is working before trying to spawn anything.
if irc.connected.is_set(): if irc.connected.is_set():
@ -383,7 +392,11 @@ def get_remote_user(irc, remoteirc, user, spawn_if_missing=True, times_tagged=0)
# don't break the relayer. If it turns out there was a client in our relayusers # don't break the relayer. If it turns out there was a client in our relayusers
# cache for the requested UID, but it doesn't match the request, # cache for the requested UID, but it doesn't match the request,
# assume it was a leftover from the last split and replace it with a new one. # assume it was a leftover from the last split and replace it with a new one.
# XXX: this technically means that PyLink is desyncing somewhere, and that we should
# fix this in core properly...
if u and ((u not in remoteirc.users) or remoteirc.users[u].remote != (irc.name, user)): if u and ((u not in remoteirc.users) or remoteirc.users[u].remote != (irc.name, user)):
log.warning('(%s) Possible desync? Got invalid relay UID %s for %s on %s',
irc.name, u, irc.get_friendly_name(user), remoteirc.name)
u = spawn_relay_user(irc, remoteirc, user, times_tagged=times_tagged) u = spawn_relay_user(irc, remoteirc, user, times_tagged=times_tagged)
spawnlocks[irc.name].release() spawnlocks[irc.name].release()
@ -718,7 +731,7 @@ def relay_joins(irc, channel, users, ts, **kwargs):
# Look at whether we should relay this join as a regular JOIN, or a SJOIN. # Look at whether we should relay this join as a regular JOIN, or a SJOIN.
# SJOIN will be used if either the amount of users to join is > 1, or there are modes # SJOIN will be used if either the amount of users to join is > 1, or there are modes
# to be set on the joining user. # to be set on the joining user.
rsid = get_remote_sid(remoteirc, irc) rsid = get_relay_server_sid(remoteirc, irc)
if burst or len(queued_users) > 1 or queued_users[0][0]: if burst or len(queued_users) > 1 or queued_users[0][0]:
modes = get_supported_cmodes(irc, remoteirc, channel, irc.channels[channel].modes) modes = get_supported_cmodes(irc, remoteirc, channel, irc.channels[channel].modes)
@ -1291,7 +1304,7 @@ def handle_messages(irc, numeric, command, args):
# possible - most IRCds except TS6 (charybdis, ratbox, hybrid) # possible - most IRCds except TS6 (charybdis, ratbox, hybrid)
# allow this. # allow this.
try: try:
user = get_remote_sid(remoteirc, irc, spawn_if_missing=False) \ user = get_relay_server_sid(remoteirc, irc, spawn_if_missing=False) \
if notice else remoteirc.pseudoclient.uid if notice else remoteirc.pseudoclient.uid
if not user: if not user:
return return
@ -1446,7 +1459,7 @@ def handle_kick(irc, source, command, args):
else: else:
# Kick originated from a server, or the kicker isn't in any # Kick originated from a server, or the kicker isn't in any
# common channels with the target relay network. # common channels with the target relay network.
rsid = get_remote_sid(remoteirc, irc) rsid = get_relay_server_sid(remoteirc, irc)
log.debug('(%s) relay.handle_kick: Kicking %s from channel %s via %s on behalf of %s/%s', irc.name, real_target, remotechan, rsid, kicker, irc.name) log.debug('(%s) relay.handle_kick: Kicking %s from channel %s via %s on behalf of %s/%s', irc.name, real_target, remotechan, rsid, kicker, irc.name)
if not irc.has_cap('can-spawn-clients'): if not irc.has_cap('can-spawn-clients'):
@ -1462,7 +1475,7 @@ def handle_kick(irc, source, command, args):
except AttributeError: except AttributeError:
text = "(<unknown kicker>@%s) %s" % (irc.name, args['text']) text = "(<unknown kicker>@%s) %s" % (irc.name, args['text'])
rsid = rsid or remoteirc.sid # Fall back to the main PyLink SID if get_remote_sid() fails rsid = rsid or remoteirc.sid # Fall back to the main PyLink SID if get_relay_server_sid() fails
remoteirc.kick(rsid, remotechan, real_target, text) remoteirc.kick(rsid, remotechan, real_target, text)
# If the target isn't on any channels, quit them. # If the target isn't on any channels, quit them.
@ -1528,7 +1541,7 @@ def handle_mode(irc, numeric, command, args):
# Check if the sender is a user with a relay client; otherwise relay the mode # Check if the sender is a user with a relay client; otherwise relay the mode
# from the corresponding server. # from the corresponding server.
remotesender = get_remote_user(irc, remoteirc, numeric, spawn_if_missing=False) or \ remotesender = get_remote_user(irc, remoteirc, numeric, spawn_if_missing=False) or \
get_remote_sid(remoteirc, irc) or remoteirc.sid get_relay_server_sid(remoteirc, irc) or remoteirc.sid
if not remoteirc.has_cap('can-spawn-clients'): if not remoteirc.has_cap('can-spawn-clients'):
friendly_modes = [] friendly_modes = []
@ -1621,7 +1634,7 @@ def handle_topic(irc, numeric, command, args):
if remoteuser: if remoteuser:
remoteirc.topic(remoteuser, remotechan, topic) remoteirc.topic(remoteuser, remotechan, topic)
else: else:
rsid = get_remote_sid(remoteirc, irc) rsid = get_relay_server_sid(remoteirc, irc)
remoteirc.topic_burst(rsid, remotechan, topic) remoteirc.topic_burst(rsid, remotechan, topic)
iterate_all(irc, _handle_topic_loop, extra_args=(numeric, command, args)) iterate_all(irc, _handle_topic_loop, extra_args=(numeric, command, args))
@ -1654,7 +1667,7 @@ def handle_kill(irc, numeric, command, args):
modes = get_prefix_modes(remoteirc, irc, remotechan, realuser[1]) modes = get_prefix_modes(remoteirc, irc, remotechan, realuser[1])
log.debug('(%s) relay.handle_kill: userpair: %s, %s', irc.name, modes, realuser) log.debug('(%s) relay.handle_kill: userpair: %s, %s', irc.name, modes, realuser)
client = get_remote_user(remoteirc, irc, realuser[1], times_tagged=1) client = get_remote_user(remoteirc, irc, realuser[1], times_tagged=1)
irc.sjoin(get_remote_sid(irc, remoteirc), localchan, [(modes, client)]) irc.sjoin(get_relay_server_sid(irc, remoteirc), localchan, [(modes, client)])
if userdata and numeric in irc.users: if userdata and numeric in irc.users:
log.info('(%s) relay.handle_kill: Blocked KILL (reason %r) from %s to relay client %s/%s.', log.info('(%s) relay.handle_kill: Blocked KILL (reason %r) from %s to relay client %s/%s.',