#!/usr/bin/env python2.3 #Copyright 2004 Sebastian Hagen # This file is part of eucharis. # eucharis is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 # as published by the Free Software Foundation # eucharis is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with eucharis; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # Not expected to ever be finished. import asynchronous_processing import irc_client import input_handlers class desynch_probe(input_handlers.handlers_user): def __init__(self, servername, hostname=None, channels=[], client_options={}, iptracker=None, callback_connection=None, callback_channels=None, callback_input=None): self.loggername = 'desynch_probe' self.logger = logging.getLogger(self.loggername) self.servername = servername if (hostname): self.hostname = hostname else: self.hostname = servername self.target_channels = channels self.callback_connection = callback_connection self.iptracker = iptracker self.connected = False self.connection = irc_client.irc_client(address=serverhost, channels=channels, **client_options) #We don't want the irc_client instance to retry on its own self.connection.goal = 'stop' self.handler_bindings = { 'irc_client':['statechange_connection', None, [], self.handler_statechange_connection] } def handler_statechange_connection(self, parent, output, event_type, event, data): if (event_type != 'statechange_connection'): raise ValueError('Got called for unknown event_type "%s" (expected statechange_connection).' % (event_type,)) if (event == 'up'): self.connected = True elif (event == 'down'): self.connected = False else: self.logger.log(35, 'handler_statechange_connection called for unknown event "%s". parent: %s output: %s event_type: %s event: %s data: %s' % (event, parent, output, event_type, event, data)) if (self.callback_connection): self.callback_connection(probe=self, event=event) if (event == 'down'): if (self.connection): if (self.iptracker): iptrack_return_value = self.iptracker.get_ip(servername=self.servername) if (iptrack_return_value): self.connection.client_settings['uplink_address'] = iptrack_return_value self.connection.connection_init() return None asynchronous_processing.gethostbyname(request=self.servername, callback_target=self.handler_asynchronous_gethostbyname) def handler_asynchronous_gethostbyname(self, request, response): if (self.connection): self.connection.client_settings['uplink_address'] = iptrack_return_value self.connection.connection_init() def clean_up(self): if (self.connection): self.connection.clean_up() self.connection = None class desynch_detector: def __init__(self, channels=[], iptracker=None): self.target_channels = channels self.iptracker = iptracker self.servers_targeted = {} self.servers_connected = {} def handler_statechange_connection(self, desynch_probe, event): servername = desynch_probe.servername if (event == 'up'): self.servers_connected[servername] = desynch_probe if (event == 'down'): if (servername in self.servers_connected): if (self.servers_connected[servername] == desynch_probe): del(self.servers_connected[servername]) else: self.logger.log(40, 'Got statechange_connection event "down" from desynch_probe %s which claims to target server %s, but the servers_connected entry for that server is %s. Ignoring.' % (desynch_probe, servername, self.servers_connected[servername])) else: self.logger.log(40, 'Got statechange_connection event "down" from desynch_probe %s which claims to target server %s, but have no record of this server being targeted. Ignoring.' % (desynch_probe, servername)) #Next Implementation steps: #1.Implement channel joining, and data management of which probes have joined which channels #2.Register handlers for and handle messages to channels #3.regularly perform comparisons between channel-data-dicts of all probes, and trigger alerts for lasting desynchs #4.Implement pinging, trigger timeouts if there is no response; perhaps measure delays? #5.Write user interface #