Browse Source

Fix IRC flood issues

Tweaked version of suggestions from Valesi, petrkr, and bauerj.
Fixes #93
master
Neil Booth 8 years ago
parent
commit
517f78858c
  1. 59
      server/irc.py

59
server/irc.py

@ -42,15 +42,15 @@ class IRC(LoggedClass):
env.irc_nick if env.irc_nick else env.irc_nick if env.irc_nick else
double_sha256(env.report_host.encode()) double_sha256(env.report_host.encode())
[:5].hex()) [:5].hex())
self.clients.append( IrcClient(irc_address, self.nick, self.clients.append(IrcClient(irc_address, self.nick,
env.report_host, env.report_host,
env.report_tcp_port, env.report_tcp_port,
env.report_ssl_port) ) env.report_ssl_port))
if env.report_host_tor: if env.report_host_tor:
self.clients.append( IrcClient(irc_address, self.nick + '_tor', self.clients.append(IrcClient(irc_address, self.nick + '_tor',
env.report_host_tor, env.report_host_tor,
env.report_tcp_port_tor, env.report_tcp_port_tor,
env.report_ssl_port_tor) ) env.report_ssl_port_tor))
self.peer_regexp = re.compile('({}[^!]*)!'.format(self.prefix)) self.peer_regexp = re.compile('({}[^!]*)!'.format(self.prefix))
self.peers = {} self.peers = {}
@ -76,9 +76,9 @@ class IRC(LoggedClass):
irc_client.ServerConnection.buffer_class = \ irc_client.ServerConnection.buffer_class = \
buffer.LenientDecodingLineBuffer buffer.LenientDecodingLineBuffer
# Register handlers for events we're interested in
reactor = irc_client.Reactor() reactor = irc_client.Reactor()
for event in ['welcome', 'join', 'quit', 'kick', 'whoreply', for event in 'welcome join quit kick whoreply disconnect'.split():
'namreply', 'disconnect']:
reactor.add_global_handler(event, getattr(self, 'on_' + event)) reactor.add_global_handler(event, getattr(self, 'on_' + event))
# Note: Multiple nicks in same channel will trigger duplicate events # Note: Multiple nicks in same channel will trigger duplicate events
@ -117,9 +117,15 @@ class IRC(LoggedClass):
def on_join(self, connection, event): def on_join(self, connection, event):
'''Called when someone new connects to our channel, including us.''' '''Called when someone new connects to our channel, including us.'''
match = self.peer_regexp.match(event.source) # /who the channel when we join. We used to /who on each
if match: # namreply event, but the IRC server would frequently kick us
connection.who(match.group(1)) # for flooding. This requests only once including the tor case.
if event.source.startswith(self.nick + '!'):
connection.who(self.channel)
else:
match = self.peer_regexp.match(event.source)
if match:
connection.who(match.group(1))
def on_quit(self, connection, event): def on_quit(self, connection, event):
'''Called when someone leaves our channel.''' '''Called when someone leaves our channel.'''
@ -134,16 +140,6 @@ class IRC(LoggedClass):
if match: if match:
self.peers.pop(match.group(1), None) self.peers.pop(match.group(1), None)
def on_namreply(self, connection, event):
'''Called repeatedly when we first connect to inform us of all users
in the channel.
The users are space-separated in the 2nd argument.
'''
for peer in event.arguments[2].split():
if peer.startswith(self.prefix):
connection.who(peer)
def on_whoreply(self, connection, event): def on_whoreply(self, connection, event):
'''Called when a response to our who requests arrives. '''Called when a response to our who requests arrives.
@ -152,14 +148,15 @@ class IRC(LoggedClass):
''' '''
try: try:
nick = event.arguments[4] nick = event.arguments[4]
line = event.arguments[6].split() if nick.startswith(self.prefix):
try: line = event.arguments[6].split()
ip_addr = socket.gethostbyname(line[1]) try:
except socket.error: ip_addr = socket.gethostbyname(line[1])
# Could be .onion or IPv6. except socket.error:
ip_addr = line[1] # Could be .onion or IPv6.
peer = self.Peer(ip_addr, line[1], line[2:]) ip_addr = line[1]
self.peers[nick] = peer peer = self.Peer(ip_addr, line[1], line[2:])
self.peers[nick] = peer
except (IndexError, UnicodeError): except (IndexError, UnicodeError):
# UnicodeError comes from invalid domains (issue #68) # UnicodeError comes from invalid domains (issue #68)
pass pass

Loading…
Cancel
Save