Beispiel #1
0
def makeService(config):
    s = service.MultiService()

    # Create backend service with storage

    if config['backend'] == 'pgsql':
        from twisted.enterprise import adbapi
        from idavoll.pgsql_storage import Storage
        from psycopg2.extras import NamedTupleConnection
        dbpool = adbapi.ConnectionPool(
            'psycopg2',
            user=config['dbuser'],
            password=config['dbpass'],
            database=config['dbname'],
            host=config['dbhost'],
            port=config['dbport'],
            cp_reconnect=True,
            client_encoding='utf-8',
            connection_factory=NamedTupleConnection,
        )
        st = Storage(dbpool)
    elif config['backend'] == 'memory':
        from idavoll.memory_storage import Storage
        st = Storage()

    bs = BackendService(st)
    bs.setName('backend')
    bs.setServiceParent(s)

    # Set up XMPP server-side component with publish-subscribe capabilities

    cs = Component(config["rhost"], int(config["rport"]), config["jid"].full(),
                   config["secret"])
    cs.setName('component')
    cs.setServiceParent(s)

    cs.factory.maxDelay = 900

    if config["verbose"]:
        cs.logTraffic = True

    FallbackHandler().setHandlerParent(cs)
    VersionHandler('Idavoll', __version__).setHandlerParent(cs)
    DiscoHandler().setHandlerParent(cs)

    resource = IPubSubResource(bs)
    resource.hideNodes = config["hide-nodes"]
    resource.serviceJID = config["jid"]

    ps = PubSubService(resource)
    ps.setHandlerParent(cs)
    resource.pubsubService = ps

    return s
Beispiel #2
0
    def __init__(self):
        config = XMPPGatewayConfig

        self.stopped = False

        self.domains = set(config.domains)
        self.muc_domains = set(
            ['%s.%s' % (config.muc_prefix, domain) for domain in self.domains])

        router = SylkRouter()
        self._server_service = ServerService(router)
        self._server_service.domains = self.domains | self.muc_domains
        self._server_service.logTraffic = False  # done manually

        self._s2s_factory = SylkS2SServerFactory(self._server_service)
        self._s2s_factory.logTraffic = False  # done manually

        # Setup internal components

        self._internal_component = SylkInternalComponent(router)
        self._internal_component.domains = self.domains
        self._internal_component.manager = self
        self._muc_component = SylkInternalComponent(router)
        self._muc_component.domains = self.muc_domains
        self._muc_component.manager = self

        # Setup protocols

        self.message_protocol = MessageProtocol()
        self.message_protocol.setHandlerParent(self._internal_component)

        self.presence_protocol = PresenceProtocol()
        self.presence_protocol.setHandlerParent(self._internal_component)

        self.disco_protocol = DiscoProtocol()
        self.disco_protocol.setHandlerParent(self._internal_component)

        self.disco_client_protocol = DiscoClientProtocol()
        self.disco_client_protocol.setHandlerParent(self._internal_component)

        self.muc_protocol = MUCServerProtocol()
        self.muc_protocol.setHandlerParent(self._muc_component)

        self.muc_presence_protocol = MUCPresenceProtocol()
        self.muc_presence_protocol.setHandlerParent(self._muc_component)

        self.disco_muc_protocol = DiscoProtocol()
        self.disco_muc_protocol.setHandlerParent(self._muc_component)

        self.version_protocol = VersionHandler('SylkServer', SYLK_VERSION)
        self.version_protocol.setHandlerParent(self._internal_component)

        self.fallback_protocol = FallbackHandler()
        self.fallback_protocol.setHandlerParent(self._internal_component)

        self.fallback_muc_protocol = FallbackHandler()
        self.fallback_muc_protocol.setHandlerParent(self._muc_component)

        self.ping_protocol = PingHandler()
        self.ping_protocol.setHandlerParent(self._internal_component)

        self.jingle_protocol = JingleProtocol()
        self.jingle_protocol.setHandlerParent(self._internal_component)

        self.jingle_coin_protocol = JingleProtocol()
        self.jingle_coin_protocol.setHandlerParent(self._muc_component)

        self._s2s_listener = None

        self.chat_session_manager = XMPPChatSessionManager()
        self.muc_session_manager = XMPPMucSessionManager()
        self.subscription_manager = XMPPSubscriptionManager()
        self.jingle_session_manager = JingleSessionManager()
