Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F7313338
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
13 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/sylk/configuration/__init__.py b/sylk/configuration/__init__.py
index 107cd1c..92830eb 100644
--- a/sylk/configuration/__init__.py
+++ b/sylk/configuration/__init__.py
@@ -1,55 +1,55 @@
# Copyright (C) 2010-2011 AG Projects. See LICENSE for details.
#
from application.configuration import ConfigSection, ConfigSetting
from application.configuration.datatypes import StringList
from application.system import host
-from sipsimple.configuration.datatypes import NonNegativeInteger, SIPProxyAddress, SRTPEncryption
+from sipsimple.configuration.datatypes import NonNegativeInteger, SRTPEncryption
from sylk import configuration_filename
-from sylk.configuration.datatypes import AudioCodecs, IPAddress, Port, PortRange
+from sylk.configuration.datatypes import AudioCodecs, IPAddress, Port, PortRange, SIPProxyAddress
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)
class MSRPConfig(ConfigSection):
__cfgfile__ = configuration_filename
__section__ = 'MSRP'
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)
diff --git a/sylk/configuration/datatypes.py b/sylk/configuration/datatypes.py
index a236317..0ad3edf 100644
--- a/sylk/configuration/datatypes.py
+++ b/sylk/configuration/datatypes.py
@@ -1,99 +1,144 @@
# Copyright (C) 2010-2011 AG Projects. See LICENSE for details.
#
import os
import re
import socket
import sys
-from sipsimple.configuration.datatypes import AudioCodecList
+from sipsimple.configuration.datatypes import AudioCodecList, Hostname, SIPTransport
from sipsimple.util import classproperty
class AudioCodecs(list):
def __new__(cls, value):
if isinstance(value, (tuple, list)):
return [str(x) for x in value if x in AudioCodecList.available_values] or None
elif isinstance(value, basestring):
if value.lower() in ('none', ''):
return None
return [x for x in re.split(r'\s*,\s*', value) if x in AudioCodecList.available_values] or None
else:
raise TypeError("value must be a string, list or tuple")
class IPAddress(str):
"""An IP address in quad dotted number notation"""
def __new__(cls, value):
if value == '0.0.0.0':
raise ValueError("%s is not allowed, please specify a specific IP address" % value)
else:
try:
socket.inet_aton(value)
except socket.error:
raise ValueError("invalid IP address: %r" % value)
except TypeError:
raise TypeError("value must be a string")
return str(value)
class ResourcePath(object):
def __init__(self, path):
self.path = os.path.normpath(str(path))
def __getstate__(self):
return unicode(self.path)
def __setstate__(self, state):
self.__init__(state)
@property
def normalized(self):
path = os.path.expanduser(self.path)
if os.path.isabs(path):
return os.path.realpath(path)
return os.path.realpath(os.path.join(self.resources_directory, path))
@classproperty
def resources_directory(cls):
binary_directory = os.path.dirname(os.path.realpath(sys.argv[0]))
if os.path.basename(binary_directory) == 'bin':
application_directory = os.path.dirname(binary_directory)
resources_component = 'share/sylkserver'
else:
application_directory = binary_directory
resources_component = 'resources'
return os.path.realpath(os.path.join(application_directory, resources_component))
def __eq__(self, other):
try:
return self.path == other.path
except AttributeError:
return False
def __hash__(self):
return hash(self.path)
def __repr__(self):
return '%s(%r)' % (self.__class__.__name__, self.path)
def __unicode__(self):
return unicode(self.path)
class Port(int):
def __new__(cls, value):
try:
value = int(value)
except ValueError:
return None
if not (0 <= value <= 65535):
raise ValueError("illegal port value: %s" % value)
return value
class PortRange(object):
"""A port range in the form start:end with start and end being even numbers in the [1024, 65536] range"""
def __init__(self, value):
self.start, self.end = [int(p) for p in value.split(':', 1)]
allowed = xrange(1024, 65537, 2)
if not (self.start in allowed and self.end in allowed and self.start < self.end):
raise ValueError("bad range: %r: ports must be even numbers in the range [1024, 65536] with start < end" % value)
+class SIPProxyAddress(object):
+ _description_re = re.compile(r"^(?P<host>(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})|([a-zA-Z0-9\-_]+(\.[a-zA-Z0-9\-_]+)*))(:(?P<port>\d+))?(;transport=(?P<transport>.+))?$")
+
+ def __new__(cls, description):
+ if not description:
+ return None
+ if not cls._description_re.match(description):
+ raise ValueError("illegal SIP proxy address: %s" % description)
+ return super(SIPProxyAddress, cls).__new__(cls)
+
+ def __init__(self, description):
+ match = self.__class__._description_re.match(description)
+ data = match.groupdict()
+ host = data.get('host')
+ port = data.get('port', None) or 5060
+ transport = data.get('transport', None) or 'udp'
+ self.host = Hostname(host)
+ self.port = Port(port)
+ if self.port == 0:
+ raise ValueError("illegal port value: 0")
+ self.transport = SIPTransport(transport)
+
+ def __getstate__(self):
+ return unicode(self)
+
+ def __setstate__(self, state):
+ if not self.__class__._description_re.match(state):
+ raise ValueError("illegal SIP proxy address: %s" % state)
+ self.__init__(state)
+
+ def __eq__(self, other):
+ try:
+ return (self.host, self.port, self.transport) == (other.host, other.port, other.transport)
+ except AttributeError:
+ return False
+
+ def __ne__(self, other):
+ return not self.__eq__(other)
+
+ def __hash__(self):
+ return hash((self.host, self.port, self.transport))
+
+ def __unicode__(self):
+ return u'%s:%d;transport=%s' % (self.host, self.port, self.transport)
+
diff --git a/sylk/configuration/settings.py b/sylk/configuration/settings.py
index 9fd5bf7..7e4396c 100644
--- a/sylk/configuration/settings.py
+++ b/sylk/configuration/settings.py
@@ -1,123 +1,121 @@
# 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 AudioCodecList, MSRPTransport, NonNegativeInteger, Path, Port, PortRange, SampleRate, SIPProxyAddress, SIPTransportList, SRTPEncryption
+from sipsimple.configuration.datatypes import AudioCodecList, MSRPTransport, NonNegativeInteger, Path, Port, 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 SIPProxyAddress
# Account settings extensions
msrp_transport = 'tls' if MSRPConfig.use_tls else 'tcp'
class AccountMSRPSettingsExtension(AccountMSRPSettings):
transport = Setting(type=MSRPTransport, default=msrp_transport)
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=AudioCodecList, 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
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, Feb 1, 11:40 AM (1 d, 2 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3489310
Default Alt Text
(13 KB)
Attached To
Mode
rSYLK SylkServer
Attached
Detach File
Event Timeline
Log In to Comment