oversip 1.2.1 → 1.3.0.dev1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. data/README.md +28 -4
  2. data/bin/oversip +1 -1
  3. data/etc/proxies.conf +10 -0
  4. data/etc/server.rb +13 -9
  5. data/ext/utils/haproxy_protocol.c +0 -3
  6. data/ext/utils/outbound_utils.c +1 -1
  7. data/ext/utils/utils_ruby.c +0 -1
  8. data/ext/websocket_http_parser/ws_http_parser.c +940 -1903
  9. data/ext/websocket_http_parser/ws_http_parser.h +1 -0
  10. data/lib/oversip/config_validators.rb +2 -2
  11. data/lib/oversip/launcher.rb +275 -240
  12. data/lib/oversip/master_process.rb +7 -2
  13. data/lib/oversip/proxies_config.rb +8 -1
  14. data/lib/oversip/sip/client.rb +304 -0
  15. data/lib/oversip/sip/client_transaction.rb +31 -36
  16. data/lib/oversip/sip/core.rb +7 -4
  17. data/lib/oversip/sip/launcher.rb +30 -30
  18. data/lib/oversip/sip/listeners/connection.rb +4 -0
  19. data/lib/oversip/sip/listeners/ipv4_tcp_server.rb +1 -0
  20. data/lib/oversip/sip/listeners/ipv4_tls_server.rb +1 -0
  21. data/lib/oversip/sip/listeners/ipv4_tls_tunnel_server.rb +1 -0
  22. data/lib/oversip/sip/listeners/ipv4_udp_server.rb +1 -0
  23. data/lib/oversip/sip/listeners/ipv6_tcp_server.rb +1 -0
  24. data/lib/oversip/sip/listeners/ipv6_tls_server.rb +1 -0
  25. data/lib/oversip/sip/listeners/ipv6_tls_tunnel_server.rb +1 -0
  26. data/lib/oversip/sip/listeners/ipv6_udp_server.rb +1 -0
  27. data/lib/oversip/sip/listeners/tcp_client.rb +26 -0
  28. data/lib/oversip/sip/listeners/tcp_connection.rb +7 -1
  29. data/lib/oversip/sip/listeners/tcp_server.rb +1 -1
  30. data/lib/oversip/sip/listeners/tls_client.rb +28 -24
  31. data/lib/oversip/sip/listeners/tls_server.rb +25 -8
  32. data/lib/oversip/sip/listeners/tls_tunnel_connection.rb +1 -24
  33. data/lib/oversip/sip/message.rb +2 -2
  34. data/lib/oversip/sip/message_processor.rb +23 -13
  35. data/lib/oversip/sip/{grammar/name_addr.rb → name_addr.rb} +11 -0
  36. data/lib/oversip/sip/proxy.rb +53 -227
  37. data/lib/oversip/sip/request.rb +15 -11
  38. data/lib/oversip/sip/response.rb +3 -3
  39. data/lib/oversip/sip/rfc3263.rb +2 -3
  40. data/lib/oversip/sip/tags.rb +1 -1
  41. data/lib/oversip/sip/transport_manager.rb +6 -5
  42. data/lib/oversip/sip/uac.rb +93 -0
  43. data/lib/oversip/sip/uac_request.rb +82 -0
  44. data/lib/oversip/sip/{grammar/uri.rb → uri.rb} +22 -0
  45. data/lib/oversip/version.rb +3 -3
  46. data/lib/oversip/websocket/launcher.rb +25 -25
  47. data/lib/oversip/websocket/listeners/connection.rb +4 -0
  48. data/lib/oversip/websocket/listeners/ipv4_ws_server.rb +1 -0
  49. data/lib/oversip/websocket/listeners/ipv4_wss_server.rb +1 -0
  50. data/lib/oversip/websocket/listeners/ipv4_wss_tunnel_server.rb +1 -0
  51. data/lib/oversip/websocket/listeners/ipv6_ws_server.rb +1 -0
  52. data/lib/oversip/websocket/listeners/ipv6_wss_server.rb +1 -0
  53. data/lib/oversip/websocket/listeners/ipv6_wss_tunnel_server.rb +1 -0
  54. data/lib/oversip/websocket/listeners/ws_server.rb +55 -26
  55. data/lib/oversip/websocket/listeners/wss_server.rb +26 -9
  56. data/lib/oversip/websocket/listeners/wss_tunnel_server.rb +14 -11
  57. data/lib/oversip/websocket/ws_framing.rb +6 -2
  58. data/lib/oversip.rb +3 -1
  59. data/test/test_http_parser.rb +3 -3
  60. data/test/test_uri.rb +18 -12
  61. metadata +91 -77