Beispiel #3
0
class XMPPManager(object):
    __metaclass__ = Singleton
    implements(IObserver)

    def __init__(self):
        config = XMPPGatewayConfig

        self.stopped = False

        self.domains = set(config.domains)
        self.muc_domains = set(
            ['%s.%s' % (config.muc_prefix, domain) for domain in self.domains])

        router = SylkRouter()
        self._server_service = ServerService(router)
        self._server_service.domains = self.domains | self.muc_domains
        self._server_service.logTraffic = False  # done manually

        self._s2s_factory = SylkS2SServerFactory(self._server_service)
        self._s2s_factory.logTraffic = False  # done manually

        # Setup internal components

        self._internal_component = SylkInternalComponent(router)
        self._internal_component.domains = self.domains
        self._internal_component.manager = self
        self._muc_component = SylkInternalComponent(router)
        self._muc_component.domains = self.muc_domains
        self._muc_component.manager = self

        # Setup protocols

        self.message_protocol = MessageProtocol()
        self.message_protocol.setHandlerParent(self._internal_component)

        self.presence_protocol = PresenceProtocol()
        self.presence_protocol.setHandlerParent(self._internal_component)

        self.disco_protocol = DiscoProtocol()
        self.disco_protocol.setHandlerParent(self._internal_component)

        self.disco_client_protocol = DiscoClientProtocol()
        self.disco_client_protocol.setHandlerParent(self._internal_component)

        self.muc_protocol = MUCServerProtocol()
        self.muc_protocol.setHandlerParent(self._muc_component)

        self.muc_presence_protocol = MUCPresenceProtocol()
        self.muc_presence_protocol.setHandlerParent(self._muc_component)

        self.disco_muc_protocol = DiscoProtocol()
        self.disco_muc_protocol.setHandlerParent(self._muc_component)

        self.version_protocol = VersionHandler('SylkServer', SYLK_VERSION)
        self.version_protocol.setHandlerParent(self._internal_component)

        self.fallback_protocol = FallbackHandler()
        self.fallback_protocol.setHandlerParent(self._internal_component)

        self.fallback_muc_protocol = FallbackHandler()
        self.fallback_muc_protocol.setHandlerParent(self._muc_component)

        self.ping_protocol = PingHandler()
        self.ping_protocol.setHandlerParent(self._internal_component)

        self.jingle_protocol = JingleProtocol()
        self.jingle_protocol.setHandlerParent(self._internal_component)

        self.jingle_coin_protocol = JingleProtocol()
        self.jingle_coin_protocol.setHandlerParent(self._muc_component)

        self._s2s_listener = None

        self.chat_session_manager = XMPPChatSessionManager()
        self.muc_session_manager = XMPPMucSessionManager()
        self.subscription_manager = XMPPSubscriptionManager()
        self.jingle_session_manager = JingleSessionManager()

    def start(self):
        self.stopped = False
        xmpp_logger.start()
        config = XMPPGatewayConfig
        if config.trace_xmpp and xmpp_logger._xmpptrace_filename is not None:
            log.msg('Logging XMPP trace to file "%s"' %
                    xmpp_logger._xmpptrace_filename)
        self._s2s_listener = reactor.listenTCP(config.local_port,
                                               self._s2s_factory,
                                               interface=config.local_ip)
        listen_address = self._s2s_listener.getHost()
        log.msg("XMPP listener started on %s:%d" %
                (listen_address.host, listen_address.port))
        self.chat_session_manager.start()
        self.muc_session_manager.start()
        self.subscription_manager.start()
        self.jingle_session_manager.start()
        notification_center = NotificationCenter()
        notification_center.add_observer(self, sender=self._internal_component)
        notification_center.add_observer(self, sender=self._muc_component)
        self._internal_component.startService()
        self._muc_component.startService()

    def stop(self):
        self.stopped = True
        self._s2s_listener.stopListening()
        self.jingle_session_manager.stop()
        self.subscription_manager.stop()
        self.muc_session_manager.stop()
        self.chat_session_manager.stop()
        self._internal_component.stopService()
        self._muc_component.stopService()
        notification_center = NotificationCenter()
        notification_center.remove_observer(self,
                                            sender=self._internal_component)
        notification_center.remove_observer(self, sender=self._muc_component)
        xmpp_logger.stop()

    def send_stanza(self, stanza):
        if self.stopped:
            return
        self._internal_component.send(stanza.to_xml_element())

    def send_muc_stanza(self, stanza):
        if self.stopped:
            return
        self._muc_component.send(stanza.to_xml_element())

    def handle_notification(self, notification):
        handler = getattr(self, '_NH_%s' % notification.name, Null)
        handler(notification)

    # Process message stanzas

    def _NH_XMPPGotChatMessage(self, notification):
        message = notification.data.message
        try:
            session = self.chat_session_manager.sessions[(
                message.recipient.uri, message.sender.uri)]
        except KeyError:
            notification.center.post_notification('XMPPGotChatMessage',
                                                  sender=self,
                                                  data=notification.data)
        else:
            session.channel.send(message)

    def _NH_XMPPGotNormalMessage(self, notification):
        notification.center.post_notification('XMPPGotNormalMessage',
                                              sender=self,
                                              data=notification.data)

    def _NH_XMPPGotComposingIndication(self, notification):
        composing_indication = notification.data.composing_indication
        try:
            session = self.chat_session_manager.sessions[(
                composing_indication.recipient.uri,
                composing_indication.sender.uri)]
        except KeyError:
            notification.center.post_notification('XMPPGotComposingIndication',
                                                  sender=self,
                                                  data=notification.data)
        else:
            session.channel.send(composing_indication)

    def _NH_XMPPGotErrorMessage(self, notification):
        error_message = notification.data.error_message
        try:
            session = self.chat_session_manager.sessions[(
                error_message.recipient.uri, error_message.sender.uri)]
        except KeyError:
            notification.center.post_notification('XMPPGotErrorMessage',
                                                  sender=self,
                                                  data=notification.data)
        else:
            session.channel.send(error_message)

    def _NH_XMPPGotReceipt(self, notification):
        receipt = notification.data.receipt
        try:
            session = self.chat_session_manager.sessions[(
                receipt.recipient.uri, receipt.sender.uri)]
        except KeyError:
            pass
        else:
            session.channel.send(receipt)

    # Process presence stanzas

    def _NH_XMPPGotPresenceAvailability(self, notification):
        stanza = notification.data.presence_stanza
        if stanza.recipient.uri.resource is not None:
            # Skip directed presence
            return
        sender_uri = stanza.sender.uri
        sender_uri_bare = FrozenURI(sender_uri.user, sender_uri.host)
        try:
            subscription = self.subscription_manager.outgoing_subscriptions[(
                stanza.recipient.uri, sender_uri_bare)]
        except KeyError:
            # Ignore incoming presence stanzas if there is no subscription
            pass
        else:
            subscription.channel.send(stanza)

    def _NH_XMPPGotPresenceSubscriptionStatus(self, notification):
        stanza = notification.data.presence_stanza
        if stanza.sender.uri.resource is not None or stanza.recipient.uri.resource is not None:
            # Skip directed presence
            return
        if stanza.type in ('subscribed', 'unsubscribed'):
            try:
                subscription = self.subscription_manager.outgoing_subscriptions[
                    (stanza.recipient.uri, stanza.sender.uri)]
            except KeyError:
                pass
            else:
                subscription.channel.send(stanza)
        elif stanza.type in ('subscribe', 'unsubscribe'):
            try:
                subscription = self.subscription_manager.incoming_subscriptions[
                    (stanza.recipient.uri, stanza.sender.uri)]
            except KeyError:
                if stanza.type == 'subscribe':
                    notification.center.post_notification(
                        'XMPPGotPresenceSubscriptionRequest',
                        sender=self,
                        data=NotificationData(stanza=stanza))
            else:
                subscription.channel.send(stanza)

    def _NH_XMPPGotPresenceProbe(self, notification):
        stanza = notification.data.presence_stanza
        if stanza.recipient.uri.resource is not None:
            # Skip directed presence
            return
        sender_uri = stanza.sender.uri
        sender_uri_bare = FrozenURI(sender_uri.user, sender_uri.host)
        try:
            subscription = self.subscription_manager.incoming_subscriptions[(
                stanza.recipient.uri, sender_uri_bare)]
        except KeyError:
            notification.center.post_notification(
                'XMPPGotPresenceSubscriptionRequest',
                sender=self,
                data=NotificationData(stanza=stanza))
        else:
            subscription.channel.send(stanza)

    # Process muc stanzas

    def _NH_XMPPMucGotGroupChat(self, notification):
        message = notification.data.message
        muc_uri = FrozenURI(message.recipient.uri.user,
                            message.recipient.uri.host)
        try:
            session = self.muc_session_manager.incoming[(muc_uri,
                                                         message.sender.uri)]
        except KeyError:
            # Ignore groupchat messages if there was no session created
            pass
        else:
            session.channel.send(message)

    def _NH_XMPPMucGotPresenceAvailability(self, notification):
        stanza = notification.data.presence_stanza
        if not stanza.sender.uri.resource:
            return
        muc_uri = FrozenURI(stanza.recipient.uri.user,
                            stanza.recipient.uri.host)
        try:
            session = self.muc_session_manager.incoming[(muc_uri,
                                                         stanza.sender.uri)]
        except KeyError:
            if stanza.available:
                notification.center.post_notification(
                    'XMPPGotMucJoinRequest',
                    sender=self,
                    data=NotificationData(stanza=stanza))
            else:
                notification.center.post_notification(
                    'XMPPGotMucLeaveRequest',
                    sender=self,
                    data=NotificationData(stanza=stanza))
        else:
            session.channel.send(stanza)

    def _NH_XMPPMucGotInvitation(self, notification):
        invitation = notification.data.invitation
        data = NotificationData(sender=invitation.sender,
                                recipient=invitation.recipient,
                                participant=invitation.invited_user)
        notification.center.post_notification(
            'XMPPGotMucAddParticipantRequest', sender=self, data=data)

    # Jingle

    def _NH_XMPPGotJingleSessionInitiate(self, notification):
        stanza = notification.data.stanza
        try:
            self.jingle_session_manager.sessions[stanza.jingle.sid]
        except KeyError:
            session = JingleSession(notification.data.protocol)
            session.init_incoming(stanza)
            session.send_ring_indication()

    def _NH_XMPPGotJingleSessionTerminate(self, notification):
        stanza = notification.data.stanza
        try:
            session = self.jingle_session_manager.sessions[stanza.jingle.sid]
        except KeyError:
            return
        session.handle_notification(notification)

    def _NH_XMPPGotJingleSessionInfo(self, notification):
        stanza = notification.data.stanza
        try:
            session = self.jingle_session_manager.sessions[stanza.jingle.sid]
        except KeyError:
            return
        session.handle_notification(notification)

    def _NH_XMPPGotJingleSessionAccept(self, notification):
        stanza = notification.data.stanza
        try:
            session = self.jingle_session_manager.sessions[stanza.jingle.sid]
        except KeyError:
            return
        session.handle_notification(notification)

    def _NH_XMPPGotJingleDescriptionInfo(self, notification):
        stanza = notification.data.stanza
        try:
            session = self.jingle_session_manager.sessions[stanza.jingle.sid]
        except KeyError:
            return
        session.handle_notification(notification)

    def _NH_XMPPGotJingleTransportInfo(self, notification):
        stanza = notification.data.stanza
        try:
            session = self.jingle_session_manager.sessions[stanza.jingle.sid]
        except KeyError:
            return
        session.handle_notification(notification)
