Beispiel #1
0
 def _NH_DNSLookupDidSucceed(self, notification):
     notification_center = NotificationCenter()
     notification_center.remove_observer(self, sender=notification.sender)
     account = DefaultAccount()
     conference_application = ConferenceApplication()
     try:
         room = conference_application.get_room(self.room_uri)
     except RoomNotFoundError:
         log.info('Room %s - failed to add %s' %
                  (self.room_uri_str, self.refer_to_uri))
         self._refer_request.end(500)
         return
     active_media = set(room.active_media).intersection(('audio', 'chat'))
     if not active_media:
         log.info('Room %s - failed to add %s' %
                  (self.room_uri_str, self.refer_to_uri))
         self._refer_request.end(500)
         return
     for stream_type in active_media:
         self.streams.append(MediaStreamRegistry.get(stream_type)())
     self.session = Session(account)
     notification_center.add_observer(self, sender=self.session)
     original_from_header = self._refer_headers.get('From')
     if original_from_header.display_name:
         original_identity = "%s <%s@%s>" % (
             original_from_header.display_name,
             original_from_header.uri.user, original_from_header.uri.host)
     else:
         original_identity = "%s@%s" % (original_from_header.uri.user,
                                        original_from_header.uri.host)
     from_header = FromHeader(SIPURI.new(self.room_uri), u'Conference Call')
     to_header = ToHeader(self.refer_to_uri)
     extra_headers = []
     if self._refer_headers.get('Referred-By', None) is not None:
         extra_headers.append(
             Header.new(self._refer_headers.get('Referred-By')))
     else:
         extra_headers.append(
             Header('Referred-By', str(original_from_header.uri)))
     if ThorNodeConfig.enabled:
         extra_headers.append(Header('Thor-Scope', 'conference-invitation'))
     extra_headers.append(
         Header('X-Originator-From', str(original_from_header.uri)))
     extra_headers.append(
         SubjectHeader(u'Join conference request from %s' %
                       original_identity))
     route = notification.data.result[0]
     self.session.connect(from_header,
                          to_header,
                          route=route,
                          streams=self.streams,
                          is_focus=True,
                          extra_headers=extra_headers)
Beispiel #2
0
    def start(self):
        notification_center = NotificationCenter()
        self.greenlet = api.getcurrent()
        settings = SIPSimpleSettings()
        account = AccountManager().sylkserver_account
        if account.sip.outbound_proxy is not None:
            uri = SIPURI(
                host=account.sip.outbound_proxy.host,
                port=account.sip.outbound_proxy.port,
                parameters={'transport': account.sip.outbound_proxy.transport})
        else:
            uri = self.destination_uri
        lookup = DNSLookup()
        try:
            routes = lookup.lookup_sip_proxy(
                uri, settings.sip.transport_list).wait()
        except DNSLookupError:
            notification_center.post_notification(
                'OutgoingFileTransferHandlerDidFail', sender=self)
            return

        self.session = Session(account)
        self.stream = FileTransferStream(self.file_selector, 'sendonly')
        notification_center.add_observer(self, sender=self.session)
        notification_center.add_observer(self, sender=self.stream)
        from_header = FromHeader(self.sender_uri, u'SIPStache File Transfer')
        to_header = ToHeader(self.destination_uri)
        transport = routes[0].transport
        parameters = {} if transport == 'udp' else {'transport': transport}
        contact_header = ContactHeader(
            SIPURI(user=self.sender_uri.user,
                   host=SIPConfig.local_ip.normalized,
                   port=getattr(Engine(), '%s_port' % transport),
                   parameters=parameters))
        extra_headers = []
        if ThorNodeConfig.enabled:
            extra_headers.append(Header('Thor-Scope', 'sipstache-file'))
        extra_headers.append(
            Header('X-Originator-From', str(self.destination_uri)))
        self.session.connect(from_header,
                             to_header,
                             contact_header=contact_header,
                             routes=routes,
                             streams=[self.stream],
                             is_focus=False,
                             extra_headers=extra_headers)
        notification_center.post_notification(
            'OutgoingFileTransferHandlerDidStart', sender=self)
