diff --git a/server/irc.py b/server/irc.py index af1e433..0e4ed48 100644 --- a/server/irc.py +++ b/server/irc.py @@ -42,15 +42,15 @@ class IRC(LoggedClass): env.irc_nick if env.irc_nick else double_sha256(env.report_host.encode()) [:5].hex()) - self.clients.append( IrcClient(irc_address, self.nick, - env.report_host, - env.report_tcp_port, - env.report_ssl_port) ) + self.clients.append(IrcClient(irc_address, self.nick, + env.report_host, + env.report_tcp_port, + env.report_ssl_port)) if env.report_host_tor: - self.clients.append( IrcClient(irc_address, self.nick + '_tor', - env.report_host_tor, - env.report_tcp_port_tor, - env.report_ssl_port_tor) ) + self.clients.append(IrcClient(irc_address, self.nick + '_tor', + env.report_host_tor, + env.report_tcp_port_tor, + env.report_ssl_port_tor)) self.peer_regexp = re.compile('({}[^!]*)!'.format(self.prefix)) self.peers = {} @@ -76,9 +76,9 @@ class IRC(LoggedClass): irc_client.ServerConnection.buffer_class = \ buffer.LenientDecodingLineBuffer + # Register handlers for events we're interested in reactor = irc_client.Reactor() - for event in ['welcome', 'join', 'quit', 'kick', 'whoreply', - 'namreply', 'disconnect']: + for event in 'welcome join quit kick whoreply disconnect'.split(): reactor.add_global_handler(event, getattr(self, 'on_' + event)) # Note: Multiple nicks in same channel will trigger duplicate events @@ -117,9 +117,15 @@ class IRC(LoggedClass): def on_join(self, connection, event): '''Called when someone new connects to our channel, including us.''' - match = self.peer_regexp.match(event.source) - if match: - connection.who(match.group(1)) + # /who the channel when we join. We used to /who on each + # namreply event, but the IRC server would frequently kick us + # 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): '''Called when someone leaves our channel.''' @@ -134,16 +140,6 @@ class IRC(LoggedClass): if match: 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): '''Called when a response to our who requests arrives. @@ -152,14 +148,15 @@ class IRC(LoggedClass): ''' try: nick = event.arguments[4] - line = event.arguments[6].split() - try: - ip_addr = socket.gethostbyname(line[1]) - except socket.error: - # Could be .onion or IPv6. - ip_addr = line[1] - peer = self.Peer(ip_addr, line[1], line[2:]) - self.peers[nick] = peer + if nick.startswith(self.prefix): + line = event.arguments[6].split() + try: + ip_addr = socket.gethostbyname(line[1]) + except socket.error: + # Could be .onion or IPv6. + ip_addr = line[1] + peer = self.Peer(ip_addr, line[1], line[2:]) + self.peers[nick] = peer except (IndexError, UnicodeError): # UnicodeError comes from invalid domains (issue #68) pass