Beispiel #4
0
    def __init__(self):
        config = XMPPGatewayConfig

        self.stopped = False

        self.domains = set(config.domains)
        self.muc_domains = set(['%s.%s' % (config.muc_prefix, domain) for domain in self.domains])

        router = SylkRouter()
        self._server_service = ServerService(router)
        self._server_service.domains = self.domains | self.muc_domains
        self._server_service.logTraffic = False    # done manually

        self._s2s_factory = SylkS2SServerFactory(self._server_service)
        self._s2s_factory.logTraffic = False    # done manually

        # Setup internal components

        self._internal_component = SylkInternalComponent(router)
        self._internal_component.domains = self.domains
        self._internal_component.manager = self
        self._muc_component = SylkInternalComponent(router)
        self._muc_component.domains = self.muc_domains
        self._muc_component.manager = self

        # Setup protocols

        self.message_protocol = MessageProtocol()
        self.message_protocol.setHandlerParent(self._internal_component)

        self.presence_protocol = PresenceProtocol()
        self.presence_protocol.setHandlerParent(self._internal_component)

        self.disco_protocol = DiscoProtocol()
        self.disco_protocol.setHandlerParent(self._internal_component)

        self.disco_client_protocol = DiscoClientProtocol()
        self.disco_client_protocol.setHandlerParent(self._internal_component)

        self.muc_protocol = MUCServerProtocol()
        self.muc_protocol.setHandlerParent(self._muc_component)

        self.muc_presence_protocol = MUCPresenceProtocol()
        self.muc_presence_protocol.setHandlerParent(self._muc_component)

        self.disco_muc_protocol = DiscoProtocol()
        self.disco_muc_protocol.setHandlerParent(self._muc_component)

        self.version_protocol = VersionHandler('SylkServer', SYLK_VERSION)
        self.version_protocol.setHandlerParent(self._internal_component)

        self.fallback_protocol = FallbackHandler()
        self.fallback_protocol.setHandlerParent(self._internal_component)

        self.fallback_muc_protocol = FallbackHandler()
        self.fallback_muc_protocol.setHandlerParent(self._muc_component)

        self.ping_protocol = PingHandler()
        self.ping_protocol.setHandlerParent(self._internal_component)

        self.jingle_protocol = JingleProtocol()
        self.jingle_protocol.setHandlerParent(self._internal_component)

        self.jingle_coin_protocol = JingleProtocol()
        self.jingle_coin_protocol.setHandlerParent(self._muc_component)

        self._s2s_listener = None

        self.chat_session_manager = XMPPChatSessionManager()
        self.muc_session_manager = XMPPMucSessionManager()
        self.subscription_manager = XMPPSubscriptionManager()
        self.jingle_session_manager = JingleSessionManager()
