oversip 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- data/AUTHORS.txt +11 -0
- data/LICENSE.txt +22 -0
- data/README.md +16 -0
- data/Rakefile +55 -0
- data/bin/oversip +182 -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 +209 -0
- data/ext/sip_parser/ext_help.h +18 -0
- data/ext/sip_parser/extconf.rb +3 -0
- data/ext/sip_parser/sip_parser.c +29649 -0
- data/ext/sip_parser/sip_parser.h +227 -0
- data/ext/sip_parser/sip_parser_ruby.c +1292 -0
- data/ext/stud/extconf.rb +27 -0
- data/ext/stud/stud.tar.gz +0 -0
- data/ext/stun/ext_help.h +16 -0
- data/ext/stun/extconf.rb +3 -0
- data/ext/stun/stun_ruby.c +391 -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 +61 -0
- data/ext/utils/outbound_utils.c +3227 -0
- data/ext/utils/outbound_utils.h +27 -0
- data/ext/utils/utils_ruby.c +384 -0
- data/ext/utils/utils_ruby.h +75 -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 +46 -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 +2598 -0
- data/ext/websocket_http_parser/ws_http_parser.h +86 -0
- data/ext/websocket_http_parser/ws_http_parser_ruby.c +630 -0
- data/lib/oversip/config.rb +541 -0
- data/lib/oversip/config_validators.rb +126 -0
- data/lib/oversip/errors.rb +7 -0
- data/lib/oversip/fiber_pool.rb +56 -0
- data/lib/oversip/launcher.rb +507 -0
- data/lib/oversip/logger.rb +170 -0
- data/lib/oversip/master_process.rb +67 -0
- data/lib/oversip/posix_mq.rb +121 -0
- data/lib/oversip/proxies_config.rb +169 -0
- data/lib/oversip/ruby_ext/eventmachine.rb +38 -0
- data/lib/oversip/sip/client_transaction.rb +587 -0
- data/lib/oversip/sip/constants.rb +87 -0
- data/lib/oversip/sip/grammar/name_addr.rb +27 -0
- data/lib/oversip/sip/grammar/uri.rb +116 -0
- data/lib/oversip/sip/launcher.rb +180 -0
- data/lib/oversip/sip/listeners/ipv4_tcp_client.rb +21 -0
- data/lib/oversip/sip/listeners/ipv4_tcp_server.rb +21 -0
- data/lib/oversip/sip/listeners/ipv4_tls_client.rb +21 -0
- data/lib/oversip/sip/listeners/ipv4_tls_server.rb +21 -0
- data/lib/oversip/sip/listeners/ipv4_tls_tunnel_server.rb +21 -0
- data/lib/oversip/sip/listeners/ipv4_udp_server.rb +20 -0
- data/lib/oversip/sip/listeners/ipv6_tcp_client.rb +21 -0
- data/lib/oversip/sip/listeners/ipv6_tcp_server.rb +21 -0
- data/lib/oversip/sip/listeners/ipv6_tls_client.rb +21 -0
- data/lib/oversip/sip/listeners/ipv6_tls_server.rb +21 -0
- data/lib/oversip/sip/listeners/ipv6_tls_tunnel_server.rb +21 -0
- data/lib/oversip/sip/listeners/ipv6_udp_server.rb +20 -0
- data/lib/oversip/sip/listeners/reactor.rb +39 -0
- data/lib/oversip/sip/listeners/tcp_client.rb +73 -0
- data/lib/oversip/sip/listeners/tcp_reactor.rb +185 -0
- data/lib/oversip/sip/listeners/tcp_server.rb +71 -0
- data/lib/oversip/sip/listeners/tls_client.rb +117 -0
- data/lib/oversip/sip/listeners/tls_server.rb +70 -0
- data/lib/oversip/sip/listeners/tls_tunnel_reactor.rb +113 -0
- data/lib/oversip/sip/listeners/tls_tunnel_server.rb +61 -0
- data/lib/oversip/sip/listeners/udp_reactor.rb +213 -0
- data/lib/oversip/sip/listeners.rb +28 -0
- data/lib/oversip/sip/logic.rb +14 -0
- data/lib/oversip/sip/message.rb +168 -0
- data/lib/oversip/sip/message_processor.rb +202 -0
- data/lib/oversip/sip/modules/core.rb +200 -0
- data/lib/oversip/sip/modules/registrar_without_path.rb +75 -0
- data/lib/oversip/sip/modules/user_assertion.rb +123 -0
- data/lib/oversip/sip/proxy.rb +460 -0
- data/lib/oversip/sip/request.rb +128 -0
- data/lib/oversip/sip/response.rb +30 -0
- data/lib/oversip/sip/rfc3263.rb +646 -0
- data/lib/oversip/sip/server_transaction.rb +295 -0
- data/lib/oversip/sip/sip.rb +74 -0
- data/lib/oversip/sip/tags.rb +39 -0
- data/lib/oversip/sip/timers.rb +55 -0
- data/lib/oversip/sip/transport_manager.rb +129 -0
- data/lib/oversip/syslogger_process.rb +119 -0
- data/lib/oversip/tls.rb +179 -0
- data/lib/oversip/utils.rb +25 -0
- data/lib/oversip/version.rb +23 -0
- data/lib/oversip/websocket/constants.rb +56 -0
- data/lib/oversip/websocket/default_policy.rb +19 -0
- data/lib/oversip/websocket/http_request.rb +63 -0
- data/lib/oversip/websocket/launcher.rb +207 -0
- data/lib/oversip/websocket/listeners/ipv4_tcp_server.rb +15 -0
- data/lib/oversip/websocket/listeners/ipv4_tls_server.rb +15 -0
- data/lib/oversip/websocket/listeners/ipv4_tls_tunnel_server.rb +15 -0
- data/lib/oversip/websocket/listeners/ipv6_tcp_server.rb +15 -0
- data/lib/oversip/websocket/listeners/ipv6_tls_server.rb +15 -0
- data/lib/oversip/websocket/listeners/ipv6_tls_tunnel_server.rb +15 -0
- data/lib/oversip/websocket/listeners/tcp_server.rb +265 -0
- data/lib/oversip/websocket/listeners/tls_server.rb +69 -0
- data/lib/oversip/websocket/listeners/tls_tunnel_server.rb +100 -0
- data/lib/oversip/websocket/listeners.rb +12 -0
- data/lib/oversip/websocket/ws_app.rb +75 -0
- data/lib/oversip/websocket/ws_apps/ipv4_ws_sip_app.rb +21 -0
- data/lib/oversip/websocket/ws_apps/ipv4_wss_sip_app.rb +21 -0
- data/lib/oversip/websocket/ws_apps/ipv6_ws_sip_app.rb +21 -0
- data/lib/oversip/websocket/ws_apps/ipv6_wss_sip_app.rb +22 -0
- data/lib/oversip/websocket/ws_apps/ws_autobahn_app.rb +23 -0
- data/lib/oversip/websocket/ws_apps/ws_sip_app.rb +156 -0
- data/lib/oversip/websocket/ws_apps.rb +9 -0
- data/lib/oversip/websocket/ws_framing.rb +597 -0
- data/lib/oversip.rb +59 -0
- data/test/oversip_test_helper.rb +20 -0
- data/test/test_http_parser.rb +73 -0
- data/test/test_sip_parser.rb +139 -0
- metadata +256 -0
@@ -0,0 +1,170 @@
|
|
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_ig() method or set @log_id
|
5
|
+
# attribute.
|
6
|
+
module Logger
|
7
|
+
|
8
|
+
SYSLOG_POSIXMQ_MAPPING = {
|
9
|
+
"debug" => 0,
|
10
|
+
"info" => 1,
|
11
|
+
"notice" => 2,
|
12
|
+
"warn" => 3,
|
13
|
+
"error" => 4,
|
14
|
+
"crit" => 5,
|
15
|
+
"alert" => 6,
|
16
|
+
"emerg" => 7
|
17
|
+
}
|
18
|
+
|
19
|
+
def self.init_logger_mq(group = nil)
|
20
|
+
OverSIP.syslogger_mq_name = "/#{OverSIP.master_name}_syslogger"
|
21
|
+
|
22
|
+
@@logger_mq = ::OverSIP::PosixMQ.create_queue({
|
23
|
+
:name => ::OverSIP.syslogger_mq_name,
|
24
|
+
:mode => :write,
|
25
|
+
:maxmsg => 1000,
|
26
|
+
:msgsize => 2000,
|
27
|
+
:group => group
|
28
|
+
})
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
def self.load_methods
|
33
|
+
begin
|
34
|
+
@@threshold = SYSLOG_POSIXMQ_MAPPING[::OverSIP.configuration[:core][:syslog_level]]
|
35
|
+
rescue
|
36
|
+
@@threshold = 0 # debug.
|
37
|
+
end
|
38
|
+
|
39
|
+
$oversip_debug = ( @@threshold == 0 ? true : false )
|
40
|
+
|
41
|
+
@@congested = false
|
42
|
+
|
43
|
+
SYSLOG_POSIXMQ_MAPPING.each do |level, level_value|
|
44
|
+
method_str = "
|
45
|
+
def log_system_#{level}(msg)
|
46
|
+
"
|
47
|
+
|
48
|
+
if ::OverSIP.syslogger_ready?
|
49
|
+
method_str << "
|
50
|
+
return false if @@threshold > #{level_value} || @@congested
|
51
|
+
begin
|
52
|
+
unless @@logger_mq.trysend ::OverSIP::Logger.syslog_system_msg2str(#{level_value}, msg, log_id), 0
|
53
|
+
@@congested = true
|
54
|
+
EM.add_timer(1) do
|
55
|
+
@@logger_mq.trysend ::OverSIP::Logger.syslog_system_msg2str(4, \"logger message queue was full, some logs have been lost\", log_id), 1
|
56
|
+
@@congested = false
|
57
|
+
end
|
58
|
+
end
|
59
|
+
rescue Errno::EMSGSIZE
|
60
|
+
@@logger_mq.trysend ::OverSIP::Logger.syslog_system_msg2str(4, \"too long message could not be logged\", log_id), 1 rescue nil
|
61
|
+
rescue => e
|
62
|
+
@@logger_mq.trysend ::OverSIP::Logger.syslog_system_msg2str(4, \"unexpected logging error (\#{e.class}: \#{e.message})\", log_id), 1 rescue nil
|
63
|
+
end
|
64
|
+
"
|
65
|
+
end
|
66
|
+
|
67
|
+
unless ::OverSIP.daemonized?
|
68
|
+
if %w{debug info notice}.include? level
|
69
|
+
method_str << "
|
70
|
+
puts ::OverSIP::Logger.fg_system_msg2str('#{level}', msg, log_id)
|
71
|
+
"
|
72
|
+
else
|
73
|
+
method_str << "
|
74
|
+
$stderr.puts ::OverSIP::Logger.fg_system_msg2str('#{level}', msg, log_id)
|
75
|
+
"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
method_str << "end"
|
80
|
+
|
81
|
+
self.module_eval method_str
|
82
|
+
|
83
|
+
|
84
|
+
if ::OverSIP.syslogger_ready?
|
85
|
+
# User/script logs.
|
86
|
+
method_str = "
|
87
|
+
def log_#{level}(msg)
|
88
|
+
return false if @@threshold > #{level_value} || @@congested
|
89
|
+
begin
|
90
|
+
unless @@logger_mq.trysend ::OverSIP::Logger.syslog_user_msg2str(#{level_value}, msg, log_id), 0
|
91
|
+
@@congested = true
|
92
|
+
EM.add_timer(1) do
|
93
|
+
@@logger_mq.trysend ::OverSIP::Logger.syslog_user_msg2str(4, \"logger message queue was full, some logs have been lost\", log_id), 1
|
94
|
+
@@congested = false
|
95
|
+
end
|
96
|
+
end
|
97
|
+
rescue Errno::EMSGSIZE
|
98
|
+
@@logger_mq.trysend ::OverSIP::Logger.syslog_user_msg2str(4, \"too long message could not be logged\", log_id), 1 rescue nil
|
99
|
+
rescue => e
|
100
|
+
@@logger_mq.trysend ::OverSIP::Logger.syslog_user_msg2str(4, \"unexpected logging error (\#{e.class}: \#{e.message})\", log_id), 1 rescue nil
|
101
|
+
end
|
102
|
+
end
|
103
|
+
"
|
104
|
+
|
105
|
+
self.module_eval method_str
|
106
|
+
end
|
107
|
+
|
108
|
+
end # .each
|
109
|
+
|
110
|
+
# A convenient method to ensure that fatal logs are properly logged and program
|
111
|
+
# exited with error status.
|
112
|
+
def fatal msg
|
113
|
+
log_system_crit msg
|
114
|
+
log_system_crit "exiting with error status"
|
115
|
+
|
116
|
+
::OverSIP::Launcher.terminate error=true
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
# Generate nice log messages. It accepst three parameters:
|
121
|
+
# - level_value: Integer representing the log level.
|
122
|
+
# - msg: the String or Exception to be logged.
|
123
|
+
# - log_id: a String helping to identify the generator of this log message.
|
124
|
+
def self.syslog_system_msg2str(level_value, msg, log_id)
|
125
|
+
case msg
|
126
|
+
when ::String
|
127
|
+
level_value.to_s << "<" << log_id << "> " << msg
|
128
|
+
when ::Exception
|
129
|
+
"#{level_value}<#{log_id}> #{msg.message} (#{msg.class })\n#{(msg.backtrace || [])[0..3].join("\n")}"
|
130
|
+
else
|
131
|
+
level_value.to_s << "<" << log_id << "> " << msg.inspect
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def self.syslog_user_msg2str(level_value, msg, log_id)
|
136
|
+
case msg
|
137
|
+
when ::String
|
138
|
+
level_value.to_s << "<" << log_id << "> script: " << msg
|
139
|
+
when ::Exception
|
140
|
+
"#{level_value}<#{log_id}> script: #{msg.message} (#{msg.class })\n#{(msg.backtrace || [])[0..3].join("\n")}"
|
141
|
+
else
|
142
|
+
level_value.to_s << "<" << log_id << "> script: " << msg.inspect
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def self.fg_system_msg2str(level, msg, log_id)
|
147
|
+
case msg
|
148
|
+
when ::String
|
149
|
+
"#{level.upcase}: <#{log_id}> " << msg
|
150
|
+
when ::Exception
|
151
|
+
"#{level.upcase}: <#{log_id}> #{msg.message} (#{msg.class })\n#{(msg.backtrace || [])[0..3].join("\n")}"
|
152
|
+
else
|
153
|
+
"#{level.upcase}: <#{log_id}> " << msg.inspect
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
def self.close
|
158
|
+
@@logger_mq.close rescue nil
|
159
|
+
@@logger_mq.unlink rescue nil
|
160
|
+
end
|
161
|
+
|
162
|
+
# Default logging identifier is the class name. If log_id() method is redefined by the
|
163
|
+
# class including this module, or it sets @log_id, then such value takes preference.
|
164
|
+
def log_id
|
165
|
+
@log_id ||= self.class.name
|
166
|
+
end
|
167
|
+
|
168
|
+
end # module Logger
|
169
|
+
|
170
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# Ruby built-in libraries.
|
2
|
+
|
3
|
+
require "base64"
|
4
|
+
require "digest/md5"
|
5
|
+
require "digest/sha1"
|
6
|
+
require "securerandom"
|
7
|
+
require "fiber"
|
8
|
+
require "openssl"
|
9
|
+
|
10
|
+
|
11
|
+
# Ruby external gems.
|
12
|
+
|
13
|
+
gem "eventmachine-le", ">= 1.1.0"
|
14
|
+
require "eventmachine-le"
|
15
|
+
|
16
|
+
gem "iobuffer", ">= 1.1.2"
|
17
|
+
require "iobuffer"
|
18
|
+
gem "em-udns", ">= 0.3.6"
|
19
|
+
require "em-udns"
|
20
|
+
gem "escape_utils", ">= 0.2.4"
|
21
|
+
require "escape_utils"
|
22
|
+
gem "posix-spawn", ">= 0.3.6"
|
23
|
+
require "posix-spawn"
|
24
|
+
|
25
|
+
|
26
|
+
# OverSIP files.
|
27
|
+
|
28
|
+
require "oversip/ruby_ext/eventmachine.rb"
|
29
|
+
|
30
|
+
require "oversip/sip/sip.rb"
|
31
|
+
require "oversip/sip/sip_parser.so"
|
32
|
+
require "oversip/sip/constants.rb"
|
33
|
+
require "oversip/sip/message.rb"
|
34
|
+
require "oversip/sip/request.rb"
|
35
|
+
require "oversip/sip/response.rb"
|
36
|
+
require "oversip/sip/grammar/uri.rb"
|
37
|
+
require "oversip/sip/grammar/name_addr.rb"
|
38
|
+
require "oversip/sip/message_processor.rb"
|
39
|
+
require "oversip/sip/listeners.rb"
|
40
|
+
require "oversip/sip/launcher.rb"
|
41
|
+
require "oversip/sip/server_transaction.rb"
|
42
|
+
require "oversip/sip/client_transaction.rb"
|
43
|
+
require "oversip/sip/transport_manager.rb"
|
44
|
+
require "oversip/sip/timers.rb"
|
45
|
+
require "oversip/sip/tags.rb"
|
46
|
+
require "oversip/sip/rfc3263.rb"
|
47
|
+
require "oversip/sip/logic.rb"
|
48
|
+
require "oversip/sip/proxy.rb"
|
49
|
+
|
50
|
+
require "oversip/websocket/ws_http_parser.so"
|
51
|
+
require "oversip/websocket/constants.rb"
|
52
|
+
require "oversip/websocket/http_request.rb"
|
53
|
+
require "oversip/websocket/default_policy.rb"
|
54
|
+
require "oversip/websocket/listeners.rb"
|
55
|
+
require "oversip/websocket/launcher.rb"
|
56
|
+
require "oversip/websocket/ws_framing_utils.so"
|
57
|
+
require "oversip/websocket/ws_framing.rb"
|
58
|
+
require "oversip/websocket/ws_app.rb"
|
59
|
+
require "oversip/websocket/ws_apps.rb"
|
60
|
+
|
61
|
+
require "oversip/fiber_pool.rb"
|
62
|
+
require "oversip/tls.rb"
|
63
|
+
require "oversip/stun.so"
|
64
|
+
|
65
|
+
require "oversip/sip/modules/core.rb"
|
66
|
+
require "oversip/sip/modules/user_assertion.rb"
|
67
|
+
require "oversip/sip/modules/registrar_without_path.rb"
|
@@ -0,0 +1,121 @@
|
|
1
|
+
module OverSIP
|
2
|
+
|
3
|
+
class PosixMQ
|
4
|
+
|
5
|
+
extend ::OverSIP::Logger
|
6
|
+
|
7
|
+
def self.create_queue options={}
|
8
|
+
@log_id = "PosixMQ #{options[:name]}"
|
9
|
+
@total_size ||= 0
|
10
|
+
|
11
|
+
# Queue attributes.
|
12
|
+
mq_name = options[:name]
|
13
|
+
mq_mode = case options[:mode]
|
14
|
+
when :read then IO::RDONLY
|
15
|
+
when :write then IO::WRONLY
|
16
|
+
when :read_write then IO::RDWR
|
17
|
+
end
|
18
|
+
mq_group = options[:group]
|
19
|
+
mq_attr = ::POSIX_MQ::Attr.new
|
20
|
+
# NOTE: maximun value for maxmsg is 65536.
|
21
|
+
mq_attr.maxmsg = options[:maxmsg]
|
22
|
+
mq_attr.msgsize = options[:msgsize]
|
23
|
+
mq_attr.flags = 0
|
24
|
+
mq_attr.curmsgs = 0
|
25
|
+
|
26
|
+
# Delete the queue if it exists.
|
27
|
+
begin
|
28
|
+
::POSIX_MQ.unlink mq_name
|
29
|
+
rescue ::Errno::ENOENT
|
30
|
+
rescue ::Errno::EACCES => e
|
31
|
+
fatal "queue already exists and cannot remove it due file permissions"
|
32
|
+
end
|
33
|
+
|
34
|
+
# Set the UMASK in a way that the group has permission to delete the queue.
|
35
|
+
orig_umask = File.umask(0007)
|
36
|
+
|
37
|
+
# Change the effective group for the Posix queue. Keep the original
|
38
|
+
# group.
|
39
|
+
orig_gid = Process::GID.eid
|
40
|
+
if mq_group
|
41
|
+
gid = Etc.getgrnam(mq_group).gid
|
42
|
+
Process::GID.change_privilege(gid)
|
43
|
+
end
|
44
|
+
|
45
|
+
### TODO: Este tamaño debe multiplicarse por el num de queues!
|
46
|
+
# System limits required size (ulimit -q).
|
47
|
+
mq_size = case 1.size
|
48
|
+
# 32 bits OS.
|
49
|
+
when 4 then mq_attr.maxmsg * 4 + mq_attr.maxmsg * mq_attr.msgsize
|
50
|
+
# 64 bits OS.
|
51
|
+
when 8 then mq_attr.maxmsg * 8 + mq_attr.maxmsg * mq_attr.msgsize
|
52
|
+
end
|
53
|
+
log_system_debug "queue requires #{mq_size} bytes" if $oversip_debug
|
54
|
+
|
55
|
+
# Set RLIMIT_MSGQUEUE (ulimit) in order to create the queue with required
|
56
|
+
# ammount of memory.
|
57
|
+
@total_size += mq_size
|
58
|
+
if ( current_rlimit = ::Process.getrlimit(12)[1] ) < @total_size
|
59
|
+
log_system_debug "incrementing rlimits (currently #{current_rlimit} bytes) to #{@total_size} bytes (ulimit -q)" if $oversip_debug
|
60
|
+
begin
|
61
|
+
::Process.setrlimit(12, @total_size)
|
62
|
+
rescue Errno::EPERM
|
63
|
+
fatal "current user has no permissions to increase rlimits to #{@total_size} bytes (ulimit -q)"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# Create the Posix message queue to write into it.
|
68
|
+
# - IO::WRONLY => Just write.
|
69
|
+
# - IO::CREAT => Create if it doesn't exist.
|
70
|
+
# - IO::EXCL => Raise if the queue already exists.
|
71
|
+
# - IO::NONBLOCK => Don't block when sending (instead raise Errno::EAGAIN).
|
72
|
+
# - mode: 00660 => User and group can write and read.
|
73
|
+
# - mq_attr => Set maxmsg and msgsize.
|
74
|
+
begin
|
75
|
+
mq = ::POSIX_MQ.new mq_name, mq_mode | IO::CREAT | IO::EXCL | IO::NONBLOCK, 00660, mq_attr
|
76
|
+
|
77
|
+
# Kernel has no support for posix message queues.
|
78
|
+
rescue Errno::ENOSYS => e
|
79
|
+
fatal "the kernel has no support for posix messages queues, enable it (#{e.class}: #{e.message})"
|
80
|
+
|
81
|
+
# http://linux.die.net/man/3/mq_open
|
82
|
+
#
|
83
|
+
# O_CREAT was specified in oflag, and attr was not NULL, but attr->mq_maxmsg or attr->mq_msqsize was
|
84
|
+
# invalid. Both of these fields must be greater than zero. In a process that is unprivileged (does not
|
85
|
+
# have the CAP_SYS_RESOURCE capability), attr->mq_maxmsg must be less than or equal to the msg_max
|
86
|
+
# limit, and attr->mq_msgsize must be less than or equal to the msgsize_max limit. In addition, even
|
87
|
+
# in a privileged process, attr->mq_maxmsg cannot exceed the HARD_MAX limit. (See mq_overview(7) for
|
88
|
+
# details of these limits.)
|
89
|
+
rescue Errno::EINVAL
|
90
|
+
log_system_warn "cannot set queue attributes due to user permissions, using system default values"
|
91
|
+
mq = ::POSIX_MQ.new mq_name, mq_mode | IO::CREAT | IO::NONBLOCK, 00660
|
92
|
+
rescue Errno::ENOMEM => e
|
93
|
+
fatal "insufficient memory (#{e.class}: #{e.message})"
|
94
|
+
rescue Errno::EMFILE => e
|
95
|
+
fatal "the process already has the maximum number of files and message queues open (#{e.class}: #{e.message})"
|
96
|
+
rescue Errno::ENFILE => e
|
97
|
+
fatal "the system limit on the total number of open files and message queues has been reached (#{e.class}: #{e.message})"
|
98
|
+
rescue Errno::ENOSPC => e
|
99
|
+
fatal "insufficient space for the creation of a new message queue, probably occurred because the queues_max limit was encountered (#{e.class}: #{e.message})"
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
# Recover the original Umask settings.
|
104
|
+
File.umask(orig_umask)
|
105
|
+
|
106
|
+
# Recover the original effective group.
|
107
|
+
Process::GID.change_privilege(orig_gid) if mq_group
|
108
|
+
|
109
|
+
if mq.attr.maxmsg == mq_attr.maxmsg and mq.attr.msgsize == mq_attr.msgsize
|
110
|
+
log_system_debug "maxmsg=#{mq.attr.maxmsg}, msgsize=#{mq.attr.msgsize}" if $oversip_debug
|
111
|
+
else
|
112
|
+
log_system_warn "maxmsg=#{mq.attr.maxmsg}, msgsize=#{mq.attr.msgsize}, " \
|
113
|
+
"but recommended values are maxmsg=#{mq_attr.maxmsg}, msgsize=#{mq_attr.msgsize}"
|
114
|
+
end
|
115
|
+
|
116
|
+
mq
|
117
|
+
end # self.create_queue
|
118
|
+
|
119
|
+
end # class PosixMQ
|
120
|
+
|
121
|
+
end
|
@@ -0,0 +1,169 @@
|
|
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
|
+
@proxies = {}
|
13
|
+
|
14
|
+
@proxy_configuration = {
|
15
|
+
:do_loose_routing => true,
|
16
|
+
:use_dns => true,
|
17
|
+
:use_dns_cache => true,
|
18
|
+
:dns_cache_time => 300,
|
19
|
+
:use_naptr => true,
|
20
|
+
:use_srv => true,
|
21
|
+
:transport_preference => ["tls", "tcp", "udp"],
|
22
|
+
:force_transport_preference => false,
|
23
|
+
:ip_type_preference => ["ipv6", "ipv4"],
|
24
|
+
:dns_failover_on_503 => true,
|
25
|
+
:timer_B => 32,
|
26
|
+
:timer_C => 120,
|
27
|
+
:timer_F => 32,
|
28
|
+
:tls_validation => false
|
29
|
+
}
|
30
|
+
|
31
|
+
PROXY_CONFIG_VALIDATIONS = {
|
32
|
+
:do_loose_routing => :boolean,
|
33
|
+
:use_dns => :boolean,
|
34
|
+
:use_dns_cache => :boolean,
|
35
|
+
:dns_cache_time => [ :fixnum, [ :greater_equal_than, 300 ] ],
|
36
|
+
:use_naptr => :boolean,
|
37
|
+
:use_srv => :boolean,
|
38
|
+
:transport_preference => [ [ :choices, %w{tls tcp udp}], :multi_value, :non_empty ],
|
39
|
+
:force_transport_preference => :boolean,
|
40
|
+
:ip_type_preference => [ [ :choices, %w{ipv4 ipv6}], :multi_value, :non_empty ],
|
41
|
+
:dns_failover_on_503 => :boolean,
|
42
|
+
:timer_B => [ :fixnum, [ :greater_equal_than, 2 ], [ :minor_equal_than, 64 ] ],
|
43
|
+
:timer_C => [ :fixnum, [ :greater_equal_than, 8 ], [ :minor_equal_than, 180 ] ],
|
44
|
+
:timer_F => [ :fixnum, [ :greater_equal_than, 2 ], [ :minor_equal_than, 64 ] ],
|
45
|
+
:tls_validation => :boolean
|
46
|
+
}
|
47
|
+
|
48
|
+
def self.load proxies_yaml
|
49
|
+
unless proxies_yaml.is_a? Hash
|
50
|
+
fatal "invalid proxies configuration file, it is not a collection"
|
51
|
+
end
|
52
|
+
|
53
|
+
begin
|
54
|
+
proxies_yaml.each do |proxy, conf|
|
55
|
+
unless proxy.is_a? String
|
56
|
+
fatal "proxy name is not a string (#{proxy.inspect})"
|
57
|
+
end
|
58
|
+
|
59
|
+
@proxies[proxy.to_sym] = @proxy_configuration.dup
|
60
|
+
@proxies[proxy.to_sym].each do |parameter, default_value|
|
61
|
+
@proxies[proxy.to_sym][parameter] = default_value.clone rescue default_value
|
62
|
+
end
|
63
|
+
|
64
|
+
PROXY_CONFIG_VALIDATIONS.each do |parameter, validations|
|
65
|
+
values = proxies_yaml[proxy][parameter.to_s]
|
66
|
+
validations = [ validations ] unless validations.is_a?(Array)
|
67
|
+
|
68
|
+
if values == nil
|
69
|
+
if validations.include? :required
|
70
|
+
fatal "#{proxy}[#{parameter}] requires a value"
|
71
|
+
end
|
72
|
+
next
|
73
|
+
end
|
74
|
+
|
75
|
+
if values.is_a? Array
|
76
|
+
unless validations.include? :multi_value
|
77
|
+
fatal "#{proxy}[#{parameter}] does not allow multiple values"
|
78
|
+
end
|
79
|
+
|
80
|
+
if validations.include? :non_empty and values.empty?
|
81
|
+
fatal "#{proxy}[#{parameter}] does not allow empty values"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
values = ( values.is_a?(Array) ? values : [ values ] )
|
86
|
+
|
87
|
+
values.each do |value|
|
88
|
+
validations.each do |validation|
|
89
|
+
|
90
|
+
if validation.is_a? Symbol
|
91
|
+
args = []
|
92
|
+
elsif validation.is_a? Array
|
93
|
+
args = validation[1..-1]
|
94
|
+
validation = validation[0]
|
95
|
+
end
|
96
|
+
|
97
|
+
next if [:required, :multi_value, :non_empty].include? validation
|
98
|
+
|
99
|
+
unless send validation, value, *args
|
100
|
+
fatal "#{proxy}[#{parameter}] has invalid value '#{::OverSIP::Config.humanize_value value}' (does not satisfy '#{validation}' validation requirement)"
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
@proxies[proxy.to_sym][parameter] = ( validations.include?(:multi_value) ? values : values[0] )
|
105
|
+
end
|
106
|
+
|
107
|
+
end # PROXY_CONFIG_VALIDATIONS[section].each
|
108
|
+
end # proxies_yaml.each
|
109
|
+
|
110
|
+
post_process
|
111
|
+
|
112
|
+
rescue OverSIP::ConfigurationError => e
|
113
|
+
fatal "proxies configuration error: #{e.message}"
|
114
|
+
rescue => e
|
115
|
+
fatal e
|
116
|
+
end
|
117
|
+
|
118
|
+
::OverSIP.proxies = @proxies
|
119
|
+
end
|
120
|
+
|
121
|
+
|
122
|
+
def self.post_process
|
123
|
+
@proxies.each_key do |proxy|
|
124
|
+
# Add a string parameter with the proxy name itself.
|
125
|
+
@proxies[proxy][:name] = proxy.to_s
|
126
|
+
|
127
|
+
# If use_srv is not set then ensure use_naptr is also not set.
|
128
|
+
@proxies[proxy][:use_naptr] = false unless @proxies[proxy][:use_srv]
|
129
|
+
|
130
|
+
# Convert transport values into Symbols.
|
131
|
+
@proxies[proxy][:transport_preference] = @proxies[proxy][:transport_preference].map do |transport|
|
132
|
+
transport.to_sym
|
133
|
+
end
|
134
|
+
|
135
|
+
# Ensure there are not duplicate transports.
|
136
|
+
@proxies[proxy][:transport_preference].uniq!
|
137
|
+
|
138
|
+
# Remove transports that are not supported.
|
139
|
+
@proxies[proxy][:transport_preference].delete :tls unless ::OverSIP.configuration[:sip][:sip_tls]
|
140
|
+
@proxies[proxy][:transport_preference].delete :tcp unless ::OverSIP.configuration[:sip][:sip_tcp]
|
141
|
+
@proxies[proxy][:transport_preference].delete :udp unless ::OverSIP.configuration[:sip][:sip_udp]
|
142
|
+
|
143
|
+
# Convert IP type values into Symbols.
|
144
|
+
@proxies[proxy][:ip_type_preference] = @proxies[proxy][:ip_type_preference].map do |ip_type|
|
145
|
+
ip_type.to_sym
|
146
|
+
end
|
147
|
+
|
148
|
+
# Ensure there are not duplicate IP types.
|
149
|
+
@proxies[proxy][:ip_type_preference].uniq!
|
150
|
+
|
151
|
+
# Remove IP types that are not supported.
|
152
|
+
@proxies[proxy][:ip_type_preference].delete :ipv4 unless ::OverSIP.configuration[:sip][:listen_ipv4]
|
153
|
+
@proxies[proxy][:ip_type_preference].delete :ipv6 unless ::OverSIP.configuration[:sip][:listen_ipv6]
|
154
|
+
|
155
|
+
# Add new parameters for fast access.
|
156
|
+
@proxies[proxy][:has_sip_ipv4] = @proxies[proxy][:ip_type_preference].include?(:ipv4)
|
157
|
+
@proxies[proxy][:has_sip_ipv6] = @proxies[proxy][:ip_type_preference].include?(:ipv6)
|
158
|
+
@proxies[proxy][:has_sip_udp] = @proxies[proxy][:transport_preference].include?(:udp)
|
159
|
+
@proxies[proxy][:has_sip_tcp] = @proxies[proxy][:transport_preference].include?(:tcp)
|
160
|
+
@proxies[proxy][:has_sip_tls] = @proxies[proxy][:transport_preference].include?(:tls)
|
161
|
+
|
162
|
+
# Add a hash for the DNS cache.
|
163
|
+
@proxies[proxy][:dns_cache] = {} if @proxies[proxy][:use_dns_cache]
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
end
|
168
|
+
|
169
|
+
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
|