@@ -61,6 +61,7 @@ typedef struct ws_http_request_parser {
61
61
  size_t hdr_value_start;
62
62
  size_t hdr_value_len;
63
63
  size_t query_start;
64
+ size_t fragment_start;
64
65
 
65
66
  /* Request method. */
66
67
  enum method method;
@@ -17,11 +17,11 @@ module OverSIP
17
17
  end
18
18
 
19
19
  def string value
20
- value.is_a? String
20
+ value.is_a? ::String
21
21
  end
22
22
 
23
23
  def fixnum value
24
- value.is_a? Fixnum
24
+ value.is_a? ::Fixnum
25
25
  end
26
26
 
27
27
  def port value
@@ -2,12 +2,12 @@ module OverSIP::Launcher
2
2
 
3
3
  extend ::OverSIP::Logger
4
4
 
5
- READY_PIPE_TIMEOUT = 8
5
+ READY_PIPE_TIMEOUT = 16
6
6
 
7
7
  @log_id = "launcher"
8
8
 
9
9
 
10
- def self.daemonize!(options)
10
+ def self.daemonize! options
11
11
  @log_id = "launcher (daemonize)"
12
12
 
13
13
  $stdin.reopen("/dev/null")
@@ -82,7 +82,7 @@ module OverSIP::Launcher
82
82
  end
83
83
 
84
84
 
85
- def self.run(options)
85
+ def self.run options
86
86
  @log_id = "launcher (run)"
87
87
 
88
88
  configuration = ::OverSIP.configuration
@@ -126,212 +126,87 @@ module OverSIP::Launcher
126
126
 
127
127
  ::EM.run do
128
128
 
129
- log_system_info "using Ruby #{RUBY_VERSION}p#{RUBY_PATCHLEVEL} (#{RUBY_RELEASE_DATE} revision #{RUBY_REVISION}) [#{RUBY_PLATFORM}]"
130
- log_system_info "using EventMachine-LE #{::EM::VERSION}"
131
- log_system_info "starting event reactor..."
129
+ ::OverSIP.is_ready = false
130
+ ::OverSIP.status = :loading
132
131
 
133
- # DNS resolver.
134
- ::OverSIP::SIP::RFC3263.run
135
-
136
- if configuration[:sip][:sip_udp]
137
- # SIP UDP IPv4 server.
138
- if configuration[:sip][:enable_ipv4]
139
- ::OverSIP::SIP::Launcher.run true, :ipv4, configuration[:sip][:listen_ipv4],
140
- configuration[:sip][:listen_port], :udp
141
- end
142
-
143
- # SIP IPv6 UDP server.
144
- if configuration[:sip][:enable_ipv6]
145
- ::OverSIP::SIP::Launcher.run true, :ipv6, configuration[:sip][:listen_ipv6],
146
- configuration[:sip][:listen_port], :udp
147
- end
148
- end
132
+ log_system_notice "using Ruby #{RUBY_VERSION}p#{RUBY_PATCHLEVEL} (#{RUBY_RELEASE_DATE} revision #{RUBY_REVISION}) [#{RUBY_PLATFORM}]"
133
+ log_system_notice "using EventMachine-LE #{::EM::VERSION}"
134
+ log_system_notice "starting event reactor..."
149
135
 
150
- if configuration[:sip][:sip_tcp]
151
- # SIP IPv4 TCP server.
152
- if configuration[:sip][:enable_ipv4]
153
- ::OverSIP::SIP::Launcher.run true, :ipv4, configuration[:sip][:listen_ipv4],
154
- configuration[:sip][:listen_port], :tcp
155
- end
136
+ # Run SIP and WebSocket servers.
137
+ run_servers options
156
138
 
157
- # SIP IPv6 TCP server.
158
- if configuration[:sip][:enable_ipv6]
159
- ::OverSIP::SIP::Launcher.run true, :ipv6, configuration[:sip][:listen_ipv6],
160
- configuration[:sip][:listen_port], :tcp
161
- end
162
- end
139
+ # Run DNS resolver.
140
+ ::OverSIP::SIP::RFC3263.run
163
141
 
164
- if configuration[:sip][:sip_tls]
165
- unless configuration[:sip][:use_tls_tunnel]
166
- # SIP IPv4 TLS server (native).
167
- if configuration[:sip][:enable_ipv4]
168
- ::OverSIP::SIP::Launcher.run true, :ipv4, configuration[:sip][:listen_ipv4],
169
- configuration[:sip][:listen_port_tls], :tls
170
- end
142
+ # Change process permissions if requested.
143
+ set_user_group(options[:user], options[:group])
171
144
 
172
- # SIP IPv6 TLS server (native).
173
- if configuration[:sip][:enable_ipv6]
174
- ::OverSIP::SIP::Launcher.run true, :ipv6, configuration[:sip][:listen_ipv6],
175
- configuration[:sip][:listen_port_tls], :tls
176
- end
177
- else
178
- # SIP IPv4 TLS server (Stud).
179
- if configuration[:sip][:enable_ipv4]
180
- ::OverSIP::SIP::Launcher.run true, :ipv4, "127.0.0.1",
181
- configuration[:sip][:listen_port_tls_tunnel], :tls_tunnel,
182
- configuration[:sip][:listen_ipv4],
183
- configuration[:sip][:listen_port_tls]
184
- ::OverSIP::SIP::Launcher.run false, :ipv4, configuration[:sip][:listen_ipv4],
185
- configuration[:sip][:listen_port_tls], :tls
186
-
187
- # Spawn a Stud process.
188
- spawn_stud_process options,
189
- configuration[:sip][:listen_ipv4], configuration[:sip][:listen_port_tls],
190
- "127.0.0.1", configuration[:sip][:listen_port_tls_tunnel],
191
- ssl = false
192
- end
145
+ # Create PID file.
146
+ create_pid_file(options[:pid_file])
193
147
 
194
- # SIP IPv6 TLS server (Stud).
195
- if configuration[:sip][:enable_ipv6]
196
- ::OverSIP::SIP::Launcher.run true, :ipv6, "::1",
197
- configuration[:sip][:listen_port_tls_tunnel], :tls_tunnel,
198
- configuration[:sip][:listen_ipv6],
199
- configuration[:sip][:listen_port_tls]
200
- ::OverSIP::SIP::Launcher.run false, :ipv6, configuration[:sip][:listen_ipv6],
201
- configuration[:sip][:listen_port_tls], :tls
202
-
203
- # Spawn a Stud process.
204
- spawn_stud_process options,
205
- configuration[:sip][:listen_ipv6], configuration[:sip][:listen_port_tls],
206
- "::1", configuration[:sip][:listen_port_tls_tunnel],
207
- ssl = false
208
- end
209
- end
210
- end
148
+ trap_signals
211
149
 
212
- if configuration[:websocket][:sip_ws]
213
- # WebSocket IPv4 TCP SIP server.
214
- if configuration[:websocket][:enable_ipv4]
215
- ::OverSIP::WebSocket::Launcher.run true, :ipv4, configuration[:websocket][:listen_ipv4],
216
- configuration[:websocket][:listen_port], :ws
217
- end
150
+ # Ensure the code in the next SystemEvents and SystemCallbacks are run serially.
151
+ ::Fiber.new do
218
152
 
219
- # WebSocket IPv6 TCP SIP server.
220
- if configuration[:websocket][:enable_ipv6]
221
- ::OverSIP::WebSocket::Launcher.run true, :ipv6, configuration[:websocket][:listen_ipv6],
222
- configuration[:websocket][:listen_port], :ws
153
+ # Run OverSIP::SystemEvents.on_initialize.
154
+ log_system_notice "calling OverSIP::SystemEvents.on_initialize() method..."
155
+ begin
156
+ ::OverSIP::SystemEvents.on_initialize
157
+ rescue ::Exception => e
158
+ log_system_crit "error calling OverSIP::SystemEvents.on_initialize():"
159
+ fatal e
223
160
  end
224
- end
225
-
226
- if configuration[:websocket][:sip_wss]
227
- unless configuration[:websocket][:use_tls_tunnel]
228
- # WebSocket IPv4 TLS SIP server (native).
229
- if configuration[:websocket][:enable_ipv4]
230
- ::OverSIP::WebSocket::Launcher.run true, :ipv4, configuration[:websocket][:listen_ipv4],
231
- configuration[:websocket][:listen_port_tls], :wss
232
- end
233
-
234
- # WebSocket IPv6 TLS SIP server (native).
235
- if configuration[:websocket][:enable_ipv6]
236
- ::OverSIP::WebSocket::Launcher.run true, :ipv6, configuration[:websocket][:listen_ipv6],
237
- configuration[:websocket][:listen_port_tls], :wss
238
- end
239
- else
240
- # WebSocket IPv4 TLS SIP server (Stud).
241
- if configuration[:websocket][:enable_ipv4]
242
- ::OverSIP::WebSocket::Launcher.run true, :ipv4, "127.0.0.1",
243
- configuration[:websocket][:listen_port_tls_tunnel], :wss_tunnel,
244
- configuration[:websocket][:listen_ipv4],
245
- configuration[:websocket][:listen_port_tls]
246
- ::OverSIP::WebSocket::Launcher.run false, :ipv4, configuration[:websocket][:listen_ipv4],
247
- configuration[:websocket][:listen_port_tls], :wss
248
-
249
- # Spawn a Stud process.
250
- spawn_stud_process options,
251
- configuration[:websocket][:listen_ipv4], configuration[:websocket][:listen_port_tls],
252
- "127.0.0.1", configuration[:websocket][:listen_port_tls_tunnel],
253
- ssl = true
254
- end
255
161
 
256
- # WebSocket IPv6 TLS SIP server (Stud).
257
- if configuration[:sip][:enable_ipv6]
258
- ::OverSIP::WebSocket::Launcher.run true, :ipv6, "::1",
259
- configuration[:websocket][:listen_port_tls_tunnel], :wss_tunnel,
260
- configuration[:websocket][:listen_ipv6],
261
- configuration[:websocket][:listen_port_tls]
262
- ::OverSIP::WebSocket::Launcher.run false, :ipv6, configuration[:websocket][:listen_ipv6],
263
- configuration[:websocket][:listen_port_tls], :wss
264
-
265
- # Spawn a Stud process.
266
- spawn_stud_process options,
267
- configuration[:websocket][:listen_ipv6], configuration[:websocket][:listen_port_tls],
268
- "::1", configuration[:websocket][:listen_port_tls_tunnel],
269
- ssl = true
162
+ # Run all the OverSIP::SystemCallbacks.on_started_callbacks.
163
+ log_system_notice "executing OverSIP::SystemCallbacks.on_started_callbacks..."
164
+ ::OverSIP::SystemCallbacks.on_started_callbacks.each do |cb|
165
+ begin
166
+ cb.call
167
+ rescue ::Exception => e
168
+ log_system_crit "error executing a callback in OverSIP::SystemCallbacks.on_started_callbacks:"
169
+ fatal e
270
170
  end
271
171
  end
272
- end
273
-
274
-
275
- # Change process permissions if requested.
276
- set_user_group(options[:user], options[:group])
277
-
278
- # Create PID file.
279
- create_pid_file(options[:pid_file])
280
172
 
281
- # Run the user provided on_initialize method.
282
- log_system_info "calling OverSIP::SystemEvents.on_initialize() method..."
283
- begin
284
- ::OverSIP::SystemEvents.on_initialize
285
- rescue ::Exception => e
286
- log_system_crit "error calling OverSIP::SystemEvents.on_initialize():"
287
- fatal e
288
- end
289
-
290
- # Run the on_started provided callbacks.
291
- log_system_info "executing OverSIP::SystemCallbacks.on_started_callbacks..."
292
- ::OverSIP::SystemCallbacks.on_started_callbacks.each do |cb|
173
+ # Run OverSIP::SystemEvents.on_started within a fiber.
174
+ log_system_notice "calling OverSIP::SystemEvents.on_started() method..."
293
175
  begin
294
- cb.call
176
+ ::OverSIP::SystemEvents.on_started
295
177
  rescue ::Exception => e
296
- log_system_crit "error executing a callback in OverSIP::SystemCallbacks.on_started_callbacks:"
178
+ log_system_crit "error calling OverSIP::SystemEvents.on_started():"
297
179
  fatal e
298
180
  end
299
- end
300
181
 
301
- # Run the user provided on_started method.
302
- log_system_info "calling OverSIP::SystemEvents.on_started() method..."
303
- begin
304
- ::OverSIP::SystemEvents.on_started
305
- rescue ::Exception => e
306
- log_system_crit "error calling OverSIP::SystemEvents.on_started():"
307
- fatal e
308
- end
309
-
310
- log_system_info "master process (PID #{$$}) ready"
311
- log_system_info "#{::OverSIP::PROGRAM_NAME} #{::OverSIP::VERSION} running in background"
182
+ log_system_notice "master process (PID #{$$}) ready"
183
+ log_system_notice "#{::OverSIP::PROGRAM_NAME} #{::OverSIP::VERSION} running in background"
312
184
 
313
- # Write "ok" into the ready_pipe so grandparent process (launcher)
314
- # exits with status 0.
315
- if ready_pipe
316
- ready_pipe.write("ok")
317
- ready_pipe.close rescue nil
318
- ready_pipe = nil
319
- end
185
+ # Write "ok" into the ready_pipe so grandparent process (launcher)
186
+ # exits with status 0.
187
+ if ready_pipe
188
+ ready_pipe.write("ok")
189
+ ready_pipe.close rescue nil
190
+ ready_pipe = nil
191
+ end
320
192
 
321
- # Stop writting into standard output/error.
322
- $stdout.reopen("/dev/null")
323
- $stderr.reopen("/dev/null")
324
- ::OverSIP.daemonized = true
325
- # So update the logger to write to syslog.
326
- ::OverSIP::Logger.load_methods
193
+ # Stop writting into standard output/error.
194
+ $stdout.reopen("/dev/null")
195
+ $stderr.reopen("/dev/null")
196
+ ::OverSIP.daemonized = true
197
+ # So update the logger to write to syslog.
198
+ ::OverSIP::Logger.load_methods
199
+
200
+ # Set the EventMachine error handler.
201
+ ::EM.error_handler do |e|
202
+ log_system_error "error raised during event loop and rescued by EM.error_handler:"
203
+ log_system_error e
204
+ end
327
205
 
328
- # Set the EventMachine error handler.
329
- ::EM.error_handler do |e|
330
- log_system_error "error raised during event loop and rescued by EM.error_handler:"
331
- log_system_error e
332
- end
206
+ ::OverSIP.is_ready = true
207
+ ::OverSIP.status = :running
333
208
 
334
- trap_signals
209
+ end.resume
335
210
 
336
211
  end # ::EM.run
337
212
 
@@ -350,7 +225,7 @@ module OverSIP::Launcher
350
225
  end
351
226
 
352
227
 
353
- def self.create_pid_file(path)
228
+ def self.create_pid_file path
354
229
  # Check that the PID file is accesible.
355
230
  begin
356
231
  assert_file_is_writable_readable_deletable(path)
@@ -371,7 +246,7 @@ module OverSIP::Launcher
371
246
  end
372
247
 
373
248
 
374
- def self.assert_file_is_writable_readable_deletable(path)
249
+ def self.assert_file_is_writable_readable_deletable path
375
250
  # File already exists.
376
251
  if ::File.exist?(path)
377
252
  if not ::File.file?(path)
@@ -391,7 +266,7 @@ module OverSIP::Launcher
391
266
 
392
267
  # Returns a PID if a given path contains a non-stale PID file,
393
268
  # false otherwise.
394
- def self.valid_pid?(path)
269
+ def self.valid_pid? path
395
270
  begin
396
271
  wpid = ::File.read(path).to_i
397
272
  wpid <= 0 and return false
@@ -408,6 +283,149 @@ module OverSIP::Launcher
408
283
  end
409
284
 
410
285
 
286
+ def self.run_servers options
287
+ configuration = ::OverSIP.configuration
288
+
289
+ if configuration[:sip][:sip_udp]
290
+ # SIP UDP IPv4 server.
291
+ if configuration[:sip][:enable_ipv4]
292
+ ::OverSIP::SIP::Launcher.run true, :ipv4, configuration[:sip][:listen_ipv4],
293
+ configuration[:sip][:listen_port], :udp
294
+ end
295
+
296
+ # SIP IPv6 UDP server.
297
+ if configuration[:sip][:enable_ipv6]
298
+ ::OverSIP::SIP::Launcher.run true, :ipv6, configuration[:sip][:listen_ipv6],
299
+ configuration[:sip][:listen_port], :udp
300
+ end
301
+ end
302
+
303
+ if configuration[:sip][:sip_tcp]
304
+ # SIP IPv4 TCP server.
305
+ if configuration[:sip][:enable_ipv4]
306
+ ::OverSIP::SIP::Launcher.run true, :ipv4, configuration[:sip][:listen_ipv4],
307
+ configuration[:sip][:listen_port], :tcp
308
+ end
309
+
310
+ # SIP IPv6 TCP server.
311
+ if configuration[:sip][:enable_ipv6]
312
+ ::OverSIP::SIP::Launcher.run true, :ipv6, configuration[:sip][:listen_ipv6],
313
+ configuration[:sip][:listen_port], :tcp
314
+ end
315
+ end
316
+
317
+ if configuration[:sip][:sip_tls]
318
+ unless configuration[:sip][:use_tls_tunnel]
319
+ # SIP IPv4 TLS server (native).
320
+ if configuration[:sip][:enable_ipv4]
321
+ ::OverSIP::SIP::Launcher.run true, :ipv4, configuration[:sip][:listen_ipv4],
322
+ configuration[:sip][:listen_port_tls], :tls
323
+ end
324
+
325
+ # SIP IPv6 TLS server (native).
326
+ if configuration[:sip][:enable_ipv6]
327
+ ::OverSIP::SIP::Launcher.run true, :ipv6, configuration[:sip][:listen_ipv6],
328
+ configuration[:sip][:listen_port_tls], :tls
329
+ end
330
+ else
331
+ # SIP IPv4 TLS server (Stud).
332
+ if configuration[:sip][:enable_ipv4]
333
+ ::OverSIP::SIP::Launcher.run true, :ipv4, "127.0.0.1",
334
+ configuration[:sip][:listen_port_tls_tunnel], :tls_tunnel,
335
+ configuration[:sip][:listen_ipv4],
336
+ configuration[:sip][:listen_port_tls]
337
+ ::OverSIP::SIP::Launcher.run false, :ipv4, configuration[:sip][:listen_ipv4],
338
+ configuration[:sip][:listen_port_tls], :tls
339
+
340
+ # Spawn a Stud process.
341
+ spawn_stud_process options,
342
+ configuration[:sip][:listen_ipv4], configuration[:sip][:listen_port_tls],
343
+ "127.0.0.1", configuration[:sip][:listen_port_tls_tunnel],
344
+ ssl = false
345
+ end
346
+
347
+ # SIP IPv6 TLS server (Stud).
348
+ if configuration[:sip][:enable_ipv6]
349
+ ::OverSIP::SIP::Launcher.run true, :ipv6, "::1",
350
+ configuration[:sip][:listen_port_tls_tunnel], :tls_tunnel,
351
+ configuration[:sip][:listen_ipv6],
352
+ configuration[:sip][:listen_port_tls]
353
+ ::OverSIP::SIP::Launcher.run false, :ipv6, configuration[:sip][:listen_ipv6],
354
+ configuration[:sip][:listen_port_tls], :tls
355
+
356
+ # Spawn a Stud process.
357
+ spawn_stud_process options,
358
+ configuration[:sip][:listen_ipv6], configuration[:sip][:listen_port_tls],
359
+ "::1", configuration[:sip][:listen_port_tls_tunnel],
360
+ ssl = false
361
+ end
362
+ end
363
+ end
364
+
365
+ if configuration[:websocket][:sip_ws]
366
+ # WebSocket IPv4 TCP SIP server.
367
+ if configuration[:websocket][:enable_ipv4]
368
+ ::OverSIP::WebSocket::Launcher.run true, :ipv4, configuration[:websocket][:listen_ipv4],
369
+ configuration[:websocket][:listen_port], :ws
370
+ end
371
+
372
+ # WebSocket IPv6 TCP SIP server.
373
+ if configuration[:websocket][:enable_ipv6]
374
+ ::OverSIP::WebSocket::Launcher.run true, :ipv6, configuration[:websocket][:listen_ipv6],
375
+ configuration[:websocket][:listen_port], :ws
376
+ end
377
+ end
378
+
379
+ if configuration[:websocket][:sip_wss]
380
+ unless configuration[:websocket][:use_tls_tunnel]
381
+ # WebSocket IPv4 TLS SIP server (native).
382
+ if configuration[:websocket][:enable_ipv4]
383
+ ::OverSIP::WebSocket::Launcher.run true, :ipv4, configuration[:websocket][:listen_ipv4],
384
+ configuration[:websocket][:listen_port_tls], :wss
385
+ end
386
+
387
+ # WebSocket IPv6 TLS SIP server (native).
388
+ if configuration[:websocket][:enable_ipv6]
389
+ ::OverSIP::WebSocket::Launcher.run true, :ipv6, configuration[:websocket][:listen_ipv6],
390
+ configuration[:websocket][:listen_port_tls], :wss
391
+ end
392
+ else
393
+ # WebSocket IPv4 TLS SIP server (Stud).
394
+ if configuration[:websocket][:enable_ipv4]
395
+ ::OverSIP::WebSocket::Launcher.run true, :ipv4, "127.0.0.1",
396
+ configuration[:websocket][:listen_port_tls_tunnel], :wss_tunnel,
397
+ configuration[:websocket][:listen_ipv4],
398
+ configuration[:websocket][:listen_port_tls]
399
+ ::OverSIP::WebSocket::Launcher.run false, :ipv4, configuration[:websocket][:listen_ipv4],
400
+ configuration[:websocket][:listen_port_tls], :wss
401
+
402
+ # Spawn a Stud process.
403
+ spawn_stud_process options,
404
+ configuration[:websocket][:listen_ipv4], configuration[:websocket][:listen_port_tls],
405
+ "127.0.0.1", configuration[:websocket][:listen_port_tls_tunnel],
406
+ ssl = true
407
+ end
408
+
409
+ # WebSocket IPv6 TLS SIP server (Stud).
410
+ if configuration[:sip][:enable_ipv6]
411
+ ::OverSIP::WebSocket::Launcher.run true, :ipv6, "::1",
412
+ configuration[:websocket][:listen_port_tls_tunnel], :wss_tunnel,
413
+ configuration[:websocket][:listen_ipv6],
414
+ configuration[:websocket][:listen_port_tls]
415
+ ::OverSIP::WebSocket::Launcher.run false, :ipv6, configuration[:websocket][:listen_ipv6],
416
+ configuration[:websocket][:listen_port_tls], :wss
417
+
418
+ # Spawn a Stud process.
419
+ spawn_stud_process options,
420
+ configuration[:websocket][:listen_ipv6], configuration[:websocket][:listen_port_tls],
421
+ "::1", configuration[:websocket][:listen_port_tls_tunnel],
422
+ ssl = true
423
+ end
424
+ end
425
+ end
426
+ end
427
+
428
+
411
429
  def self.trap_signals
412
430
  # This should never occur (unless some not trapped signal is received
413
431
  # and causes Ruby to exit, or maybe the user called "exit()" within its
@@ -449,87 +467,104 @@ module OverSIP::Launcher
449
467
 
450
468
  # Signal HUP reloads OverSIP system configuration.
451
469
  trap :HUP do
470
+ # Ignore another HUP signal until this code is finished.
471
+ original_trap_proc = trap(:HUP){}
472
+
452
473
  log_system_notice "HUP signal received, reloading configuration files..."
453
474
  ::OverSIP::Config.system_reload
454
475
 
455
- # Run the on_reload provided callbacks.
476
+ # Run all the OverSIP::SystemCallbacks.on_reload_callbacks.
456
477
  log_system_info "executing OverSIP::SystemCallbacks.on_reload_callbacks..."
457
- ::OverSIP::SystemCallbacks.on_reload_callbacks.each do |cb|
458
- begin
459
- cb.call
460
- rescue ::Exception => e
461
- log_system_crit "error executing a callback in OverSIP::SystemCallbacks.on_reload_callbacks:"
462
- log_system_crit e
478
+ ::Fiber.new do
479
+ ::OverSIP::SystemCallbacks.on_reload_callbacks.each do |cb|
480
+ begin
481
+ cb.call
482
+ rescue ::Exception => e
483
+ log_system_crit "error executing a callback in OverSIP::SystemCallbacks.on_reload_callbacks:"
484
+ log_system_crit e
485
+ end
463
486
  end
464
- end
487
+
488
+ # Reset the signal handler.
489
+ trap :HUP, original_trap_proc
490
+ end.resume
465
491
  end
466
492
 
467
493
  # Signal USR1 reloads custom code provided by the user.
468
494
  trap :USR1 do
495
+ # Ignore another HUP signal until this code is finished.
496
+ original_trap_proc = trap(:USR1){}
497
+
469
498
  log_system_notice "USR1 signal received, calling OverSIP::SystemEvents.on_user_reload() method..."
470
- # Run the user provided on_started callback.
471
- begin
472
- ::OverSIP::SystemEvents.on_user_reload
473
- rescue ::Exception => e
474
- log_system_crit "error calling OverSIP::SystemEvents.on_user_reload():"
475
- log_system_crit e
476
- end
477
- end
499
+ # Run OverSIP::SystemEvents.on_user_reload.
500
+ ::Fiber.new do
501
+ begin
502
+ ::OverSIP::SystemEvents.on_user_reload
503
+ rescue ::Exception => e
504
+ log_system_crit "error calling OverSIP::SystemEvents.on_user_reload():"
505
+ log_system_crit e
506
+ end
478
507
 
479
- # Signal CHLD is sent by syslogger process if it dies.
480
- trap :CHLD do
481
- # NOTE: This won't be logged if the died proces is oversip_syslogger!
482
- log_system_crit "CHLD signal received, syslogger process could be death"
508
+ # Reset the signal handler.
509
+ trap :USR1, original_trap_proc
510
+ end.resume
483
511
  end
512
+
484
513
  end
485
514
 
486
515
 
487
516
  def self.terminate error=false, fatal=false
517
+ ::OverSIP.is_ready = false
518
+ ::OverSIP.status = :terminating
519
+
488
520
  # Trap TERM/QUIT signals (we are already exiting).
489
521
  trap(:TERM) {}
490
522
  trap(:QUIT) {}
491
523
 
492
- unless fatal
493
- # Run the on_terminated provided callbacks.
494
- log_system_info "executing OverSIP::SystemCallbacks.on_terminated_callbacks..."
495
- ::OverSIP::SystemCallbacks.on_terminated_callbacks.each do |cb|
524
+ ::Fiber.new do
525
+
526
+ unless fatal
527
+ # Run OverSIP::SystemEvents.on_terminated.
528
+ log_system_info "calling OverSIP::SystemEvents.on_terminated() method..."
496
529
  begin
497
- cb.call error
530
+ ::OverSIP::SystemEvents.on_terminated error
498
531
  rescue ::Exception => e
499
- log_system_crit "error executing a callback in OverSIP::SystemCallbacks.on_terminated_callbacks:"
532
+ log_system_crit "error calling OverSIP::SystemEvents.on_terminated():"
500
533
  log_system_crit e
501
534
  end
535
+
536
+ # Run all the SystemCallbacks.on_terminated_callbacks in reverse order.
537
+ log_system_info "executing OverSIP::SystemCallbacks.on_terminated_callbacks..."
538
+ ::OverSIP::SystemCallbacks.on_terminated_callbacks.reverse.each do |cb|
539
+ begin
540
+ cb.call error
541
+ rescue ::Exception => e
542
+ log_system_crit "error executing a callback in OverSIP::SystemCallbacks.on_terminated_callbacks:"
543
+ log_system_crit e
544
+ end
545
+ end
502
546
  end
503
547
 
504
- # Run the user provided on_terminated method.
505
- log_system_info "calling OverSIP::SystemEvents.on_terminated() method..."
506
- begin
507
- ::OverSIP::SystemEvents.on_terminated error
508
- rescue ::Exception => e
509
- log_system_crit "error calling OverSIP::SystemEvents.on_terminated():"
510
- log_system_crit e
548
+ unless error
549
+ log_system_info "exiting, thank you for tasting #{::OverSIP::PROGRAM_NAME}"
511
550
  end
512
- end
513
551
 
514
- unless error
515
- log_system_info "exiting, thank you for tasting #{::OverSIP::PROGRAM_NAME}"
516
- end
552
+ # Kill Stud processes and delete its temporal file with the full certificate.
553
+ kill_stud_processes
554
+ ::File.delete ::OverSIP.configuration[:tls][:full_cert] rescue nil
517
555
 
518
- # Kill Stud processes and delete its temporal file with the full certificate.
519
- kill_stud_processes
520
- ::File.delete ::OverSIP.configuration[:tls][:full_cert] rescue nil
556
+ # Wait a bit so pending log messages in the Posix MQ can be queued.
557
+ sleep 0.1
558
+ ::OverSIP::Logger.close
521
559
 
522
- # Wait a bit so pending log messages in the Posix MQ can be queued.
523
- sleep 0.1
524
- ::OverSIP::Logger.close
560
+ kill_syslogger_process
525
561
 
526
- # Fill the syslogger process.
527
- kill_syslogger_process
562
+ delete_pid_file
528
563
 
529
- delete_pid_file
564
+ # Exit by preventing any exception.
565
+ exit!( error ? false : true )
530
566
 
531
- # Exit by preventing any exception.
532
- exit!( error ? false : true )
567
+ end.resume
533
568
  end
534
569
 
535
570
 
@@ -557,7 +592,7 @@ module OverSIP::Launcher
557
592
  end
558
593
 
559
594
 
560
- def self.set_user_group(user, group)
595
+ def self.set_user_group user, group
561
596
  uid = ::Etc.getpwnam(user).uid if user
562
597
  gid = ::Etc.getgrnam(group).gid if group
563
598
  if uid or gid
@@ -572,7 +607,7 @@ module OverSIP::Launcher
572
607
  end
573
608
 
574
609
 
575
- def self.spawn_stud_process(options, listen_ip, listen_port, bg_ip, bg_port, ssl=false)
610
+ def self.spawn_stud_process options, listen_ip, listen_port, bg_ip, bg_port, ssl=false
576
611
  stud_user_group = ""
577
612
  stud_user_group << "-u #{options[:user]}" if options[:user]
578
613
  stud_user_group << " -g #{options[:group]}" if options[:group]