oversip_p 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/AUTHORS +22 -0
- data/LICENSE +25 -0
- data/README.md +43 -0
- data/Rakefile +54 -0
- data/bin/oversip +184 -0
- data/etc/oversip.conf +274 -0
- data/etc/proxies.conf +145 -0
- data/etc/server.rb +315 -0
- data/etc/tls/ca/cacert.pem +3894 -0
- data/etc/tls/demo-tls.oversip.net.crt +17 -0
- data/etc/tls/demo-tls.oversip.net.key +15 -0
- data/etc/tls/upgrade-cacert.sh +12 -0
- data/etc/tls/utils/create-cert.rb +162 -0
- data/etc/tls/utils/get-sip-identities.rb +95 -0
- data/ext/common/c_util.h +74 -0
- data/ext/common/ruby_c_util.h +88 -0
- data/ext/sip_parser/common_headers.h +210 -0
- data/ext/sip_parser/ext_help.h +18 -0
- data/ext/sip_parser/extconf.rb +3 -0
- data/ext/sip_parser/sip_message_parser.c +29741 -0
- data/ext/sip_parser/sip_parser.h +250 -0
- data/ext/sip_parser/sip_parser_ruby.c +1370 -0
- data/ext/sip_parser/sip_uri_parser.c +39699 -0
- data/ext/stud/extconf.rb +43 -0
- data/ext/stun/ext_help.h +16 -0
- data/ext/stun/extconf.rb +3 -0
- data/ext/stun/stun_ruby.c +394 -0
- data/ext/utils/ext_help.h +14 -0
- data/ext/utils/extconf.rb +3 -0
- data/ext/utils/haproxy_protocol.c +6163 -0
- data/ext/utils/haproxy_protocol.h +27 -0
- data/ext/utils/ip_utils.c +5952 -0
- data/ext/utils/ip_utils.h +64 -0
- data/ext/utils/outbound_utils.c +3227 -0
- data/ext/utils/outbound_utils.h +27 -0
- data/ext/utils/utils_ruby.c +392 -0
- data/ext/utils/utils_ruby.h +76 -0
- data/ext/websocket_framing_utils/ext_help.h +18 -0
- data/ext/websocket_framing_utils/extconf.rb +3 -0
- data/ext/websocket_framing_utils/ws_framing_utils.h +47 -0
- data/ext/websocket_framing_utils/ws_framing_utils_ruby.c +135 -0
- data/ext/websocket_http_parser/ext_help.h +18 -0
- data/ext/websocket_http_parser/extconf.rb +3 -0
- data/ext/websocket_http_parser/ws_http_parser.c +1635 -0
- data/ext/websocket_http_parser/ws_http_parser.h +87 -0
- data/ext/websocket_http_parser/ws_http_parser_ruby.c +630 -0
- data/lib/oversip/config.rb +597 -0
- data/lib/oversip/config_validators.rb +126 -0
- data/lib/oversip/default_server.rb +52 -0
- data/lib/oversip/errors.rb +10 -0
- data/lib/oversip/fiber_pool.rb +56 -0
- data/lib/oversip/launcher.rb +635 -0
- data/lib/oversip/logger.rb +84 -0
- data/lib/oversip/modules/outbound_mangling.rb +56 -0
- data/lib/oversip/modules/user_assertion.rb +73 -0
- data/lib/oversip/proxies_config.rb +189 -0
- data/lib/oversip/ruby_ext/eventmachine.rb +38 -0
- data/lib/oversip/sip/client.rb +428 -0
- data/lib/oversip/sip/client_transaction.rb +586 -0
- data/lib/oversip/sip/constants.rb +88 -0
- data/lib/oversip/sip/core.rb +217 -0
- data/lib/oversip/sip/launcher.rb +221 -0
- data/lib/oversip/sip/listeners/connection.rb +54 -0
- data/lib/oversip/sip/listeners/ipv4_tcp_client.rb +21 -0
- data/lib/oversip/sip/listeners/ipv4_tcp_server.rb +22 -0
- data/lib/oversip/sip/listeners/ipv4_tls_client.rb +21 -0
- data/lib/oversip/sip/listeners/ipv4_tls_server.rb +22 -0
- data/lib/oversip/sip/listeners/ipv4_tls_tunnel_server.rb +22 -0
- data/lib/oversip/sip/listeners/ipv4_udp_server.rb +21 -0
- data/lib/oversip/sip/listeners/ipv6_tcp_client.rb +21 -0
- data/lib/oversip/sip/listeners/ipv6_tcp_server.rb +22 -0
- data/lib/oversip/sip/listeners/ipv6_tls_client.rb +21 -0
- data/lib/oversip/sip/listeners/ipv6_tls_server.rb +22 -0
- data/lib/oversip/sip/listeners/ipv6_tls_tunnel_server.rb +22 -0
- data/lib/oversip/sip/listeners/ipv6_udp_server.rb +21 -0
- data/lib/oversip/sip/listeners/tcp_client.rb +97 -0
- data/lib/oversip/sip/listeners/tcp_connection.rb +202 -0
- data/lib/oversip/sip/listeners/tcp_server.rb +71 -0
- data/lib/oversip/sip/listeners/tls_client.rb +125 -0
- data/lib/oversip/sip/listeners/tls_server.rb +88 -0
- data/lib/oversip/sip/listeners/tls_tunnel_connection.rb +89 -0
- data/lib/oversip/sip/listeners/tls_tunnel_server.rb +61 -0
- data/lib/oversip/sip/listeners/udp_connection.rb +214 -0
- data/lib/oversip/sip/listeners.rb +24 -0
- data/lib/oversip/sip/message.rb +177 -0
- data/lib/oversip/sip/message_processor.rb +213 -0
- data/lib/oversip/sip/name_addr.rb +51 -0
- data/lib/oversip/sip/proxy.rb +324 -0
- data/lib/oversip/sip/request.rb +179 -0
- data/lib/oversip/sip/response.rb +37 -0
- data/lib/oversip/sip/rfc3263.rb +643 -0
- data/lib/oversip/sip/server_transaction.rb +295 -0
- data/lib/oversip/sip/sip.rb +76 -0
- data/lib/oversip/sip/tags.rb +39 -0
- data/lib/oversip/sip/timers.rb +55 -0
- data/lib/oversip/sip/transport_manager.rb +130 -0
- data/lib/oversip/sip/uac.rb +89 -0
- data/lib/oversip/sip/uac_request.rb +84 -0
- data/lib/oversip/sip/uri.rb +208 -0
- data/lib/oversip/syslog.rb +68 -0
- data/lib/oversip/system_callbacks.rb +45 -0
- data/lib/oversip/tls.rb +172 -0
- data/lib/oversip/utils.rb +30 -0
- data/lib/oversip/version.rb +21 -0
- data/lib/oversip/websocket/constants.rb +55 -0
- data/lib/oversip/websocket/http_request.rb +59 -0
- data/lib/oversip/websocket/launcher.rb +183 -0
- data/lib/oversip/websocket/listeners/connection.rb +51 -0
- data/lib/oversip/websocket/listeners/ipv4_ws_server.rb +22 -0
- data/lib/oversip/websocket/listeners/ipv4_wss_server.rb +22 -0
- data/lib/oversip/websocket/listeners/ipv4_wss_tunnel_server.rb +22 -0
- data/lib/oversip/websocket/listeners/ipv6_ws_server.rb +22 -0
- data/lib/oversip/websocket/listeners/ipv6_wss_server.rb +22 -0
- data/lib/oversip/websocket/listeners/ipv6_wss_tunnel_server.rb +22 -0
- data/lib/oversip/websocket/listeners/ws_server.rb +331 -0
- data/lib/oversip/websocket/listeners/wss_server.rb +88 -0
- data/lib/oversip/websocket/listeners/wss_tunnel_server.rb +133 -0
- data/lib/oversip/websocket/listeners.rb +13 -0
- data/lib/oversip/websocket/websocket.rb +13 -0
- data/lib/oversip/websocket/ws_framing.rb +545 -0
- data/lib/oversip/websocket/ws_sip_app.rb +120 -0
- data/lib/oversip.rb +127 -0
- data/test/oversip_test_helper.rb +19 -0
- data/test/test_http_parser.rb +73 -0
- data/test/test_name_addr.rb +27 -0
- data/test/test_name_addr_parser.rb +24 -0
- data/test/test_sip_message_parser.rb +168 -0
- data/test/test_sip_uri_parser.rb +56 -0
- data/test/test_uri.rb +68 -0
- data/thirdparty/stud/stud.tar.gz +0 -0
- metadata +334 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
module OverSIP
|
|
2
|
+
|
|
3
|
+
# Logging client module. Any class desiring to log messages must include (or extend) this module.
|
|
4
|
+
# In order to identify itself in the logs, the class can define log_id() method or set @log_id
|
|
5
|
+
# attribute.
|
|
6
|
+
module Logger
|
|
7
|
+
|
|
8
|
+
def self.load_methods
|
|
9
|
+
::Syslog.close if ::Syslog.opened?
|
|
10
|
+
|
|
11
|
+
syslog_options = ::Syslog::LOG_PID | ::Syslog::LOG_NDELAY
|
|
12
|
+
syslog_facility = ::OverSIP::Syslog::SYSLOG_FACILITY_MAPPING[::OverSIP.configuration[:core][:syslog_facility]] rescue ::Syslog::LOG_DAEMON
|
|
13
|
+
::Syslog.open(::OverSIP.master_name, syslog_options, syslog_facility)
|
|
14
|
+
|
|
15
|
+
begin
|
|
16
|
+
@@threshold = ::OverSIP::Syslog::SYSLOG_SEVERITY_MAPPING[::OverSIP.configuration[:core][:syslog_level]]
|
|
17
|
+
rescue
|
|
18
|
+
@@threshold = 0 # debug.
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
$oversip_debug = ( @@threshold == 0 ? true : false )
|
|
22
|
+
|
|
23
|
+
::OverSIP::Syslog::SYSLOG_SEVERITY_MAPPING.each do |level_str, level_value|
|
|
24
|
+
method_str = "
|
|
25
|
+
def log_system_#{level_str}(msg)
|
|
26
|
+
"
|
|
27
|
+
|
|
28
|
+
method_str << "
|
|
29
|
+
return false if @@threshold > #{level_value}
|
|
30
|
+
|
|
31
|
+
::OverSIP::Syslog.log #{level_value}, msg, log_id, false
|
|
32
|
+
"
|
|
33
|
+
|
|
34
|
+
if not ::OverSIP.daemonized?
|
|
35
|
+
if %w{debug info notice}.include? level_str
|
|
36
|
+
method_str << "
|
|
37
|
+
puts ::OverSIP::Logger.fg_system_msg2str('#{level_str}', msg, log_id)
|
|
38
|
+
"
|
|
39
|
+
else
|
|
40
|
+
method_str << "
|
|
41
|
+
$stderr.puts ::OverSIP::Logger.fg_system_msg2str('#{level_str}', msg, log_id)
|
|
42
|
+
"
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
method_str << "end"
|
|
47
|
+
|
|
48
|
+
self.module_eval method_str
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
# User logs.
|
|
52
|
+
method_str = "
|
|
53
|
+
def log_#{level_str}(msg)
|
|
54
|
+
return false if @@threshold > #{level_value}
|
|
55
|
+
|
|
56
|
+
::OverSIP::Syslog.log #{level_value}, msg, log_id, true
|
|
57
|
+
end
|
|
58
|
+
"
|
|
59
|
+
|
|
60
|
+
self.module_eval method_str
|
|
61
|
+
|
|
62
|
+
end # .each
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def self.fg_system_msg2str(level_str, msg, log_id)
|
|
66
|
+
case msg
|
|
67
|
+
when ::String
|
|
68
|
+
"#{level_str.upcase}: <#{log_id}> " << msg
|
|
69
|
+
when ::Exception
|
|
70
|
+
"#{level_str.upcase}: <#{log_id}> #{msg.message} (#{msg.class })\n#{(msg.backtrace || [])[0..3].join("\n")}"
|
|
71
|
+
else
|
|
72
|
+
"#{level_str.upcase}: <#{log_id}> " << msg.inspect
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Default logging identifier is the class name. If log_id() method is redefined by the
|
|
77
|
+
# class including this module, or it sets @log_id, then such a value takes preference.
|
|
78
|
+
def log_id
|
|
79
|
+
@log_id ||= (self.is_a?(::Module) ? self.name.split("::").last : self.class.name)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
end # module Logger
|
|
83
|
+
|
|
84
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
module OverSIP::Modules
|
|
2
|
+
|
|
3
|
+
module OutboundMangling
|
|
4
|
+
|
|
5
|
+
extend ::OverSIP::Logger
|
|
6
|
+
|
|
7
|
+
@log_id = "OutboundMangling module"
|
|
8
|
+
|
|
9
|
+
def self.add_outbound_to_contact proxy
|
|
10
|
+
unless proxy.is_a? ::OverSIP::SIP::Proxy
|
|
11
|
+
raise ::OverSIP::RuntimeError, "proxy must be a OverSIP::SIP::Proxy instance"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
proxy.on_target do |target|
|
|
15
|
+
request = proxy.request
|
|
16
|
+
# Just act in case the request has a single Contact, its connection uses Outbound
|
|
17
|
+
# and no ;ov-ob param exists in Contact URI.
|
|
18
|
+
if request.contact and request.connection_outbound_flow_token and not request.contact.has_param? "ov-ob"
|
|
19
|
+
log_system_debug "performing Contact mangling (adding ;ov-ob Outbound param) for #{request.log_id}" if $oversip_debug
|
|
20
|
+
|
|
21
|
+
request.contact.set_param "ov-ob", request.connection_outbound_flow_token
|
|
22
|
+
|
|
23
|
+
proxy.on_success_response do |response|
|
|
24
|
+
if (contacts = response.headers["Contact"])
|
|
25
|
+
log_system_debug "reverting original Contact value (removing ;ov-ob Outbound param) from response" if $oversip_debug
|
|
26
|
+
contacts.each { |contact| contact.gsub! /;ov-ob=[_\-0-9A-Za-z]+/, "" }
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def self.extract_outbound_from_ruri request
|
|
34
|
+
# Do nothing if the request already contains a Route header with the Outbound flow token (so
|
|
35
|
+
# the registrar *does* support Path).
|
|
36
|
+
unless request.incoming_outbound_requested?
|
|
37
|
+
if (ov_ob = request.ruri.del_param("ov-ob"))
|
|
38
|
+
log_system_debug "incoming Outbound flow token extracted from ;ov-ob param in RURI for #{request.log_id}" if $oversip_debug
|
|
39
|
+
request.route_outbound_flow_token = ov_ob
|
|
40
|
+
request.incoming_outbound_requested = true
|
|
41
|
+
return true
|
|
42
|
+
else
|
|
43
|
+
return false
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
else
|
|
47
|
+
# If the request already contains a proper Outbound Route header, then at least try to remove
|
|
48
|
+
# the ;ov-ob param from the RURI.
|
|
49
|
+
request.ruri.del_param("ov-ob")
|
|
50
|
+
return false
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
end # module OutboundMangling
|
|
55
|
+
|
|
56
|
+
end
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
module OverSIP::Modules
|
|
2
|
+
|
|
3
|
+
module UserAssertion
|
|
4
|
+
|
|
5
|
+
extend ::OverSIP::Logger
|
|
6
|
+
|
|
7
|
+
@log_id = "UserAssertion module"
|
|
8
|
+
|
|
9
|
+
def self.assert_connection message
|
|
10
|
+
case message
|
|
11
|
+
when ::OverSIP::SIP::Request
|
|
12
|
+
request = message
|
|
13
|
+
when ::OverSIP::SIP::Response
|
|
14
|
+
request = message.request
|
|
15
|
+
else
|
|
16
|
+
raise ::OverSIP::RuntimeError, "message must be a OverSIP::SIP::Request or OverSIP::SIP::Response"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Don't do this stuf for UDP or for outbound connections.
|
|
20
|
+
return false unless request.connection.class.reliable_transport_listener?
|
|
21
|
+
# Return if already set.
|
|
22
|
+
return request.cvars[:asserted_user] if request.cvars[:asserted_user]
|
|
23
|
+
# Don't do this stuf in case of P-Preferred-Identity header is present.
|
|
24
|
+
return false if request.headers["P-Preferred-Identity"]
|
|
25
|
+
|
|
26
|
+
log_system_debug "user #{request.from.uri} asserted to connection" if $oversip_debug
|
|
27
|
+
# Store the request From URI as "asserted_user" for this connection.
|
|
28
|
+
request.cvars[:asserted_user] = request.from.uri
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def self.revoke_assertion message
|
|
32
|
+
case message
|
|
33
|
+
when ::OverSIP::SIP::Request
|
|
34
|
+
request = message
|
|
35
|
+
when ::OverSIP::SIP::Response
|
|
36
|
+
request = message.request
|
|
37
|
+
else
|
|
38
|
+
raise ::OverSIP::RuntimeError, "message must be a OverSIP::SIP::Request or OverSIP::SIP::Response"
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
request.cvars.delete :asserted_user
|
|
42
|
+
true
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def self.add_pai request
|
|
46
|
+
# Add P-Asserted-Identity if the user has previously been asserted but JUST
|
|
47
|
+
# in case it matches request From URI !
|
|
48
|
+
# NOTE: If the connection is not asserted (it's null) then it will not match this
|
|
49
|
+
# comparisson, so OK.
|
|
50
|
+
if request.cvars[:asserted_user] == request.from.uri
|
|
51
|
+
# Don't add P-Asserted-Identity if the request contains P-Preferred-Identity header.
|
|
52
|
+
unless request.headers["P-Preferred-Identity"]
|
|
53
|
+
log_system_debug "user asserted, adding P-Asserted-Identity for #{request.log_id}" if $oversip_debug
|
|
54
|
+
request.set_header "P-Asserted-Identity", "<" << request.cvars[:asserted_user] << ">"
|
|
55
|
+
return true
|
|
56
|
+
else
|
|
57
|
+
# Remove posible P-Asserted-Identity header!
|
|
58
|
+
log_system_debug "user asserted but P-Preferred-Identity header present, P-Asserted-Identity not added for #{request.log_id}" if $oversip_debug
|
|
59
|
+
request.headers.delete "P-Asserted-Identity"
|
|
60
|
+
return nil
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Otherwise ensure the request has no spoofed P-Asserted-Identity headers!
|
|
64
|
+
else
|
|
65
|
+
request.headers.delete "P-Asserted-Identity"
|
|
66
|
+
return false
|
|
67
|
+
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
end # module UserAssertion
|
|
72
|
+
|
|
73
|
+
end
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
module OverSIP
|
|
2
|
+
|
|
3
|
+
module ProxiesConfig
|
|
4
|
+
|
|
5
|
+
extend ::OverSIP::Logger
|
|
6
|
+
extend ::OverSIP::Config::Validators
|
|
7
|
+
|
|
8
|
+
def self.log_id
|
|
9
|
+
@log_id ||= "ProxiesConfig"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
@proxy_configuration = {
|
|
13
|
+
:do_record_routing => true,
|
|
14
|
+
:record_route_all => false,
|
|
15
|
+
:use_dns => true,
|
|
16
|
+
:use_dns_cache => true,
|
|
17
|
+
:dns_cache_time => 300,
|
|
18
|
+
:use_blacklist => true,
|
|
19
|
+
:blacklist_time => 10,
|
|
20
|
+
:use_naptr => true,
|
|
21
|
+
:use_srv => true,
|
|
22
|
+
:transport_preference => ["tls", "tcp", "udp"],
|
|
23
|
+
:force_transport_preference => false,
|
|
24
|
+
:ip_type_preference => ["ipv6", "ipv4"],
|
|
25
|
+
:dns_failover_on_503 => true,
|
|
26
|
+
:timer_B => 32,
|
|
27
|
+
:timer_C => 120,
|
|
28
|
+
:timer_F => 32,
|
|
29
|
+
:callback_on_server_tls_handshake => true
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
PROXY_CONFIG_VALIDATIONS = {
|
|
33
|
+
:do_record_routing => :boolean,
|
|
34
|
+
:record_route_all => :boolean,
|
|
35
|
+
:use_dns => :boolean,
|
|
36
|
+
:use_dns_cache => :boolean,
|
|
37
|
+
:dns_cache_time => [ :fixnum, [ :greater_equal_than, 300 ] ],
|
|
38
|
+
:use_blacklist => :boolean,
|
|
39
|
+
:blacklist_time => [ :fixnum, [ :greater_equal_than, 2 ], [ :minor_equal_than, 600 ] ],
|
|
40
|
+
:use_naptr => :boolean,
|
|
41
|
+
:use_srv => :boolean,
|
|
42
|
+
:transport_preference => [ [ :choices, %w{tls tcp udp}], :multi_value, :non_empty ],
|
|
43
|
+
:force_transport_preference => :boolean,
|
|
44
|
+
:ip_type_preference => [ [ :choices, %w{ipv4 ipv6}], :multi_value, :non_empty ],
|
|
45
|
+
:dns_failover_on_503 => :boolean,
|
|
46
|
+
:timer_B => [ :fixnum, [ :greater_equal_than, 2 ], [ :minor_equal_than, 64 ] ],
|
|
47
|
+
:timer_C => [ :fixnum, [ :greater_equal_than, 8 ], [ :minor_equal_than, 180 ] ],
|
|
48
|
+
:timer_F => [ :fixnum, [ :greater_equal_than, 2 ], [ :minor_equal_than, 64 ] ],
|
|
49
|
+
:callback_on_server_tls_handshake => :boolean
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
def self.load proxies_yaml, reload=false
|
|
53
|
+
begin
|
|
54
|
+
unless proxies_yaml.is_a? ::Hash
|
|
55
|
+
raise "invalid proxies configuration file, it is not a collection"
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
proxies = {}
|
|
59
|
+
|
|
60
|
+
proxies_yaml.each do |proxy, conf|
|
|
61
|
+
unless proxy.is_a? ::String
|
|
62
|
+
raise "proxy name is not a string (#{proxy.inspect})"
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
proxies[proxy.to_sym] = @proxy_configuration.dup
|
|
66
|
+
proxies[proxy.to_sym].each do |parameter, default_value|
|
|
67
|
+
proxies[proxy.to_sym][parameter] = case default_value
|
|
68
|
+
when ::TrueClass, ::FalseClass, ::NilClass, ::Fixnum
|
|
69
|
+
default_value
|
|
70
|
+
else
|
|
71
|
+
default_value.clone
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
PROXY_CONFIG_VALIDATIONS.each do |parameter, validations|
|
|
76
|
+
values = proxies_yaml[proxy][parameter.to_s]
|
|
77
|
+
validations = [ validations ] unless validations.is_a?(::Array)
|
|
78
|
+
|
|
79
|
+
if values == nil
|
|
80
|
+
if validations.include? :required
|
|
81
|
+
raise "#{proxy}[#{parameter}] requires a value"
|
|
82
|
+
end
|
|
83
|
+
next
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
if values.is_a? ::Array
|
|
87
|
+
unless validations.include? :multi_value
|
|
88
|
+
raise "#{proxy}[#{parameter}] does not allow multiple values"
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
if validations.include? :non_empty and values.empty?
|
|
92
|
+
raise "#{proxy}[#{parameter}] does not allow empty values"
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
values = ( values.is_a?(::Array) ? values : [ values ] )
|
|
97
|
+
|
|
98
|
+
values.each do |value|
|
|
99
|
+
validations.each do |validation|
|
|
100
|
+
|
|
101
|
+
if validation.is_a? ::Symbol
|
|
102
|
+
args = []
|
|
103
|
+
elsif validation.is_a? ::Array
|
|
104
|
+
args = validation[1..-1]
|
|
105
|
+
validation = validation[0]
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
next if [:required, :multi_value, :non_empty].include? validation
|
|
109
|
+
|
|
110
|
+
unless send validation, value, *args
|
|
111
|
+
raise "#{proxy}[#{parameter}] has invalid value '#{::OverSIP::Config.humanize_value value}' (does not satisfy '#{validation}' validation requirement)"
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
proxies[proxy.to_sym][parameter] = ( validations.include?(:multi_value) ? values : values[0] )
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
end # PROXY_CONFIG_VALIDATIONS[section].each
|
|
119
|
+
end # proxies_yaml.each
|
|
120
|
+
|
|
121
|
+
rescue ::Exception => e
|
|
122
|
+
unless reload
|
|
123
|
+
::OverSIP::Launcher.fatal e.message
|
|
124
|
+
else
|
|
125
|
+
raise ::OverSIP::ConfigurationError, e.message
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
@proxies = proxies
|
|
130
|
+
post_process
|
|
131
|
+
|
|
132
|
+
::OverSIP.proxies = @proxies
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def self.post_process
|
|
137
|
+
@proxies.each_key do |proxy|
|
|
138
|
+
# Add a string parameter with the proxy name itself.
|
|
139
|
+
@proxies[proxy][:name] = proxy.to_s
|
|
140
|
+
|
|
141
|
+
# If use_srv is not set then ensure use_naptr is also not set.
|
|
142
|
+
@proxies[proxy][:use_naptr] = false unless @proxies[proxy][:use_srv]
|
|
143
|
+
|
|
144
|
+
# Convert transport values into Symbols.
|
|
145
|
+
@proxies[proxy][:transport_preference] = @proxies[proxy][:transport_preference].map do |transport|
|
|
146
|
+
transport.to_sym
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# Ensure there are not duplicate transports.
|
|
150
|
+
@proxies[proxy][:transport_preference].uniq!
|
|
151
|
+
|
|
152
|
+
# Remove transports that are not supported.
|
|
153
|
+
@proxies[proxy][:transport_preference].delete :tls unless ::OverSIP.configuration[:sip][:sip_tls]
|
|
154
|
+
@proxies[proxy][:transport_preference].delete :tcp unless ::OverSIP.configuration[:sip][:sip_tcp]
|
|
155
|
+
@proxies[proxy][:transport_preference].delete :udp unless ::OverSIP.configuration[:sip][:sip_udp]
|
|
156
|
+
|
|
157
|
+
# Convert IP type values into Symbols.
|
|
158
|
+
@proxies[proxy][:ip_type_preference] = @proxies[proxy][:ip_type_preference].map do |ip_type|
|
|
159
|
+
ip_type.to_sym
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
# Ensure there are not duplicate IP types.
|
|
163
|
+
@proxies[proxy][:ip_type_preference].uniq!
|
|
164
|
+
|
|
165
|
+
# Remove IP types that are not supported.
|
|
166
|
+
@proxies[proxy][:ip_type_preference].delete :ipv4 unless ::OverSIP.configuration[:sip][:listen_ipv4]
|
|
167
|
+
@proxies[proxy][:ip_type_preference].delete :ipv6 unless ::OverSIP.configuration[:sip][:listen_ipv6]
|
|
168
|
+
|
|
169
|
+
# Add new parameters for fast access.
|
|
170
|
+
@proxies[proxy][:has_sip_ipv4] = @proxies[proxy][:ip_type_preference].include?(:ipv4)
|
|
171
|
+
@proxies[proxy][:has_sip_ipv6] = @proxies[proxy][:ip_type_preference].include?(:ipv6)
|
|
172
|
+
@proxies[proxy][:has_sip_udp] = @proxies[proxy][:transport_preference].include?(:udp)
|
|
173
|
+
@proxies[proxy][:has_sip_tcp] = @proxies[proxy][:transport_preference].include?(:tcp)
|
|
174
|
+
@proxies[proxy][:has_sip_tls] = @proxies[proxy][:transport_preference].include?(:tls)
|
|
175
|
+
|
|
176
|
+
# Add a hash for the DNS cache.
|
|
177
|
+
@proxies[proxy][:dns_cache] = {}
|
|
178
|
+
|
|
179
|
+
# Add a hash for the blacklist.
|
|
180
|
+
@proxies[proxy][:blacklist] = {}
|
|
181
|
+
|
|
182
|
+
# Only allow record routing for all requsts if record routing is enabled
|
|
183
|
+
@proxies[proxy][:record_route_all] = false unless @proxies[proxy][:do_record_routing]
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
module EventMachine
|
|
2
|
+
|
|
3
|
+
# Fast method for setting an outgoing TCP connection.
|
|
4
|
+
def self.oversip_connect_tcp_server bind_addr, server, port, klass, *args
|
|
5
|
+
s = bind_connect_server bind_addr, 0, server, port
|
|
6
|
+
c = klass.new s, *args
|
|
7
|
+
@conns[s] = c
|
|
8
|
+
block_given? and yield c
|
|
9
|
+
c
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class Connection
|
|
14
|
+
|
|
15
|
+
# We require Ruby 1.9 so don't check String#bytesize method.
|
|
16
|
+
def send_data data
|
|
17
|
+
::EventMachine::send_data @signature, data, data.bytesize
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def send_datagram data, address, port
|
|
21
|
+
::EventMachine::send_datagram @signature, data, data.bytesize, address, port
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Rewrite close_connection so it set an internal attribute (which can be
|
|
25
|
+
# inspected when unbind() callback is called).
|
|
26
|
+
alias _em_close_connection close_connection
|
|
27
|
+
def close_connection after_writing=false
|
|
28
|
+
@local_closed = true
|
|
29
|
+
_em_close_connection after_writing
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def close_connection_after_writing
|
|
33
|
+
close_connection true
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
end
|