# Written by Arno Bakker # see LICENSE.txt for license information # # All applications on top of the SecureOverlay should be started here. # import sys from traceback import print_exc from time import time from BitTornado.BT1.MessageID import * from Tribler.toofastbt.CoordinatorMessageHandler import CoordinatorMessageHandler from Tribler.toofastbt.HelperMessageHandler import HelperMessageHandler from MetadataHandler import MetadataHandler from Tribler.BuddyCast.buddycast import BuddyCastFactory from Tribler.NATFirewall.DialbackMsgHandler import DialbackMsgHandler from Tribler.SocialNetwork.SocialNetworkMsgHandler import SocialNetworkMsgHandler from Tribler.SocialNetwork.RemoteQueryMsgHandler import RemoteQueryMsgHandler from Tribler.SocialNetwork.RemoteTorrentHandler import RemoteTorrentHandler from Tribler.utilities import show_permid_short from Tribler.CacheDB.CacheDBHandler import MyDBHandler DEBUG = False class OverlayApps: # Code to make this a singleton __single = None def __init__(self): if OverlayApps.__single: raise RuntimeError, "OverlayApps is Singleton" OverlayApps.__single = self self.coord_handler = None self.help_handler = None self.metadata_handler = None self.buddycast = None self.collect = None self.dialback_handler = None self.socnet_handler = None self.rquery_handler = None self.msg_handlers = {} self.text_mode = None self.torrent_collecting_solution = 2 # TODO: read from config # 1: simplest solution: per torrent/buddycasted peer/4hours # 2: tig for tag on group base def getInstance(*args, **kw): if OverlayApps.__single is None: OverlayApps(*args, **kw) return OverlayApps.__single getInstance = staticmethod(getInstance) def register(self, secure_overlay, launchmany, rawserver, config): self.secure_overlay = secure_overlay self.text_mode = config.has_key('text_mode') # OverlayApps gets all messages, and demultiplexes secure_overlay.register_recv_callback(self.handleMessage) secure_overlay.register_conns_callback(self.handleConnection) # Create handler for metadata messages in two parts, as # download help needs to know the metadata_handler and we need # to know the download helper handler. # Part 1: self.metadata_handler = MetadataHandler.getInstance() if config['download_help']: # Create handler for messages to dlhelp coordinator self.coord_handler = CoordinatorMessageHandler(launchmany) self.register_msg_handler(HelpHelperMessages, self.coord_handler.handleMessage) # Create handler for messages to dlhelp helper self.help_handler = HelperMessageHandler(launchmany) self.help_handler.register(self.metadata_handler,secure_overlay) self.register_msg_handler(HelpCoordinatorMessages, self.help_handler.handleMessage) # Part 2: self.metadata_handler.register(secure_overlay, self.help_handler, launchmany, config) self.register_msg_handler(MetadataMessages, self.metadata_handler.handleMessage) if not config['torrent_collecting']: self.torrent_collecting_solution = 0 if config['buddycast']: # Create handler for Buddycast messages self.buddycast = BuddyCastFactory.getInstance(superpeer=config['superpeer'], log=config['overlay_log']) # Using buddycast to handle torrent collecting since they are dependent self.buddycast.register(secure_overlay, launchmany.rawserver, launchmany, launchmany.listen_port, launchmany.exchandler, True, self.metadata_handler, self.torrent_collecting_solution, config['start_recommender'], config['max_peers']) self.register_msg_handler(BuddyCastMessages, self.buddycast.handleMessage) if config['dialback']: self.dialback_handler = DialbackMsgHandler.getInstance() self.dialback_handler.register(secure_overlay, launchmany.rawserver, launchmany, launchmany.handler, launchmany.listen_port, config['max_message_length'], config['dialback_active'], config['dialback_trust_superpeers'], config['dialback_interval']) self.register_msg_handler([DIALBACK_REQUEST], self.dialback_handler.handleSecOverlayMessage) if config['socnet']: self.socnet_handler = SocialNetworkMsgHandler.getInstance() self.socnet_handler.register(secure_overlay, launchmany.rawserver, config) self.register_msg_handler(SocialNetworkMessages,self.socnet_handler.handleMessage) if config['rquery']: self.rquery_handler = RemoteQueryMsgHandler.getInstance() self.rquery_handler.register(secure_overlay,launchmany,launchmany.rawserver,config,self.buddycast,log=config['overlay_log']) self.register_msg_handler(RemoteQueryMessages,self.rquery_handler.handleMessage) self.rtorrent_handler = RemoteTorrentHandler.getInstance() self.rtorrent_handler.register(launchmany.rawserver,self.metadata_handler) self.metadata_handler.register2(self.rtorrent_handler) if config['nickname'] != '__default_name__': # update my nickname mydb = MyDBHandler() mydb.put('name',config['nickname']) def register_msg_handler(self, ids, handler): """ ids is the [ID1, ID2, ..] where IDn is a sort of message ID in overlay swarm. Each ID can only be handled by one handler, but a handler can handle multiple IDs """ for id in ids: if DEBUG: print >> sys.stderr,"olapps: Handler registered for",getMessageName(id) self.msg_handlers[id] = handler def handleMessage(self,permid,selversion,message): """ demultiplex message stream to handlers """ id = message[0] if DEBUG: print >> sys.stderr,"olapps: got_message",getMessageName(id),"v"+str(selversion) if not self.msg_handlers.has_key(id): if DEBUG: print >> sys.stderr,"olapps: No handler found for",getMessageName(id) return False else: if DEBUG: print >> sys.stderr,"secover: Giving message to handler for",getMessageName(id) try: return self.msg_handlers[id](permid,selversion,message) except: # Catch all print_exc() return False def handleConnection(self,exc,permid,selversion,locally_initiated): """ An overlay-connection was established. Notify interested parties. """ if DEBUG: print >> sys.stderr,"olapps: handleConnection",exc,selversion,locally_initiated if self.dialback_handler is not None: # overlay-protocol version check done inside self.dialback_handler.handleSecOverlayConnection(exc,permid,selversion,locally_initiated) try: if exc is None: bOnline = True else: bOnline = False if not self.text_mode: from Tribler.vwxGUI.peermanager import PeerDataManager PeerDataManager.getInstance().setOnline(permid, bOnline) except: print_exc() if self.buddycast: self.buddycast.handleConnection(exc,permid,selversion,locally_initiated) if DEBUG: nconn = 0 conns = self.buddycast.buddycast_core.connections print >> sys.stdout, "\nbc: conn in buddycast" for peer_permid in conns: _permid = show_permid_short(peer_permid) nconn += 1 print >> sys.stdout, "bc: ", nconn, _permid, conns[peer_permid] if self.socnet_handler is not None: # overlay-protocol version check done inside self.socnet_handler.handleConnection(exc,permid,selversion,locally_initiated) if self.rquery_handler is not None: # overlay-protocol version check done inside self.rquery_handler.handleConnection(exc,permid,selversion,locally_initiated)