Beispiel #3
0
    def sendReplicationMessage(self,
                               response_code,
                               content,
                               content_type="message/cpim",
                               timestamp=None):
        timestamp = timestamp or ISOTimestamp.now()
        # Lookup routes
        if self.account.sip.outbound_proxy is not None:
            uri = SIPURI(host=self.account.sip.outbound_proxy.host,
                         port=self.account.sip.outbound_proxy.port,
                         parameters={
                             'transport':
                             self.account.sip.outbound_proxy.transport
                         })
        else:
            uri = SIPURI(host=self.account.id.domain)

        route = None
        if self.last_route is None:
            lookup = DNSLookup()
            settings = SIPSimpleSettings()
            try:
                routes = lookup.lookup_sip_proxy(
                    uri, settings.sip.transport_list).wait()
            except DNSLookupError:
                pass
            else:
                route = routes[0]
        else:
            route = self.last_route

        if route:
            extra_headers = [
                Header("X-Offline-Storage", "no"),
                Header("X-Replication-Code", str(response_code)),
                Header("X-Replication-Timestamp", str(ISOTimestamp.now()))
            ]
            message_request = Message(FromHeader(self.account.uri,
                                                 self.account.display_name),
                                      ToHeader(self.account.uri),
                                      RouteHeader(route.uri),
                                      content_type,
                                      content,
                                      credentials=self.account.credentials,
                                      extra_headers=extra_headers)
            message_request.send(
                15 if content_type != "application/im-iscomposing+xml" else 5)
 def sendReplicationMessage(self,
                            response_code,
                            text,
                            content_type="message/cpim",
                            timestamp=None):
     timestamp = timestamp or datetime.datetime.now(tzlocal())
     # Lookup routes
     if self.account.sip.outbound_proxy is not None:
         uri = SIPURI(host=self.account.sip.outbound_proxy.host,
                      port=self.account.sip.outbound_proxy.port,
                      parameters={
                          'transport':
                          self.account.sip.outbound_proxy.transport
                      })
     else:
         uri = SIPURI(host=self.account.id.domain)
     lookup = DNSLookup()
     settings = SIPSimpleSettings()
     try:
         routes = lookup.lookup_sip_proxy(
             uri, settings.sip.transport_list).wait()
     except DNSLookupError:
         pass
     else:
         utf8_encode = content_type not in (
             'application/im-iscomposing+xml', 'message/cpim')
         extra_headers = [
             Header("X-Offline-Storage", "no"),
             Header("X-Replication-Code", str(response_code)),
             Header("X-Replication-Timestamp",
                    str(Timestamp(datetime.datetime.now())))
         ]
         message_request = Message(
             FromHeader(self.account.uri, self.account.display_name),
             ToHeader(self.account.uri),
             RouteHeader(routes[0].get_uri()),
             content_type,
             text.encode('utf-8') if utf8_encode else text,
             credentials=self.account.credentials,
             extra_headers=extra_headers)
         message_request.send(
             15 if content_type != "application/im-iscomposing+xml" else 5)
Beispiel #5
0
 def send_publish(self, uri, body):
     if self.outbound_proxy is None:
         return
     uri = self.sip_prefix_re.sub('', uri)
     publication = Publication(
         FromHeader(SIPURI(uri)),
         "xcap-diff",
         "application/xcap-diff+xml",
         duration=0,
         extra_headers=[Header('Thor-Scope', 'publish-xcap')])
     NotificationCenter().add_observer(self, sender=publication)
     route_header = RouteHeader(
         SIPURI(host=self.outbound_proxy.host,
                port=self.outbound_proxy.port,
                parameters=dict(transport=self.outbound_proxy.transport)))
     publication.publish(body, route_header, timeout=5)
Beispiel #6
0
 def send_publish(self, uri, body):
     uri = re.sub("^(sip:|sips:)", "", uri)
     destination_node = self.provisioning.lookup(uri)
     if destination_node is not None:
         # TODO: add configuration settings for SIP transport. -Saul
         publication = Publication(
             FromHeader(SIPURI(uri)),
             "xcap-diff",
             "application/xcap-diff+xml",
             duration=0,
             extra_headers=[Header('Thor-Scope', 'publish-xcap')])
         NotificationCenter().add_observer(self, sender=publication)
         route_header = RouteHeader(
             SIPURI(host=str(destination_node),
                    port='5060',
                    parameters=dict(transport='udp')))
         publication.publish(body, route_header, timeout=5)
    def _CH_register(self, command):
        notification_center = NotificationCenter()
        settings = SIPSimpleSettings()

        if self._registration_timer is not None and self._registration_timer.active(
        ):
            self._registration_timer.cancel()
        self._registration_timer = None

        # Initialize the registration
        if self._registration is None:
            duration = command.refresh_interval or self.account.sip.register_interval
            self._registration = Registration(
                FromHeader(self.account.uri, self.account.display_name),
                credentials=self.account.credentials,
                duration=duration,
                extra_headers=[Header('Supported', 'gruu')])
            notification_center.add_observer(self, sender=self._registration)
            notification_center.post_notification('SIPAccountWillRegister',
                                                  sender=self.account)
        else:
            notification_center.post_notification(
                'SIPAccountRegistrationWillRefresh', sender=self.account)

        try:
            # Lookup routes
            if self.account.sip.outbound_proxy is not None and self.account.sip.outbound_proxy.transport in settings.sip.transport_list:
                uri = SIPURI(host=self.account.sip.outbound_proxy.host,
                             port=self.account.sip.outbound_proxy.port,
                             parameters={
                                 'transport':
                                 self.account.sip.outbound_proxy.transport
                             })
            else:
                uri = SIPURI(host=self.account.id.domain)
            lookup = DNSLookup()
            try:
                routes = lookup.lookup_sip_proxy(
                    uri, settings.sip.transport_list).wait()
            except DNSLookupError, e:
                retry_after = random.uniform(self._dns_wait,
                                             2 * self._dns_wait)
                self._dns_wait = limit(2 * self._dns_wait, max=30)
                raise RegistrationError('DNS lookup failed: %s' % e,
                                        retry_after=retry_after)
            else:
Beispiel #8
0
 def _NH_DNSLookupDidSucceed(self, notification):
     notification_center = NotificationCenter()
     notification_center.remove_observer(self, sender=notification.sender)
     account = DefaultAccount()
     conference_application = ConferenceApplication()
     try:
         room = conference_application.get_room(self.room_uri)
     except RoomNotFoundError:
         log.msg("Room %s - failed to add %s" % (self.room_uri_str, self.refer_to_uri))
         self._refer_request.end(500)
         return
     active_media = set(room.active_media).intersection(("audio", "chat"))
     if not active_media:
         log.msg("Room %s - failed to add %s" % (self.room_uri_str, self.refer_to_uri))
         self._refer_request.end(500)
         return
     registry = MediaStreamRegistry()
     for stream_type in active_media:
         self.streams.append(registry.get(stream_type)())
     self.session = Session(account)
     notification_center.add_observer(self, sender=self.session)
     original_from_header = self._refer_headers.get("From")
     if original_from_header.display_name:
         original_identity = "%s <%s@%s>" % (
             original_from_header.display_name,
             original_from_header.uri.user,
             original_from_header.uri.host,
         )
     else:
         original_identity = "%s@%s" % (original_from_header.uri.user, original_from_header.uri.host)
     from_header = FromHeader(SIPURI.new(self.room_uri), u"Conference Call")
     to_header = ToHeader(self.refer_to_uri)
     extra_headers = []
     if self._refer_headers.get("Referred-By", None) is not None:
         extra_headers.append(Header.new(self._refer_headers.get("Referred-By")))
     else:
         extra_headers.append(Header("Referred-By", str(original_from_header.uri)))
     if ThorNodeConfig.enabled:
         extra_headers.append(Header("Thor-Scope", "conference-invitation"))
     extra_headers.append(Header("X-Originator-From", str(original_from_header.uri)))
     extra_headers.append(SubjectHeader(u"Join conference request from %s" % original_identity))
     route = notification.data.result[0]
     self.session.connect(
         from_header, to_header, route=route, streams=self.streams, is_focus=True, extra_headers=extra_headers
     )
    def _CH_register(self, command):
        notification_center = NotificationCenter()
        settings = SIPSimpleSettings()

        if self._registration_timer is not None and self._registration_timer.active(
        ):
            self._registration_timer.cancel()
        self._registration_timer = None

        # Initialize the registration
        if self._registration is None:
            duration = command.refresh_interval or self.account.sip.register_interval
            self._registration = Registration(
                FromHeader(self.account.uri, self.account.display_name),
                credentials=self.account.credentials,
                duration=duration,
                extra_headers=[Header('Supported', 'gruu')])
            notification_center.add_observer(self, sender=self._registration)
            notification_center.post_notification('SIPAccountWillRegister',
                                                  sender=self.account)
        else:
            notification_center.post_notification(
                'SIPAccountRegistrationWillRefresh', sender=self.account)

        try:
            # Lookup routes
            if self.account.sip.outbound_proxy is not None and self.account.sip.outbound_proxy.transport in settings.sip.transport_list:
                uri = SIPURI(host=self.account.sip.outbound_proxy.host,
                             port=self.account.sip.outbound_proxy.port,
                             parameters={
                                 'transport':
                                 self.account.sip.outbound_proxy.transport
                             })
            else:
                uri = SIPURI(host=self.account.id.domain)
            lookup = DNSLookup()
            try:
                routes = lookup.lookup_sip_proxy(
                    uri, settings.sip.transport_list).wait()
            except DNSLookupError as e:
                retry_after = random.uniform(self._dns_wait,
                                             2 * self._dns_wait)
                self._dns_wait = limit(2 * self._dns_wait, max=30)
                raise RegistrationError('DNS lookup failed: %s' % e,
                                        retry_after=retry_after)
            else:
                self._dns_wait = 1

            # Register by trying each route in turn
            register_timeout = time() + 30
            for route in routes:
                remaining_time = register_timeout - time()
                if remaining_time > 0:
                    try:
                        contact_uri = self.account.contact[NoGRUU, route]
                    except KeyError:
                        continue
                    contact_header = ContactHeader(contact_uri)
                    contact_header.parameters[
                        '+sip.instance'] = '"<%s>"' % settings.instance_id
                    if self.account.nat_traversal.use_ice:
                        contact_header.parameters['+sip.ice'] = None
                    route_header = RouteHeader(route.uri)
                    try:
                        self._registration.register(contact_header,
                                                    route_header,
                                                    timeout=limit(
                                                        remaining_time,
                                                        min=1,
                                                        max=10))
                    except SIPCoreError:
                        raise RegistrationError('Internal error',
                                                retry_after=5)
                    try:
                        while True:
                            notification = self._data_channel.wait()
                            if notification.name == 'SIPRegistrationDidSucceed':
                                break
                            if notification.name == 'SIPRegistrationDidEnd':
                                raise RegistrationError(
                                    'Registration expired', retry_after=0
                                )  # registration expired while we were trying to re-register
                    except SIPRegistrationDidFail as e:
                        notification_data = NotificationData(
                            code=e.data.code,
                            reason=e.data.reason,
                            registration=self._registration,
                            registrar=route)
                        notification_center.post_notification(
                            'SIPAccountRegistrationGotAnswer',
                            sender=self.account,
                            data=notification_data)
                        if e.data.code == 401:
                            # Authentication failed, so retry the registration in some time
                            raise RegistrationError('Authentication failed',
                                                    retry_after=random.uniform(
                                                        60, 120))
                        elif e.data.code == 423:
                            # Get the value of the Min-Expires header
                            if e.data.min_expires is not None and e.data.min_expires > self.account.sip.register_interval:
                                refresh_interval = e.data.min_expires
                            else:
                                refresh_interval = None
                            raise RegistrationError(
                                'Interval too short',
                                retry_after=random.uniform(60, 120),
                                refresh_interval=refresh_interval)
                        else:
                            # Otherwise just try the next route
                            continue
                    else:
                        notification_data = NotificationData(
                            code=notification.data.code,
                            reason=notification.data.reason,
                            registration=self._registration,
                            registrar=route)
                        notification_center.post_notification(
                            'SIPAccountRegistrationGotAnswer',
                            sender=self.account,
                            data=notification_data)
                        self.registered = True
                        # Save GRUU
                        try:
                            header = next(
                                header for header in
                                notification.data.contact_header_list
                                if header.parameters.get('+sip.instance', '').
                                strip('"<>') == settings.instance_id)
                        except StopIteration:
                            self.account.contact.public_gruu = None
                            self.account.contact.temporary_gruu = None
                        else:
                            public_gruu = header.parameters.get(
                                'pub-gruu', None)
                            temporary_gruu = header.parameters.get(
                                'temp-gruu', None)
                            try:
                                self.account.contact.public_gruu = SIPURI.parse(
                                    public_gruu.strip('"'))
                            except (AttributeError, SIPCoreError):
                                self.account.contact.public_gruu = None
                            try:
                                self.account.contact.temporary_gruu = SIPURI.parse(
                                    temporary_gruu.strip('"'))
                            except (AttributeError, SIPCoreError):
                                self.account.contact.temporary_gruu = None
                        notification_data = NotificationData(
                            contact_header=notification.data.contact_header,
                            contact_header_list=notification.data.
                            contact_header_list,
                            expires=notification.data.expires_in,
                            registrar=route)
                        notification_center.post_notification(
                            'SIPAccountRegistrationDidSucceed',
                            sender=self.account,
                            data=notification_data)
                        self._register_wait = 1
                        command.signal()
                        break
            else:
                # There are no more routes to try, reschedule the registration
                retry_after = random.uniform(self._register_wait,
                                             2 * self._register_wait)
                self._register_wait = limit(self._register_wait * 2, max=30)
                raise RegistrationError('No more routes to try',
                                        retry_after=retry_after)
        except RegistrationError as e:
            self.registered = False
            notification_center.remove_observer(self,
                                                sender=self._registration)
            notification_center.post_notification(
                'SIPAccountRegistrationDidFail',
                sender=self.account,
                data=NotificationData(error=e.error,
                                      retry_after=e.retry_after))

            def register():
                if self.active:
                    self._command_channel.send(
                        Command('register',
                                command.event,
                                refresh_interval=e.refresh_interval))
                self._registration_timer = None

            self._registration_timer = reactor.callLater(
                e.retry_after, register)
            self._registration = None
            self.account.contact.public_gruu = None
            self.account.contact.temporary_gruu = None
Beispiel #10
0
 def extra_headers(self):
     return [Header('Supported', 'eventlist')]