oversip 1.1.2 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/etc/server.rb +34 -23
- data/ext/stun/stun_ruby.c +7 -4
- data/ext/utils/utils_ruby.c +9 -0
- data/lib/oversip/config.rb +22 -15
- data/lib/oversip/default_server.rb +13 -9
- data/lib/oversip/launcher.rb +62 -7
- data/lib/oversip/logger.rb +0 -9
- data/lib/oversip/master_process.rb +4 -7
- data/lib/oversip/modules/outbound_mangling.rb +60 -0
- data/lib/oversip/modules/user_assertion.rb +73 -0
- data/lib/oversip/posix_mq.rb +8 -8
- data/lib/oversip/proxies_config.rb +1 -1
- data/lib/oversip/sip/core.rb +189 -0
- data/lib/oversip/sip/grammar/name_addr.rb +4 -0
- data/lib/oversip/sip/grammar/uri.rb +25 -1
- data/lib/oversip/sip/launcher.rb +1 -4
- data/lib/oversip/sip/listeners/udp_connection.rb +2 -2
- data/lib/oversip/sip/message_processor.rb +1 -1
- data/lib/oversip/sip/proxy.rb +22 -6
- data/lib/oversip/sip/request.rb +16 -1
- data/lib/oversip/sip/response.rb +7 -0
- data/lib/oversip/sip/rfc3263.rb +2 -4
- data/lib/oversip/syslogger_process.rb +0 -2
- data/lib/oversip/system_callbacks.rb +45 -0
- data/lib/oversip/tls.rb +1 -4
- data/lib/oversip/utils.rb +10 -5
- data/lib/oversip/version.rb +2 -2
- data/lib/oversip/websocket/launcher.rb +1 -3
- data/lib/oversip.rb +9 -0
- data/test/test_uri.rb +11 -4
- metadata +23 -22
- data/lib/oversip/sip/modules/core.rb +0 -194
- data/lib/oversip/sip/modules/registrar_without_path.rb +0 -72
- data/lib/oversip/sip/modules/user_assertion.rb +0 -77
data/etc/server.rb
CHANGED
@@ -19,13 +19,15 @@ module MyExampleApp
|
|
19
19
|
# Custom configuration options:
|
20
20
|
|
21
21
|
# Set this to _true_ if the SIP registrar behind OverSIP does not support Path.
|
22
|
-
|
22
|
+
# OverSIP::Modules::OutboundMangling methods will be used.
|
23
|
+
DO_OUTBOUND_MANGLING = true
|
23
24
|
|
24
25
|
# Set this to _true_ if the SIP proxy/server behind OverSIP performing the authentication
|
25
26
|
# is ready to accept a P-Asserted-Identity header from OverSIP indicating the already
|
26
27
|
# asserted SIP user of the client's connection (this avoids authenticating all the requests
|
27
28
|
# but the first one).
|
28
|
-
|
29
|
+
# OverSIP::Modules::UserAssertion methods will be used.
|
30
|
+
DO_USER_ASSERTION = true
|
29
31
|
end
|
30
32
|
|
31
33
|
|
@@ -34,14 +36,23 @@ end
|
|
34
36
|
### OverSIP System Events:
|
35
37
|
|
36
38
|
|
37
|
-
# This
|
39
|
+
# This method is called when the main configuration files have been loaded.
|
40
|
+
# Place here 3rd party modules initializer code.
|
41
|
+
# This method is not executed again when OverSIP is reloaded (HUP signal).
|
42
|
+
#
|
43
|
+
# def (OverSIP::SystemEvents).on_initialize
|
44
|
+
# [...]
|
45
|
+
# end
|
46
|
+
|
47
|
+
|
48
|
+
# This method is called once the OverSIP reactor has been started.
|
38
49
|
#
|
39
50
|
# def (OverSIP::SystemEvents).on_started
|
40
51
|
# [...]
|
41
52
|
# end
|
42
53
|
|
43
54
|
|
44
|
-
# This
|
55
|
+
# This method is called when a USR1 signal is received by OverSIP main
|
45
56
|
# process and allows the user to set custom code to be executed
|
46
57
|
# or reloaded.
|
47
58
|
#
|
@@ -50,7 +61,7 @@ end
|
|
50
61
|
# end
|
51
62
|
|
52
63
|
|
53
|
-
# This
|
64
|
+
# This method is called after OverSIP has been terminated. It's called
|
54
65
|
# with argument "error" which is _true_ in case OverSIP has died in an
|
55
66
|
# unexpected way.
|
56
67
|
#
|
@@ -64,7 +75,7 @@ end
|
|
64
75
|
### OverSIP SIP Events:
|
65
76
|
|
66
77
|
|
67
|
-
# This
|
78
|
+
# This method is called when a SIP request is received.
|
68
79
|
#
|
69
80
|
def (OverSIP::SipEvents).on_request request
|
70
81
|
|
@@ -107,9 +118,9 @@ def (OverSIP::SipEvents).on_request request
|
|
107
118
|
return
|
108
119
|
end
|
109
120
|
|
110
|
-
if MyExampleApp::
|
121
|
+
if MyExampleApp::DO_OUTBOUND_MANGLING
|
111
122
|
# Extract the Outbound flow token from the RURI.
|
112
|
-
::OverSIP::
|
123
|
+
::OverSIP::Modules::OutboundMangling.extract_outbound_from_ruri request
|
113
124
|
end
|
114
125
|
|
115
126
|
# The request goes to a client using Outbound through OverSIP.
|
@@ -149,8 +160,8 @@ def (OverSIP::SipEvents).on_request request
|
|
149
160
|
|
150
161
|
when :INVITE, :MESSAGE, :OPTIONS, :SUBSCRIBE, :PUBLISH, :REFER
|
151
162
|
|
152
|
-
if MyExampleApp::
|
153
|
-
::OverSIP::
|
163
|
+
if MyExampleApp::DO_USER_ASSERTION
|
164
|
+
::OverSIP::Modules::UserAssertion.add_pai request
|
154
165
|
end
|
155
166
|
|
156
167
|
proxy = ::OverSIP::SIP::Proxy.new :proxy_out
|
@@ -180,32 +191,32 @@ def (OverSIP::SipEvents).on_request request
|
|
180
191
|
|
181
192
|
when :REGISTER
|
182
193
|
|
183
|
-
if MyExampleApp::
|
194
|
+
if MyExampleApp::DO_OUTBOUND_MANGLING
|
184
195
|
# Contact mangling for the case in which the registrar does not support Path.
|
185
|
-
::OverSIP::
|
196
|
+
::OverSIP::Modules::OutboundMangling.add_outbound_to_contact request
|
186
197
|
end
|
187
198
|
|
188
199
|
proxy = ::OverSIP::SIP::Proxy.new :proxy_out
|
189
200
|
|
190
201
|
proxy.on_success_response do |response|
|
191
|
-
if MyExampleApp::
|
202
|
+
if MyExampleApp::DO_OUTBOUND_MANGLING
|
192
203
|
# Undo changes done to the Contact header provided by the client, so it receives
|
193
204
|
# the same value in the 200 response from the registrar.
|
194
|
-
::OverSIP::
|
205
|
+
::OverSIP::Modules::OutboundMangling.remove_outbound_from_contact response
|
195
206
|
end
|
196
207
|
|
197
|
-
if MyExampleApp::
|
208
|
+
if MyExampleApp::DO_USER_ASSERTION
|
198
209
|
# The registrar replies 200 after a REGISTER with credentials so let's assert
|
199
210
|
# the current SIP user to this connection.
|
200
|
-
::OverSIP::
|
211
|
+
::OverSIP::Modules::UserAssertion.assert_connection response
|
201
212
|
end
|
202
213
|
end
|
203
214
|
|
204
215
|
proxy.on_failure_response do |response|
|
205
|
-
if MyExampleApp::
|
216
|
+
if MyExampleApp::DO_USER_ASSERTION
|
206
217
|
# We don't add PAI for re-REGISTER, so 401 will be replied, and after it let's
|
207
218
|
# revoke the current user assertion (will be re-added upon REGISTER with credentials).
|
208
|
-
::OverSIP::
|
219
|
+
::OverSIP::Modules::UserAssertion.revoke_assertion response
|
209
220
|
end
|
210
221
|
end
|
211
222
|
|
@@ -223,7 +234,7 @@ def (OverSIP::SipEvents).on_request request
|
|
223
234
|
end
|
224
235
|
|
225
236
|
|
226
|
-
# This
|
237
|
+
# This method is called when a client initiates a SIP TLS handshake.
|
227
238
|
def (OverSIP::SipEvents).on_client_tls_handshake connection, pems
|
228
239
|
|
229
240
|
log_info "validating TLS connection from IP #{connection.remote_ip} and port #{connection.remote_port}"
|
@@ -241,7 +252,7 @@ def (OverSIP::SipEvents).on_client_tls_handshake connection, pems
|
|
241
252
|
end
|
242
253
|
|
243
254
|
|
244
|
-
# This
|
255
|
+
# This method is called when conntacting a SIP TLS server and the TLS handshake takes place.
|
245
256
|
def (OverSIP::SipEvents).on_server_tls_handshake connection, pems
|
246
257
|
|
247
258
|
log_info "validating TLS connection to IP #{connection.remote_ip} and port #{connection.remote_port}"
|
@@ -264,7 +275,7 @@ end
|
|
264
275
|
### OverSIP WebSocket Events:
|
265
276
|
|
266
277
|
|
267
|
-
# This
|
278
|
+
# This method is called when a new WebSocket connection is being requested.
|
268
279
|
# Here you can inspect the connection and the HTTP GET request. If you
|
269
280
|
# decide not to accept this connection then call to:
|
270
281
|
#
|
@@ -279,7 +290,7 @@ end
|
|
279
290
|
# end
|
280
291
|
|
281
292
|
|
282
|
-
# This
|
293
|
+
# This method is called when a WebSocket connection is closed. The connection
|
283
294
|
# is given as first argument along with a second argument "client_closed" which
|
284
295
|
# is _true_ in case the WebSocket connection was closed by the client.
|
285
296
|
#
|
@@ -288,7 +299,7 @@ end
|
|
288
299
|
# end
|
289
300
|
|
290
301
|
|
291
|
-
# This
|
302
|
+
# This method is called when a client initiates a WebSocket TLS handshake.
|
292
303
|
def (OverSIP::WebSocketEvents).on_client_tls_handshake connection, pems
|
293
304
|
|
294
305
|
log_info "validating TLS connection from IP #{connection.remote_ip} and port #{connection.remote_port}"
|
data/ext/stun/stun_ruby.c
CHANGED
@@ -54,7 +54,7 @@ static VALUE mStun;
|
|
54
54
|
VALUE Stun_parse_request(VALUE self, VALUE rb_stun_request, VALUE rb_source_ip, VALUE rb_source_port)
|
55
55
|
{
|
56
56
|
TRACE();
|
57
|
-
|
57
|
+
|
58
58
|
char *request = NULL;
|
59
59
|
size_t request_len = 0;
|
60
60
|
char *source_ip = NULL;
|
@@ -228,7 +228,8 @@ VALUE Stun_parse_request(VALUE self, VALUE rb_stun_request, VALUE rb_source_ip,
|
|
228
228
|
break;
|
229
229
|
/* Not valid INET family, hummmm. */
|
230
230
|
case -1:
|
231
|
-
|
231
|
+
LOG("ERROR: Family AF_INET (IPv4) not supported\n");
|
232
|
+
return Qfalse;
|
232
233
|
break;
|
233
234
|
/* Let's check with IPv6. */
|
234
235
|
case 0:
|
@@ -239,11 +240,13 @@ VALUE Stun_parse_request(VALUE self, VALUE rb_stun_request, VALUE rb_source_ip,
|
|
239
240
|
break;
|
240
241
|
/* Not valid INET family, hummmm. */
|
241
242
|
case -1:
|
242
|
-
|
243
|
+
LOG("ERROR: Family AF_INET6 (IPv6) not supported\n");
|
244
|
+
return Qfalse;
|
243
245
|
break;
|
244
246
|
/* The string is neither an IPv4 or IPv6. */
|
245
247
|
case 0:
|
246
|
-
|
248
|
+
LOG("ERROR: Unknown Address Family\n");
|
249
|
+
return Qfalse;
|
247
250
|
break;
|
248
251
|
}
|
249
252
|
}
|
data/ext/utils/utils_ruby.c
CHANGED
@@ -228,6 +228,8 @@ VALUE Utils_normalize_ipv6(int argc, VALUE *argv, VALUE self)
|
|
228
228
|
* - Second argument is the type of host (:ipv4, :ipv6, :ipv6_reference or :domain).
|
229
229
|
* - Third argument is optional. If true, returned value is a pure IPv6 even
|
230
230
|
* if the first argument is a IPv6 reference.
|
231
|
+
*
|
232
|
+
* TODO: Not in use and seems really ugly!
|
231
233
|
*/
|
232
234
|
VALUE Utils_normalize_host(int argc, VALUE *argv, VALUE self)
|
233
235
|
{
|
@@ -259,6 +261,8 @@ VALUE Utils_normalize_host(int argc, VALUE *argv, VALUE self)
|
|
259
261
|
/*
|
260
262
|
* If the given argument is a IPV6 reference it returns a new string with the pure IPv6.
|
261
263
|
* In any other case, return the given argument.
|
264
|
+
*
|
265
|
+
* TODO: Not documented in the API (seems ugly).
|
262
266
|
*/
|
263
267
|
VALUE Utils_to_pure_ip(VALUE self, VALUE string)
|
264
268
|
{
|
@@ -273,6 +277,11 @@ VALUE Utils_to_pure_ip(VALUE self, VALUE string)
|
|
273
277
|
}
|
274
278
|
|
275
279
|
|
280
|
+
/*
|
281
|
+
* TODO: We lack a simple "normalice_host(ip)" method that parses the given ip and so on...
|
282
|
+
*/
|
283
|
+
|
284
|
+
|
276
285
|
/*
|
277
286
|
* Expects a string like "1.2.3.4_5060" or "1af:43::ab_9090" and returns
|
278
287
|
* an Array as follows:
|
data/lib/oversip/config.rb
CHANGED
@@ -8,9 +8,9 @@ module OverSIP
|
|
8
8
|
extend ::OverSIP::Logger
|
9
9
|
extend ::OverSIP::Config::Validators
|
10
10
|
|
11
|
-
DEFAULT_CONFIG_DIR = "/etc/oversip
|
12
|
-
DEFAULT_TLS_DIR = "tls
|
13
|
-
DEFAULT_TLS_CA_DIR = "tls/ca
|
11
|
+
DEFAULT_CONFIG_DIR = "/etc/oversip"
|
12
|
+
DEFAULT_TLS_DIR = "tls"
|
13
|
+
DEFAULT_TLS_CA_DIR = "tls/ca"
|
14
14
|
DEFAULT_CONFIG_FILE = "oversip.conf"
|
15
15
|
PROXIES_FILE = "proxies.conf"
|
16
16
|
SERVER_FILE = "server.rb"
|
@@ -127,27 +127,31 @@ module OverSIP
|
|
127
127
|
@proxies_file = ::File.join(@config_dir, PROXIES_FILE)
|
128
128
|
@server_file = ::File.join(@config_dir, SERVER_FILE)
|
129
129
|
|
130
|
+
# Load the oversip.conf YAML file.
|
130
131
|
begin
|
131
132
|
conf_yaml = ::YAML.load_file @config_file
|
132
133
|
rescue ::Exception => e
|
133
134
|
log_system_crit "error loading Main Configuration file '#{@config_file}':"
|
134
|
-
fatal e
|
135
|
+
::OverSIP::Launcher.fatal e
|
135
136
|
end
|
136
137
|
|
138
|
+
# Load the proxies.conf YAML file.
|
137
139
|
begin
|
138
140
|
proxies_yaml = ::YAML.load_file @proxies_file
|
139
141
|
rescue ::Exception => e
|
140
142
|
log_system_crit "error loading Proxies Configuration file '#{@proxies_file}':"
|
141
|
-
fatal e
|
143
|
+
::OverSIP::Launcher.fatal e
|
142
144
|
end
|
143
145
|
|
146
|
+
# Load the server.rb file.
|
144
147
|
begin
|
145
|
-
|
148
|
+
require @server_file
|
146
149
|
rescue ::Exception => e
|
147
150
|
log_system_crit "error loading Server file '#{@server_file}':"
|
148
|
-
fatal e
|
151
|
+
::OverSIP::Launcher.fatal e
|
149
152
|
end
|
150
153
|
|
154
|
+
# Process the oversip.conf file.
|
151
155
|
begin
|
152
156
|
pre_check(conf_yaml)
|
153
157
|
|
@@ -158,18 +162,18 @@ module OverSIP
|
|
158
162
|
|
159
163
|
if values == nil
|
160
164
|
if validations.include? :required
|
161
|
-
fatal "#{section}[#{parameter}] requires a value"
|
165
|
+
::OverSIP::Launcher.fatal "#{section}[#{parameter}] requires a value"
|
162
166
|
end
|
163
167
|
next
|
164
168
|
end
|
165
169
|
|
166
170
|
if values.is_a? ::Array
|
167
171
|
unless validations.include? :multi_value
|
168
|
-
fatal "#{section}[#{parameter}] does not allow multiple values"
|
172
|
+
::OverSIP::Launcher.fatal "#{section}[#{parameter}] does not allow multiple values"
|
169
173
|
end
|
170
174
|
|
171
175
|
if validations.include? :non_empty and values.empty?
|
172
|
-
fatal "#{section}[#{parameter}] does not allow empty values"
|
176
|
+
::OverSIP::Launcher.fatal "#{section}[#{parameter}] does not allow empty values"
|
173
177
|
end
|
174
178
|
end
|
175
179
|
|
@@ -188,7 +192,7 @@ module OverSIP
|
|
188
192
|
next if [:required, :multi_value, :non_empty].include? validation
|
189
193
|
|
190
194
|
unless send validation, value, *args
|
191
|
-
fatal "#{section}[#{parameter}] has invalid value '#{humanize_value value}' (does not satisfy '#{validation}' validation requirement)"
|
195
|
+
::OverSIP::Launcher.fatal "#{section}[#{parameter}] has invalid value '#{humanize_value value}' (does not satisfy '#{validation}' validation requirement)"
|
192
196
|
end
|
193
197
|
end
|
194
198
|
|
@@ -202,20 +206,21 @@ module OverSIP
|
|
202
206
|
post_check
|
203
207
|
|
204
208
|
rescue ::OverSIP::ConfigurationError => e
|
205
|
-
fatal "configuration error: #{e.message}"
|
209
|
+
::OverSIP::Launcher.fatal "configuration error: #{e.message}"
|
206
210
|
rescue => e
|
207
|
-
fatal e
|
211
|
+
::OverSIP::Launcher.fatal e
|
208
212
|
end
|
209
213
|
|
210
214
|
::OverSIP.configuration = @configuration
|
211
215
|
|
216
|
+
# Process the proxies.conf file.
|
212
217
|
begin
|
213
218
|
::OverSIP::ProxiesConfig.load proxies_yaml
|
214
219
|
rescue ::OverSIP::ConfigurationError => e
|
215
|
-
fatal "error loading Proxies Configuration file '#{@proxies_file}': #{e.message}"
|
220
|
+
::OverSIP::Launcher.fatal "error loading Proxies Configuration file '#{@proxies_file}': #{e.message}"
|
216
221
|
rescue ::Exception => e
|
217
222
|
log_system_crit "error loading Proxies Configuration file '#{@proxies_file}':"
|
218
|
-
fatal e
|
223
|
+
::OverSIP::Launcher.fatal e
|
219
224
|
end
|
220
225
|
end
|
221
226
|
|
@@ -551,6 +556,7 @@ module OverSIP
|
|
551
556
|
def self.system_reload
|
552
557
|
log_system_notice "reloading OverSIP..."
|
553
558
|
|
559
|
+
# Load and process the proxies.conf file.
|
554
560
|
begin
|
555
561
|
proxies_yaml = ::YAML.load_file @proxies_file
|
556
562
|
::OverSIP::ProxiesConfig.load proxies_yaml, reload=true
|
@@ -562,6 +568,7 @@ module OverSIP
|
|
562
568
|
log_system_crit e
|
563
569
|
end
|
564
570
|
|
571
|
+
# Load the server.rb file.
|
565
572
|
begin
|
566
573
|
::Kernel.load @server_file
|
567
574
|
log_system_notice "Server file '#{@server_file}' reloaded"
|
@@ -4,16 +4,20 @@ module OverSIP
|
|
4
4
|
|
5
5
|
extend ::OverSIP::Logger
|
6
6
|
|
7
|
+
def self.on_initialize
|
8
|
+
log_system_notice "on_initialize() method is not defined"
|
9
|
+
end
|
10
|
+
|
7
11
|
def self.on_started
|
8
|
-
log_system_notice "on_started()
|
12
|
+
log_system_notice "on_started() method is not defined"
|
9
13
|
end
|
10
14
|
|
11
15
|
def self.on_user_reload
|
12
|
-
log_system_notice "on_user_reload()
|
16
|
+
log_system_notice "on_user_reload() method is not defined"
|
13
17
|
end
|
14
18
|
|
15
19
|
def self.on_terminated error
|
16
|
-
log_system_notice "on_terminated()
|
20
|
+
log_system_notice "on_terminated() method is not defined"
|
17
21
|
end
|
18
22
|
|
19
23
|
|
@@ -24,15 +28,15 @@ module OverSIP
|
|
24
28
|
extend ::OverSIP::Logger
|
25
29
|
|
26
30
|
def self.on_request request
|
27
|
-
log_system_notice "on_request()
|
31
|
+
log_system_notice "on_request() method is not defined"
|
28
32
|
end
|
29
33
|
|
30
34
|
def self.on_client_tls_handshake connection, pems
|
31
|
-
log_system_notice "on_client_tls_handshake()
|
35
|
+
log_system_notice "on_client_tls_handshake() method is not defined"
|
32
36
|
end
|
33
37
|
|
34
38
|
def self.on_server_tls_handshake connection, pems
|
35
|
-
log_system_notice "on_server_tls_handshake()
|
39
|
+
log_system_notice "on_server_tls_handshake() method is not defined"
|
36
40
|
end
|
37
41
|
|
38
42
|
end
|
@@ -42,15 +46,15 @@ module OverSIP
|
|
42
46
|
extend ::OverSIP::Logger
|
43
47
|
|
44
48
|
def self.on_connection connection, http_request
|
45
|
-
log_system_notice "on_connection()
|
49
|
+
log_system_notice "on_connection() method is not defined"
|
46
50
|
end
|
47
51
|
|
48
52
|
def self.on_disconnection connection, client_closed
|
49
|
-
log_system_notice "on_disconnection()
|
53
|
+
log_system_notice "on_disconnection() method is not defined"
|
50
54
|
end
|
51
55
|
|
52
56
|
def self.on_client_tls_handshake connection, pems
|
53
|
-
log_system_notice "on_client_tls_handshake()
|
57
|
+
log_system_notice "on_client_tls_handshake() method is not defined"
|
54
58
|
end
|
55
59
|
|
56
60
|
end
|
data/lib/oversip/launcher.rb
CHANGED
@@ -2,7 +2,7 @@ module OverSIP::Launcher
|
|
2
2
|
|
3
3
|
extend ::OverSIP::Logger
|
4
4
|
|
5
|
-
READY_PIPE_TIMEOUT =
|
5
|
+
READY_PIPE_TIMEOUT = 8
|
6
6
|
|
7
7
|
@log_id = "launcher"
|
8
8
|
|
@@ -54,6 +54,7 @@ module OverSIP::Launcher
|
|
54
54
|
master_ok = (rd.read(2) rescue nil)
|
55
55
|
end
|
56
56
|
rescue ::Timeout::Error
|
57
|
+
log_system_crit "master process is not ready within #{READY_PIPE_TIMEOUT/2} seconds, killing it..."
|
57
58
|
begin
|
58
59
|
::Process.kill(:TERM, master_pid)
|
59
60
|
10.times do |i|
|
@@ -65,7 +66,7 @@ module OverSIP::Launcher
|
|
65
66
|
::Process.kill(:KILL, master_pid) rescue nil
|
66
67
|
rescue ::Errno::ESRCH
|
67
68
|
end
|
68
|
-
fatal "master process
|
69
|
+
fatal "master process killed"
|
69
70
|
end
|
70
71
|
unless master_ok == "ok"
|
71
72
|
fatal "master process failed to start"
|
@@ -279,8 +280,28 @@ module OverSIP::Launcher
|
|
279
280
|
|
280
281
|
log_system_info "reactor running"
|
281
282
|
|
282
|
-
# Run the user provided
|
283
|
-
log_system_info "calling OverSIP::SystemEvents.
|
283
|
+
# Run the user provided on_initialize method.
|
284
|
+
log_system_info "calling OverSIP::SystemEvents.on_initialize() method..."
|
285
|
+
begin
|
286
|
+
::OverSIP::SystemEvents.on_initialize
|
287
|
+
rescue ::Exception => e
|
288
|
+
log_system_crit "error calling OverSIP::SystemEvents.on_initialize():"
|
289
|
+
fatal e
|
290
|
+
end
|
291
|
+
|
292
|
+
# Run the on_started provided callbacks.
|
293
|
+
log_system_info "executing OverSIP::SystemCallbacks.on_started_callbacks..."
|
294
|
+
::OverSIP::SystemCallbacks.on_started_callbacks.each do |cb|
|
295
|
+
begin
|
296
|
+
cb.call
|
297
|
+
rescue ::Exception => e
|
298
|
+
log_system_crit "error executing a callback in OverSIP::SystemCallbacks.on_started_callbacks:"
|
299
|
+
fatal e
|
300
|
+
end
|
301
|
+
end
|
302
|
+
|
303
|
+
# Run the user provided on_started method.
|
304
|
+
log_system_info "calling OverSIP::SystemEvents.on_started() method..."
|
284
305
|
begin
|
285
306
|
::OverSIP::SystemEvents.on_started
|
286
307
|
rescue ::Exception => e
|
@@ -323,6 +344,14 @@ module OverSIP::Launcher
|
|
323
344
|
end # def self.run
|
324
345
|
|
325
346
|
|
347
|
+
def self.fatal msg
|
348
|
+
log_system_crit msg
|
349
|
+
log_system_crit "exiting with error status"
|
350
|
+
|
351
|
+
terminate error=true, fatal=true
|
352
|
+
end
|
353
|
+
|
354
|
+
|
326
355
|
def self.create_pid_file(path)
|
327
356
|
# Check that the PID file is accesible.
|
328
357
|
begin
|
@@ -424,11 +453,22 @@ module OverSIP::Launcher
|
|
424
453
|
trap :HUP do
|
425
454
|
log_system_notice "HUP signal received, reloading configuration files..."
|
426
455
|
::OverSIP::Config.system_reload
|
456
|
+
|
457
|
+
# Run the on_reload provided callbacks.
|
458
|
+
log_system_info "executing OverSIP::SystemCallbacks.on_reload_callbacks..."
|
459
|
+
::OverSIP::SystemCallbacks.on_reload_callbacks.each do |cb|
|
460
|
+
begin
|
461
|
+
cb.call
|
462
|
+
rescue ::Exception => e
|
463
|
+
log_system_crit "error executing a callback in OverSIP::SystemCallbacks.on_reload_callbacks:"
|
464
|
+
log_system_crit e
|
465
|
+
end
|
466
|
+
end
|
427
467
|
end
|
428
468
|
|
429
469
|
# Signal USR1 reloads custom code provided by the user.
|
430
470
|
trap :USR1 do
|
431
|
-
log_system_notice "USR1 signal received, calling OverSIP::SystemEvents.on_user_reload()..."
|
471
|
+
log_system_notice "USR1 signal received, calling OverSIP::SystemEvents.on_user_reload() method..."
|
432
472
|
# Run the user provided on_started callback.
|
433
473
|
begin
|
434
474
|
::OverSIP::SystemEvents.on_user_reload
|
@@ -447,9 +487,24 @@ module OverSIP::Launcher
|
|
447
487
|
|
448
488
|
|
449
489
|
def self.terminate error=false, fatal=false
|
490
|
+
# Trap TERM/QUIT signals (we are already exiting).
|
491
|
+
trap(:TERM) {}
|
492
|
+
trap(:QUIT) {}
|
493
|
+
|
450
494
|
unless fatal
|
451
|
-
# Run the
|
452
|
-
log_system_info "
|
495
|
+
# Run the on_terminated provided callbacks.
|
496
|
+
log_system_info "executing OverSIP::SystemCallbacks.on_terminated_callbacks..."
|
497
|
+
::OverSIP::SystemCallbacks.on_terminated_callbacks.each do |cb|
|
498
|
+
begin
|
499
|
+
cb.call error
|
500
|
+
rescue ::Exception => e
|
501
|
+
log_system_crit "error executing a callback in OverSIP::SystemCallbacks.on_terminated_callbacks:"
|
502
|
+
log_system_crit e
|
503
|
+
end
|
504
|
+
end
|
505
|
+
|
506
|
+
# Run the user provided on_terminated method.
|
507
|
+
log_system_info "calling OverSIP::SystemEvents.on_terminated() method..."
|
453
508
|
begin
|
454
509
|
::OverSIP::SystemEvents.on_terminated error
|
455
510
|
rescue ::Exception => e
|
data/lib/oversip/logger.rb
CHANGED
@@ -108,15 +108,6 @@ module OverSIP
|
|
108
108
|
end
|
109
109
|
|
110
110
|
end # .each
|
111
|
-
|
112
|
-
# A convenient method to ensure that fatal logs are properly logged and program
|
113
|
-
# exited with error status.
|
114
|
-
def fatal msg
|
115
|
-
log_system_crit msg
|
116
|
-
log_system_crit "exiting with error status"
|
117
|
-
|
118
|
-
::OverSIP::Launcher.terminate error=true, fatal=true
|
119
|
-
end
|
120
111
|
end
|
121
112
|
|
122
113
|
# Generate nice log messages. It accepst three parameters:
|
@@ -10,8 +10,6 @@ require "openssl"
|
|
10
10
|
|
11
11
|
# Ruby external gems.
|
12
12
|
|
13
|
-
gem "eventmachine-le", ">= 1.1.3"
|
14
|
-
require "eventmachine-le"
|
15
13
|
gem "iobuffer", ">= 1.1.2"
|
16
14
|
require "iobuffer"
|
17
15
|
gem "em-udns", ">= 0.3.6"
|
@@ -27,6 +25,7 @@ require "posix-spawn"
|
|
27
25
|
require "oversip/sip/sip.rb"
|
28
26
|
require "oversip/sip/sip_parser.so"
|
29
27
|
require "oversip/sip/constants.rb"
|
28
|
+
require "oversip/sip/core.rb"
|
30
29
|
require "oversip/sip/message.rb"
|
31
30
|
require "oversip/sip/request.rb"
|
32
31
|
require "oversip/sip/response.rb"
|
@@ -53,13 +52,11 @@ require "oversip/websocket/ws_framing_utils.so"
|
|
53
52
|
require "oversip/websocket/ws_framing.rb"
|
54
53
|
require "oversip/websocket/ws_sip_app.rb"
|
55
54
|
|
56
|
-
require "oversip/sip/modules/core.rb"
|
57
|
-
require "oversip/sip/modules/user_assertion.rb"
|
58
|
-
require "oversip/sip/modules/registrar_without_path.rb"
|
59
|
-
|
60
|
-
require "oversip/default_server.rb"
|
61
55
|
require "oversip/fiber_pool.rb"
|
62
56
|
require "oversip/tls.rb"
|
63
57
|
require "oversip/stun.so"
|
64
58
|
|
59
|
+
require "oversip/modules/user_assertion.rb"
|
60
|
+
require "oversip/modules/outbound_mangling.rb"
|
61
|
+
|
65
62
|
require "oversip/ruby_ext/eventmachine.rb"
|
@@ -0,0 +1,60 @@
|
|
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 request
|
10
|
+
if request.contact and request.connection_outbound_flow_token
|
11
|
+
log_system_debug "performing Contact mangling (adding ;ov-ob Outbound param) for #{request.log_id}" if $oversip_debug
|
12
|
+
|
13
|
+
# Add the ;ov-ob param to the Contact URI.
|
14
|
+
request.contact.set_param "ov-ob", request.connection_outbound_flow_token
|
15
|
+
return true
|
16
|
+
else
|
17
|
+
return false
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.extract_outbound_from_ruri request
|
22
|
+
# Do nothing if the request already contains a Route header with the Outbound flow token (so
|
23
|
+
# the registrar *does* support Path).
|
24
|
+
unless request.incoming_outbound_requested?
|
25
|
+
if (ov_ob = request.ruri.del_param("ov-ob"))
|
26
|
+
log_system_debug "incoming Outbound flow token extracted from ;ov-ob param in RURI for #{request.log_id}" if $oversip_debug
|
27
|
+
request.route_outbound_flow_token = ov_ob
|
28
|
+
request.incoming_outbound_requested = true
|
29
|
+
return true
|
30
|
+
else
|
31
|
+
return false
|
32
|
+
end
|
33
|
+
|
34
|
+
else
|
35
|
+
# If the request already contains a proper Outbound Route header, then at least try to remove
|
36
|
+
# the ;ov-ob param from the RURI.
|
37
|
+
request.ruri.del_param("ov-ob")
|
38
|
+
return false
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.remove_outbound_from_contact message
|
43
|
+
unless message.is_a? ::OverSIP::SIP::Message
|
44
|
+
raise ::OverSIP::RuntimeError, "message must be a OverSIP::SIP::Request or OverSIP::SIP::Response"
|
45
|
+
end
|
46
|
+
|
47
|
+
if (contacts = message.headers["Contact"])
|
48
|
+
log_system_debug "reverting original Contact value (removing ;ov-ob Outbound param) for response" if $oversip_debug
|
49
|
+
contacts.each do |contact|
|
50
|
+
contact.gsub! /;ov-ob=[_\-0-9A-Za-z]+/, ""
|
51
|
+
end
|
52
|
+
return true
|
53
|
+
else
|
54
|
+
return false
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
end # module OutboundMangling
|
59
|
+
|
60
|
+
end
|