Beispiel #5
0
class XMPPManager(object):
    __metaclass__ = Singleton
    implements(IObserver)

    def __init__(self):
        config = XMPPGatewayConfig

        self.stopped = False

        self.domains = set(config.domains)
        self.muc_domains = set(['%s.%s' % (config.muc_prefix, domain) for domain in self.domains])

        router = SylkRouter()
        self._server_service = ServerService(router)
        self._server_service.domains = self.domains | self.muc_domains
        self._server_service.logTraffic = False    # done manually

        self._s2s_factory = SylkS2SServerFactory(self._server_service)
        self._s2s_factory.logTraffic = False    # done manually

        # Setup internal components

        self._internal_component = SylkInternalComponent(router)
        self._internal_component.domains = self.domains
        self._internal_component.manager = self
        self._muc_component = SylkInternalComponent(router)
        self._muc_component.domains = self.muc_domains
        self._muc_component.manager = self

        # Setup protocols

        self.message_protocol = MessageProtocol()
        self.message_protocol.setHandlerParent(self._internal_component)

        self.presence_protocol = PresenceProtocol()
        self.presence_protocol.setHandlerParent(self._internal_component)

        self.disco_protocol = DiscoProtocol()
        self.disco_protocol.setHandlerParent(self._internal_component)

        self.disco_client_protocol = DiscoClientProtocol()
        self.disco_client_protocol.setHandlerParent(self._internal_component)

        self.muc_protocol = MUCServerProtocol()
        self.muc_protocol.setHandlerParent(self._muc_component)

        self.muc_presence_protocol = MUCPresenceProtocol()
        self.muc_presence_protocol.setHandlerParent(self._muc_component)

        self.disco_muc_protocol = DiscoProtocol()
        self.disco_muc_protocol.setHandlerParent(self._muc_component)

        self.version_protocol = VersionHandler('SylkServer', SYLK_VERSION)
        self.version_protocol.setHandlerParent(self._internal_component)

        self.fallback_protocol = FallbackHandler()
        self.fallback_protocol.setHandlerParent(self._internal_component)

        self.fallback_muc_protocol = FallbackHandler()
        self.fallback_muc_protocol.setHandlerParent(self._muc_component)

        self.ping_protocol = PingHandler()
        self.ping_protocol.setHandlerParent(self._internal_component)

        self.jingle_protocol = JingleProtocol()
        self.jingle_protocol.setHandlerParent(self._internal_component)

        self.jingle_coin_protocol = JingleProtocol()
        self.jingle_coin_protocol.setHandlerParent(self._muc_component)

        self._s2s_listener = None

        self.chat_session_manager = XMPPChatSessionManager()
        self.muc_session_manager = XMPPMucSessionManager()
        self.subscription_manager = XMPPSubscriptionManager()
        self.jingle_session_manager = JingleSessionManager()

    def start(self):
        self.stopped = False
        xmpp_logger.start()
        config = XMPPGatewayConfig
        if config.trace_xmpp and xmpp_logger._xmpptrace_filename is not None:
            log.msg('Logging XMPP trace to file "%s"' % xmpp_logger._xmpptrace_filename)
        self._s2s_listener = reactor.listenTCP(config.local_port, self._s2s_factory, interface=config.local_ip)
        listen_address = self._s2s_listener.getHost()
        log.msg("XMPP listener started on %s:%d" % (listen_address.host, listen_address.port))
        self.chat_session_manager.start()
        self.muc_session_manager.start()
        self.subscription_manager.start()
        self.jingle_session_manager.start()
        notification_center = NotificationCenter()
        notification_center.add_observer(self, sender=self._internal_component)
        notification_center.add_observer(self, sender=self._muc_component)
        self._internal_component.startService()
        self._muc_component.startService()

    def stop(self):
        self.stopped = True
        self._s2s_listener.stopListening()
        self.jingle_session_manager.stop()
        self.subscription_manager.stop()
        self.muc_session_manager.stop()
        self.chat_session_manager.stop()
        self._internal_component.stopService()
        self._muc_component.stopService()
        notification_center = NotificationCenter()
        notification_center.remove_observer(self, sender=self._internal_component)
        notification_center.remove_observer(self, sender=self._muc_component)
        xmpp_logger.stop()

    def send_stanza(self, stanza):
        if self.stopped:
            return
        self._internal_component.send(stanza.to_xml_element())

    def send_muc_stanza(self, stanza):
        if self.stopped:
            return
        self._muc_component.send(stanza.to_xml_element())

    def handle_notification(self, notification):
        handler = getattr(self, '_NH_%s' % notification.name, Null)
        handler(notification)

    # Process message stanzas

    def _NH_XMPPGotChatMessage(self, notification):
        message = notification.data.message
        try:
            session = self.chat_session_manager.sessions[(message.recipient.uri, message.sender.uri)]
        except KeyError:
            notification.center.post_notification('XMPPGotChatMessage', sender=self, data=notification.data)
        else:
            session.channel.send(message)

    def _NH_XMPPGotNormalMessage(self, notification):
        notification.center.post_notification('XMPPGotNormalMessage', sender=self, data=notification.data)

    def _NH_XMPPGotComposingIndication(self, notification):
        composing_indication = notification.data.composing_indication
        try:
            session = self.chat_session_manager.sessions[(composing_indication.recipient.uri, composing_indication.sender.uri)]
        except KeyError:
            notification.center.post_notification('XMPPGotComposingIndication', sender=self, data=notification.data)
        else:
            session.channel.send(composing_indication)

    def _NH_XMPPGotErrorMessage(self, notification):
        error_message = notification.data.error_message
        try:
            session = self.chat_session_manager.sessions[(error_message.recipient.uri, error_message.sender.uri)]
        except KeyError:
            notification.center.post_notification('XMPPGotErrorMessage', sender=self, data=notification.data)
        else:
            session.channel.send(error_message)

    def _NH_XMPPGotReceipt(self, notification):
        receipt = notification.data.receipt
        try:
            session = self.chat_session_manager.sessions[(receipt.recipient.uri, receipt.sender.uri)]
        except KeyError:
            pass
        else:
            session.channel.send(receipt)

    # Process presence stanzas

    def _NH_XMPPGotPresenceAvailability(self, notification):
        stanza = notification.data.presence_stanza
        if stanza.recipient.uri.resource is not None:
            # Skip directed presence
            return
        sender_uri = stanza.sender.uri
        sender_uri_bare = FrozenURI(sender_uri.user, sender_uri.host)
        try:
            subscription = self.subscription_manager.outgoing_subscriptions[(stanza.recipient.uri, sender_uri_bare)]
        except KeyError:
            # Ignore incoming presence stanzas if there is no subscription
            pass
        else:
            subscription.channel.send(stanza)

    def _NH_XMPPGotPresenceSubscriptionStatus(self, notification):
        stanza = notification.data.presence_stanza
        if stanza.sender.uri.resource is not None or stanza.recipient.uri.resource is not None:
            # Skip directed presence
            return
        if stanza.type in ('subscribed', 'unsubscribed'):
            try:
                subscription = self.subscription_manager.outgoing_subscriptions[(stanza.recipient.uri, stanza.sender.uri)]
            except KeyError:
                pass
            else:
                subscription.channel.send(stanza)
        elif stanza.type in ('subscribe', 'unsubscribe'):
            try:
                subscription = self.subscription_manager.incoming_subscriptions[(stanza.recipient.uri, stanza.sender.uri)]
            except KeyError:
                if stanza.type == 'subscribe':
                    notification.center.post_notification('XMPPGotPresenceSubscriptionRequest', sender=self, data=NotificationData(stanza=stanza))
            else:
                subscription.channel.send(stanza)

    def _NH_XMPPGotPresenceProbe(self, notification):
        stanza = notification.data.presence_stanza
        if stanza.recipient.uri.resource is not None:
            # Skip directed presence
            return
        sender_uri = stanza.sender.uri
        sender_uri_bare = FrozenURI(sender_uri.user, sender_uri.host)
        try:
            subscription = self.subscription_manager.incoming_subscriptions[(stanza.recipient.uri, sender_uri_bare)]
        except KeyError:
            notification.center.post_notification('XMPPGotPresenceSubscriptionRequest', sender=self, data=NotificationData(stanza=stanza))
        else:
            subscription.channel.send(stanza)

    # Process muc stanzas

    def _NH_XMPPMucGotGroupChat(self, notification):
        message = notification.data.message
        muc_uri = FrozenURI(message.recipient.uri.user, message.recipient.uri.host)
        try:
            session = self.muc_session_manager.incoming[(muc_uri, message.sender.uri)]
        except KeyError:
            # Ignore groupchat messages if there was no session created
            pass
        else:
            session.channel.send(message)

    def _NH_XMPPMucGotPresenceAvailability(self, notification):
        stanza = notification.data.presence_stanza
        if not stanza.sender.uri.resource:
            return
        muc_uri = FrozenURI(stanza.recipient.uri.user, stanza.recipient.uri.host)
        try:
            session = self.muc_session_manager.incoming[(muc_uri, stanza.sender.uri)]
        except KeyError:
            if stanza.available:
                notification.center.post_notification('XMPPGotMucJoinRequest', sender=self, data=NotificationData(stanza=stanza))
            else:
                notification.center.post_notification('XMPPGotMucLeaveRequest', sender=self, data=NotificationData(stanza=stanza))
        else:
            session.channel.send(stanza)

    def _NH_XMPPMucGotInvitation(self, notification):
        invitation = notification.data.invitation
        data = NotificationData(sender=invitation.sender, recipient=invitation.recipient, participant=invitation.invited_user)
        notification.center.post_notification('XMPPGotMucAddParticipantRequest', sender=self, data=data)

    # Jingle

    def _NH_XMPPGotJingleSessionInitiate(self, notification):
        stanza = notification.data.stanza
        try:
            self.jingle_session_manager.sessions[stanza.jingle.sid]
        except KeyError:
            session = JingleSession(notification.data.protocol)
            session.init_incoming(stanza)
            session.send_ring_indication()

    def _NH_XMPPGotJingleSessionTerminate(self, notification):
        stanza = notification.data.stanza
        try:
            session = self.jingle_session_manager.sessions[stanza.jingle.sid]
        except KeyError:
            return
        session.handle_notification(notification)

    def _NH_XMPPGotJingleSessionInfo(self, notification):
        stanza = notification.data.stanza
        try:
            session = self.jingle_session_manager.sessions[stanza.jingle.sid]
        except KeyError:
            return
        session.handle_notification(notification)

    def _NH_XMPPGotJingleSessionAccept(self, notification):
        stanza = notification.data.stanza
        try:
            session = self.jingle_session_manager.sessions[stanza.jingle.sid]
        except KeyError:
            return
        session.handle_notification(notification)

    def _NH_XMPPGotJingleDescriptionInfo(self, notification):
        stanza = notification.data.stanza
        try:
            session = self.jingle_session_manager.sessions[stanza.jingle.sid]
        except KeyError:
            return
        session.handle_notification(notification)

    def _NH_XMPPGotJingleTransportInfo(self, notification):
        stanza = notification.data.stanza
        try:
            session = self.jingle_session_manager.sessions[stanza.jingle.sid]
        except KeyError:
            return
        session.handle_notification(notification)