Page MenuHomePhabricator

No OneTemporary

diff --git a/config.ini.sample b/config.ini.sample
index 26aaf6d..631b8ae 100644
--- a/config.ini.sample
+++ b/config.ini.sample
@@ -1,84 +1,82 @@
; SylkServer configuration file
[Server]
; The following settings are the default used by the software, uncomment
; them only if you want to make changes
; default_application = conference
; Map user part of the Request URI to a specific application
; application_map = 123:conference,test:irc-conference
; trace_dir = /var/log/sylkserver
; trace_sip = False
; trace_msrp = False
; trace_notifications = False
; TLS can be used for encryption of SIP signaling and MSRP media. TLS is
; disabled by default. To enable TLS, you must have a valid X.509
; certificate and configure it below, then set the local_tls_port in the SIP
; section and use_tls in MSRP section
; The X.509 Certificate Authorities file
; ca_file = /etc/sylkserver/tls/ca.crt
; The file containing X.509 certificate and private key in unencrypted format
; certificate = /etc/sylkserver/tls/sylkserver.crt
; verify_server = False
[SIP]
; SIP transport settings
; IP address used for SIP signaling; empty string or any means listen on interface used
; by the default route
; local_ip =
; Ports used for SIP transports, if not set to any value the transport will be disabled
; local_udp_port = 5060
; local_tcp_port = 5060
; local_tls_port =
; If set all outbound SIP requests will be sent through this SIP proxy
; outbound_proxy =
; A comma-separated list of hosts or networks to trust.
; The elements can be an IP address in CIDR format, a
; hostname or an IP address (in the latter 2 a mask of 32
; is assumed), or the special keywords 'any' and 'none'
; (being equivalent to 0.0.0.0/0 and 0.0.0.0/32
; respectively). It defaults to 'any'.
; trusted_peers =
[MSRP]
; MSRP transport settings
; Indicate if ACM should be offered. If set to true (default) the server will offer 'actpass'
-; for outbound sessions, alowing clients to connect to the server without using a MSRP relay
+; for outbound sessions
; use_acm = True
-; By default MSRP media is using TCP, to enable TLS you must configure a
-; X.509 certificate in the server section and enable it here
; use_tls = False
[RTP]
; RTP transport settings
; Allowed codec list, valid values: G722, speex, PCMU, PCMA, iLBC, GSM
; audio_codecs = G722,speex,PCMU,PCMA
; Port range used for RTP
; port_range = 50000:50500
; SRTP valid values: disabled, mandatory, optional
; srtp_encryption = optional
; RTP stream timeout, session will be disconnected after this value
; timeout = 30
diff --git a/sylk/configuration/__init__.py b/sylk/configuration/__init__.py
index 1e478b7..d175e93 100644
--- a/sylk/configuration/__init__.py
+++ b/sylk/configuration/__init__.py
@@ -1,70 +1,69 @@
# Copyright (C) 2010-2011 AG Projects. See LICENSE for details.
#
from application.configuration import ConfigSection, ConfigSetting
from application.configuration.datatypes import NetworkRangeList, StringList
from application.system import host
from sipsimple.configuration.datatypes import NonNegativeInteger, SRTPEncryption
from sylk import configuration_filename
from sylk.configuration.datatypes import AudioCodecs, IPAddress, Port, PortRange, SIPProxyAddress
from sylk.tls import Certificate, PrivateKey
class ServerConfig(ConfigSection):
__cfgfile__ = configuration_filename
__section__ = 'Server'
ca_file = ConfigSetting(type=str, value='/etc/sylkserver/tls/ca.crt')
certificate = ConfigSetting(type=str, value='/etc/sylkserver/tls/sylkserver.crt')
verify_server = False
default_application = 'conference'
application_map = ConfigSetting(type=StringList, value='')
trace_dir = ConfigSetting(type=str, value='/var/log/sylkserver')
trace_sip = False
trace_msrp = False
trace_notifications = False
class SIPConfig(ConfigSection):
__cfgfile__ = configuration_filename
__section__ = 'SIP'
local_ip = ConfigSetting(type=IPAddress, value=host.default_ip)
local_udp_port = ConfigSetting(type=Port, value=5060)
local_tcp_port = ConfigSetting(type=Port, value=5060)
local_tls_port = ConfigSetting(type=Port, value=None)
outbound_proxy = ConfigSetting(type=SIPProxyAddress, value=None)
trusted_peers = ConfigSetting(type=NetworkRangeList, value=NetworkRangeList('any'))
class MSRPConfig(ConfigSection):
__cfgfile__ = configuration_filename
__section__ = 'MSRP'
- use_acm = True
use_tls = False
class RTPConfig(ConfigSection):
__cfgfile__ = configuration_filename
__section__ = 'RTP'
audio_codecs = ConfigSetting(type=AudioCodecs, value=None)
port_range = ConfigSetting(type=PortRange, value=PortRange('50000:50500'))
srtp_encryption = ConfigSetting(type=SRTPEncryption, value='optional')
timeout = ConfigSetting(type=NonNegativeInteger, value=30)
class ThorNodeConfig(ConfigSection):
__cfgfile__ = configuration_filename
__section__ = 'ThorNetwork'
enabled = False
domain = "sipthor.net"
multiply = 1000
certificate = ConfigSetting(type=Certificate, value=None)
private_key = ConfigSetting(type=PrivateKey, value=None)
ca = ConfigSetting(type=Certificate, value=None)
diff --git a/sylk/configuration/settings.py b/sylk/configuration/settings.py
index 4588905..2cd8e0c 100644
--- a/sylk/configuration/settings.py
+++ b/sylk/configuration/settings.py
@@ -1,121 +1,122 @@
# Copyright (C) 2010-2011 AG Projects. See LICENSE for details.
#
"""
SIP SIMPLE SDK settings extensions.
"""
__all__ = ['AccountExtension', 'BonjourAccountExtension', 'SylkServerSettingsExtension']
import os
from sipsimple.account import MSRPSettings as AccountMSRPSettings, NATTraversalSettings as AccountNATTraversalSettings
from sipsimple.account import RTPSettings as AccountRTPSettings, SIPSettings as AccountSIPSettings, TLSSettings as AccountTLSSettings
from sipsimple.configuration import CorrelatedSetting, Setting, SettingsObjectExtension
-from sipsimple.configuration.datatypes import MSRPTransport, NonNegativeInteger, Path, PortRange, SampleRate, SIPTransportList, SRTPEncryption
+from sipsimple.configuration.datatypes import MSRPConnectionModel, MSRPTransport, NonNegativeInteger, Path, PortRange, SampleRate, SIPTransportList, SRTPEncryption
from sipsimple.configuration.settings import AudioSettings, LogsSettings, RTPSettings, SIPSettings, TLSSettings
from sylk import __version__ as server_version
from sylk.configuration import ServerConfig, SIPConfig, MSRPConfig, RTPConfig
from sylk.configuration.datatypes import AudioCodecs, Port, SIPProxyAddress
# Account settings extensions
msrp_transport = 'tls' if MSRPConfig.use_tls else 'tcp'
class AccountMSRPSettingsExtension(AccountMSRPSettings):
transport = Setting(type=MSRPTransport, default=msrp_transport)
+ connection_model = Setting(type=MSRPConnectionModel, default='acm')
class AccountNATTraversalSettingsExtension(AccountNATTraversalSettings):
use_msrp_relay_for_inbound = Setting(type=bool, default=False)
use_msrp_relay_for_outbound = Setting(type=bool, default=False)
class AccountRTPSettingsExtension(AccountRTPSettings):
audio_codec_list = Setting(type=AudioCodecs, default=RTPConfig.audio_codecs, nillable=True)
srtp_encryption = Setting(type=SRTPEncryption, default=RTPConfig.srtp_encryption)
use_srtp_without_tls = Setting(type=bool, default=True)
class AccountSIPSettingsExtension(AccountSIPSettings):
register = Setting(type=bool, default=False)
outbound_proxy = Setting(type=SIPProxyAddress, default=SIPConfig.outbound_proxy, nillable=True)
tls_certificate = Path(ServerConfig.certificate) if ServerConfig.certificate and os.path.isfile(ServerConfig.certificate) else None
class AccountTLSSettingsExtension(AccountTLSSettings):
certificate = Setting(type=Path, default=tls_certificate, nillable=True)
verify_server = Setting(type=bool, default=ServerConfig.verify_server)
class AccountExtension(SettingsObjectExtension):
enabled = Setting(type=bool, default=True)
msrp = AccountMSRPSettingsExtension
nat_traversal = AccountNATTraversalSettingsExtension
rtp = AccountRTPSettingsExtension
sip = AccountSIPSettingsExtension
tls = AccountTLSSettingsExtension
class BonjourAccountExtension(SettingsObjectExtension):
enabled = Setting(type=bool, default=False)
# General settings extensions
class AudioSettingsExtension(AudioSettings):
input_device = Setting(type=str, default=None, nillable=True)
output_device = Setting(type=str, default=None, nillable=True)
sample_rate = Setting(type=SampleRate, default=16000)
log_directory = Path(ServerConfig.trace_dir) if ServerConfig.trace_dir else None
class LogsSettingsExtension(LogsSettings):
directory = Setting(type=Path, default=log_directory)
trace_sip = Setting(type=bool, default=ServerConfig.trace_sip)
trace_msrp = Setting(type=bool, default=ServerConfig.trace_msrp)
trace_pjsip = Setting(type=bool, default=False)
trace_notifications = Setting(type=bool, default=ServerConfig.trace_notifications)
class RTPSettingsExtension(RTPSettings):
port_range = Setting(type=PortRange, default=PortRange(RTPConfig.port_range.start, RTPConfig.port_range.end))
timeout = Setting(type=NonNegativeInteger, default=RTPConfig.timeout)
def sip_port_validator(port, sibling_port):
if port == sibling_port != 0:
raise ValueError("the TCP and TLS ports must be different")
transport_list = []
if SIPConfig.local_udp_port:
transport_list.append('udp')
if SIPConfig.local_tcp_port:
transport_list.append('tcp')
if SIPConfig.local_tls_port:
transport_list.append('tls')
udp_port = SIPConfig.local_udp_port or 0
tcp_port = SIPConfig.local_tcp_port or 0
tls_port = SIPConfig.local_tls_port or 0
class SIPSettingsExtension(SIPSettings):
udp_port = Setting(type=Port, default=udp_port)
tcp_port = CorrelatedSetting(type=Port, sibling='tls_port', validator=sip_port_validator, default=tcp_port)
tls_port = CorrelatedSetting(type=Port, sibling='tcp_port', validator=sip_port_validator, default=tls_port)
transport_list = Setting(type=SIPTransportList, default=transport_list)
ca_list = Path(ServerConfig.ca_file) if ServerConfig.ca_file and os.path.isfile(ServerConfig.ca_file) else None
class TLSSettingsExtension(TLSSettings):
ca_list = Setting(type=Path, default=ca_list, nillable=True)
class SylkServerSettingsExtension(SettingsObjectExtension):
user_agent = Setting(type=str, default='SylkServer-%s' % server_version)
audio = AudioSettingsExtension
logs = LogsSettingsExtension
rtp = RTPSettingsExtension
sip = SIPSettingsExtension
tls = TLSSettingsExtension
diff --git a/sylk/extensions.py b/sylk/extensions.py
index 6991ba7..bd28944 100644
--- a/sylk/extensions.py
+++ b/sylk/extensions.py
@@ -1,134 +1,81 @@
# Copyright (C) 2010-2011 AG Projects. See LICENSE for details.
#
import random
from datetime import datetime
-from application.notification import NotificationCenter
-from eventlet import api
-from msrplib.connect import get_acceptor, get_connector
from msrplib.protocol import URI
from msrplib.session import contains_mime_type
from sipsimple.account import AccountManager
from sipsimple.core import SDPAttribute
from sipsimple.payloads.iscomposing import IsComposingMessage, State, LastActive, Refresh, ContentType
from sipsimple.streams import MediaStreamRegistry
from sipsimple.streams.applications.chat import CPIMMessage
-from sipsimple.streams.msrp import ChatStream as _ChatStream, ChatStreamError, MSRPStreamBase, MSRPStreamError, NotificationProxyLogger
-from sipsimple.threading.green import run_in_green_thread
-from sipsimple.util import TimestampedNotificationData
-from twisted.python.failure import Failure
+from sipsimple.streams.msrp import ChatStream as _ChatStream, ChatStreamError, MSRPStreamBase
-from sylk.configuration import SIPConfig, MSRPConfig
+from sylk.configuration import SIPConfig
# We need to match on the only account that will be available
def _always_find_default_account(self, contact_uri):
return self.default_account
AccountManager.find_account = _always_find_default_account
# We need to be able to set the local identity in the message CPIM envelope
# so that messages appear to be coming from the users themselves, instead of
# just seeying the server identity
registry = MediaStreamRegistry()
for stream_type in registry.stream_types[:]:
if stream_type is _ChatStream:
registry.stream_types.remove(stream_type)
break
del registry
class ChatStream(_ChatStream):
accept_types = ['message/cpim']
accept_wrapped_types = ['*']
chatroom_capabilities = ['private-messages']
+ @property
+ def local_uri(self):
+ return URI(host=SIPConfig.local_ip, port=0, use_tls=self.transport=='tls', credentials=self.account.tls_credentials)
+
def _create_local_media(self, uri_path):
local_media = MSRPStreamBase._create_local_media(self, uri_path)
if self.session.local_focus and self.chatroom_capabilities:
local_media.attributes.append(SDPAttribute('chatroom', ' '.join(self.chatroom_capabilities)))
return local_media
def send_message(self, content, content_type='text/plain', local_identity=None, recipients=None, courtesy_recipients=None, subject=None, timestamp=None, required=None, additional_headers=None):
if self.direction=='recvonly':
raise ChatStreamError('Cannot send message on recvonly stream')
message_id = '%x' % random.getrandbits(64)
if not contains_mime_type(self.accept_wrapped_types, content_type):
raise ChatStreamError('Invalid content_type for outgoing message: %r' % content_type)
if not recipients:
recipients = [self.remote_identity]
if timestamp is None:
timestamp = datetime.now()
# Only use CPIM, it's the only type we accept
msg = CPIMMessage(content, content_type, sender=local_identity or self.local_identity, recipients=recipients, courtesy_recipients=courtesy_recipients,
subject=subject, timestamp=timestamp, required=required, additional_headers=additional_headers)
self._enqueue_message(message_id, str(msg), 'message/cpim', failure_report='yes', success_report='yes', notify_progress=True)
return message_id
def send_composing_indication(self, state, refresh, last_active=None, recipients=None, local_identity=None):
if self.direction == 'recvonly':
raise ChatStreamError('Cannot send message on recvonly stream')
if state not in ('active', 'idle'):
raise ValueError('Invalid value for composing indication state')
message_id = '%x' % random.getrandbits(64)
content = IsComposingMessage(state=State(state), refresh=Refresh(refresh), last_active=LastActive(last_active or datetime.now()), content_type=ContentType('text')).toxml()
if recipients is None:
recipients = [self.remote_identity]
# Only use CPIM, it's the only type we accept
msg = CPIMMessage(content, IsComposingMessage.content_type, sender=local_identity or self.local_identity, recipients=recipients, timestamp=datetime.now())
self._enqueue_message(message_id, str(msg), 'message/cpim', failure_report='partial', success_report='no')
return message_id
-# Patch MediaStreamBase initialize method
-# - There is no need for relay support
-# - We need to choose the outbound IP address
-@run_in_green_thread
-def _initialize(self, session, direction):
- self.greenlet = api.getcurrent()
- notification_center = NotificationCenter()
- notification_center.add_observer(self, sender=self)
- try:
- self.session = session
- outgoing = direction=='outgoing'
- self.transport = self.account.msrp.transport
- if not outgoing and self.transport == 'tls' and None in (self.account.tls_credentials.cert, self.account.tls_credentials.key):
- raise MSRPStreamError("Cannot accept MSRP connection without a TLS certificate")
- logger = NotificationProxyLogger()
- local_uri = URI(host=SIPConfig.local_ip,
- port=0,
- use_tls=self.transport=='tls',
- credentials=self.account.tls_credentials)
- if outgoing:
- if MSRPConfig.use_acm:
- # We start the transport as passive, because we expect the other end to become active. -Saul
- self.msrp_connector = get_acceptor(relay=None, use_acm=True, logger=logger)
- self.local_role = 'actpass'
- else:
- self.msrp_connector = get_connector(relay=None, use_acm=True, logger=logger)
- self.local_role = 'active'
- else:
- if self.remote_role in ('actpass', 'active'):
- self.msrp_connector = get_acceptor(relay=None, use_acm=True, logger=logger)
- self.local_role = 'passive'
- else:
- # Remote role is passive. Not allowed by the draft but play nice for interoperability. -Saul
- self.msrp_connector = get_connector(relay=None, use_acm=True, logger=logger)
- self.local_role = 'active'
- full_local_path = self.msrp_connector.prepare(local_uri)
- self.local_media = self._create_local_media(full_local_path)
- except api.GreenletExit:
- raise
- except Exception, ex:
- ndata = TimestampedNotificationData(context='initialize', failure=Failure(), reason=str(ex))
- notification_center.post_notification('MediaStreamDidFail', self, ndata)
- else:
- notification_center.post_notification('MediaStreamDidInitialize', self, data=TimestampedNotificationData())
- finally:
- if self.msrp_session is None and self.msrp is None and self.msrp_connector is None:
- notification_center.remove_observer(self, sender=self)
- self.greenlet = None
-
-MSRPStreamBase.initialize = _initialize
-

File Metadata

Mime Type
text/x-diff
Expires
Sat, Feb 1, 11:30 AM (1 d, 2 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3489299
Default Alt Text
(18 KB)

Event Timeline