oversip 1.0.2 → 1.0.3

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.
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- <a style="color: red" href="http://www.oversip.net"><img src="https://github.com/versatica/OverSIP/wiki/oversip-banner.png"/></a>
1
+ <a href="http://www.oversip.net"><img src="http://www-test.oversip.net/images/dev/oversip-banner.png"/></a>
2
2
 
3
3
  **WEB UNDER CONSTRUCTION:** The code is stable and working. This web page and documentation is not... please wait a bit.
4
4
 
data/bin/oversip CHANGED
@@ -1,16 +1,14 @@
1
- #!/usr/bin/ruby1.9
1
+ #!/usr/bin/ruby
2
2
  # -*- encoding: binary -*-
3
3
 
4
4
  unless RUBY_VERSION >= "1.9.2"
5
5
  raise LoadError, "OverSIP requires Ruby version >= 1.9.2 (current version is #{RUBY_VERSION})"
6
6
  end
7
7
 
8
-
9
8
  # First of all, trap some signals in order to ignore them if they arrive while
10
9
  # loading server libraries.
11
10
  [:HUP, :INT, :USR1, :USR2].each {|signal| trap(signal) {} }
12
11
 
13
-
14
12
  require "optparse"
15
13
  require "etc"
16
14
  require "oversip"
@@ -28,10 +26,11 @@ module OverSIP
28
26
 
29
27
  # Options by default.
30
28
  options = {
31
- :colorize => true
29
+ :num_instances => 1,
30
+ :colorize => true
32
31
  }
33
32
 
34
- OptionParser.new("", 24, " ") do |opts|
33
+ OptionParser.new("", 28, " ") do |opts|
35
34
  opts.banner = "#{::OverSIP::DESCRIPTION}" \
36
35
  "\n\nUsage: #{File.basename(__FILE__)} " \
37
36
  "[#{::OverSIP::PROGRAM_NAME} options] [Ruby options]"
@@ -42,12 +41,16 @@ module OverSIP
42
41
  options[:pid_file] = value
43
42
  end
44
43
 
45
- opts.on("-p", "--process_name NAME", "Change the running process name, also affects to syslogger process and Posix Message Queue name (default 'oversip')") do |value|
44
+ opts.on("-p", "--process-name NAME", "Change the running process name, also affects to syslogger process and Posix Message Queue name (default 'oversip')") do |value|
46
45
  options[:process_name] = value
47
46
  end
48
47
 
49
- opts.on("-c", "--dir_config DIR", "Absolute path to the directory with user configuration files (default '/etc/oversip/')") do |value|
50
- options[:dir_config] = value
48
+ opts.on("--config-dir DIR", "Absolute path to the directory with user configuration files (default '/etc/oversip/')") do |value|
49
+ options[:config_dir] = value
50
+ end
51
+
52
+ opts.on("--config-file FILE", "Name of the configuration file within the configuration directory (default 'oversip.conf')") do |value|
53
+ options[:config_file] = value
51
54
  end
52
55
 
53
56
  opts.on("-u", "--user USER", "System user to run with") do |value|
@@ -58,6 +61,10 @@ module OverSIP
58
61
  options[:group] = value
59
62
  end
60
63
 
64
+ opts.on("-n", "--num-instances NUM", "Number of OverSIP instances that will run together in this host (this parameter is just for some resources allocation, it does not run NUM instances!) (default 1)") do |value|
65
+ options[:num_instances] = value.to_i
66
+ end
67
+
61
68
  opts.on("--no-color", "Don't colorize text printed in stdout") do |value|
62
69
  options[:colorize] = false
63
70
  end
@@ -156,6 +163,11 @@ module OverSIP
156
163
  end
157
164
  end
158
165
 
166
+ # Check the --num-instances parameter.
167
+ if options[:num_instances] < 1
168
+ fatal "num_instances #{n} is not a valid value (must be greater than 0)"
169
+ end
170
+
159
171
  # Set the command name (as it appears in "ps" output) to given --process_name option (-p)
160
172
  # or to the script filename otherwise.
161
173
  $0 = options[:process_name] || File.basename(__FILE__)
@@ -163,12 +175,12 @@ module OverSIP
163
175
  OverSIP.master_name = $0
164
176
  log_system_info "master process name: #{OverSIP.master_name}"
165
177
 
166
- OverSIP::Config.load options[:dir_config]
178
+ OverSIP::Config.load options[:config_dir], options[:config_file]
167
179
  log_system_info "applied configuration:"
168
180
  OverSIP::Config.print options[:colorize]
169
181
 
170
182
  log_system_info "creating Posix Message Queue for communicating master and syslogger processes"
171
- OverSIP::Logger.init_logger_mq options[:group]
183
+ OverSIP::Logger.init_logger_mq options[:num_instances], options[:group]
172
184
  OverSIP::Logger.load_methods
173
185
 
174
186
  OverSIP::Launcher.daemonize!(options)
data/debian/preinst CHANGED
@@ -6,7 +6,7 @@ set -e
6
6
 
7
7
  #DEBHELPER#
8
8
 
9
- OVERSIP_GEM_VERSION="~>1.0.1"
9
+ OVERSIP_GEM_VERSION="~>1.0.3"
10
10
 
11
11
  case "$1" in
12
12
 
@@ -11,7 +11,7 @@ module OverSIP
11
11
  DEFAULT_CONFIG_DIR = "/etc/oversip/"
12
12
  DEFAULT_TLS_DIR = "tls/"
13
13
  DEFAULT_TLS_CA_DIR = "tls/ca/"
14
- CONF_FILE = "oversip.conf"
14
+ DEFAULT_CONFIG_FILE = "oversip.conf"
15
15
  PROXIES_FILE = "proxies.conf"
16
16
  LOGIC_FILE = "logic.rb"
17
17
  WEBSOCKET_POLICY_FILE = "websocket_policy.rb"
@@ -20,21 +20,6 @@ module OverSIP
20
20
  @log_id ||= "Config"
21
21
  end
22
22
 
23
- def self.conf_file
24
- @conf_file ||= ::File.join(@conf_dir, CONF_FILE)
25
- end
26
-
27
- def self.proxies_file
28
- @proxies_file ||= ::File.join(@conf_dir, PROXIES_FILE)
29
- end
30
-
31
- def self.logic_file
32
- @logic_file ||= ::File.join(@conf_dir, LOGIC_FILE)
33
- end
34
-
35
- def self.websocket_policy_file
36
- @websocket_policy_file ||= ::File.join(@conf_dir, WEBSOCKET_POLICY_FILE)
37
- end
38
23
 
39
24
  @configuration = {
40
25
  :core => {
@@ -104,7 +89,6 @@ module OverSIP
104
89
  :listen_port => :port,
105
90
  :listen_port_tls => :port,
106
91
  :use_tls_tunnel => :boolean,
107
- # TODO, si use_tls_tunnel es yes entonces listen_port_tls_tunnel debe estar puesto.
108
92
  :listen_port_tls_tunnel => :port,
109
93
  :local_domains => [ :domain, :multi_value ],
110
94
  :tcp_keepalive_interval => [ :fixnum, [ :greater_equal_than, 180 ] ],
@@ -134,31 +118,35 @@ module OverSIP
134
118
  }
135
119
 
136
120
 
137
- def self.load conf_dir = nil
138
- @conf_dir ||= (conf_dir || DEFAULT_CONFIG_DIR)
121
+ def self.load config_dir=nil, config_file=nil
122
+ @config_dir = (config_dir || DEFAULT_CONFIG_DIR)
123
+ @config_file = ::File.join(@config_dir, config_file || DEFAULT_CONFIG_FILE)
124
+ @proxies_file = ::File.join(@config_dir, PROXIES_FILE)
125
+ @logic_file ||= ::File.join(@config_dir, LOGIC_FILE)
126
+ @websocket_policy_file ||= ::File.join(@config_dir, WEBSOCKET_POLICY_FILE)
139
127
 
140
128
  begin
141
- conf_yaml = ::YAML.load_file conf_file
129
+ conf_yaml = ::YAML.load_file @config_file
142
130
  rescue => e
143
- fatal "error loading configuration file '#{conf_file}': #{e.message} (#{e.class})"
131
+ fatal "error loading configuration file '#{@config_file}': #{e.message} (#{e.class})"
144
132
  end
145
133
 
146
134
  begin
147
- proxies_yaml = ::YAML.load_file proxies_file
135
+ proxies_yaml = ::YAML.load_file @proxies_file
148
136
  rescue => e
149
- fatal "error loading proxies configuration file '#{proxies_file}': #{e.message} (#{e.class})"
137
+ fatal "error loading proxies configuration file '#{@proxies_file}': #{e.message} (#{e.class})"
150
138
  end
151
139
 
152
140
  begin
153
- Kernel.load logic_file
141
+ Kernel.load @logic_file
154
142
  rescue LoadError => e
155
- fatal "error loading logic file '#{logic_file}': #{e.message} (#{e.class})"
143
+ fatal "error loading logic file '#{@logic_file}': #{e.message} (#{e.class})"
156
144
  end
157
145
 
158
146
  begin
159
- Kernel.load websocket_policy_file
147
+ Kernel.load @websocket_policy_file
160
148
  rescue LoadError => e
161
- log_system_warn "cannot load WebSocket Policy file '#{websocket_policy_file}': #{e.message} (#{e.class}), using default policy (allow all)"
149
+ log_system_warn "cannot load WebSocket Policy file '#{@websocket_policy_file}': #{e.message} (#{e.class}), using default policy (allow all)"
162
150
  end
163
151
 
164
152
  begin
@@ -221,7 +209,6 @@ module OverSIP
221
209
  end
222
210
 
223
211
  ::OverSIP.configuration = @configuration
224
-
225
212
  ::OverSIP::ProxiesConfig.load proxies_yaml
226
213
  end
227
214
 
@@ -234,15 +221,15 @@ module OverSIP
234
221
  tls_ca_dir = conf_yaml["tls"]["ca_dir"] rescue nil
235
222
 
236
223
  if tls_public_cert.is_a?(String) and tls_public_cert[0] != "/"
237
- conf_yaml["tls"]["public_cert"] = ::File.join(@conf_dir, DEFAULT_TLS_DIR, tls_public_cert)
224
+ conf_yaml["tls"]["public_cert"] = ::File.join(@config_dir, DEFAULT_TLS_DIR, tls_public_cert)
238
225
  end
239
226
 
240
227
  if tls_private_cert.is_a?(String) and tls_private_cert[0] != "/"
241
- conf_yaml["tls"]["private_cert"] = ::File.join(@conf_dir, DEFAULT_TLS_DIR, tls_private_cert)
228
+ conf_yaml["tls"]["private_cert"] = ::File.join(@config_dir, DEFAULT_TLS_DIR, tls_private_cert)
242
229
  end
243
230
 
244
231
  if tls_ca_dir.is_a?(String) and tls_ca_dir[0] != "/"
245
- conf_yaml["tls"]["ca_dir"] = ::File.join(@conf_dir, DEFAULT_TLS_DIR, tls_ca_dir)
232
+ conf_yaml["tls"]["ca_dir"] = ::File.join(@config_dir, DEFAULT_TLS_DIR, tls_ca_dir)
246
233
  end
247
234
  end
248
235
 
@@ -526,7 +513,7 @@ module OverSIP
526
513
 
527
514
  def self.reload_logic
528
515
  begin
529
- Kernel.load logic_file
516
+ Kernel.load @logic_file
530
517
  log_system_info "logic reloaded"
531
518
  true
532
519
  rescue Exception => e
@@ -106,7 +106,7 @@ module OverSIP::Launcher
106
106
  ::OverSIP::WebSocket::WsFraming.class_init
107
107
  ::OverSIP::WebSocket::WsApp.class_init
108
108
 
109
- # I'm the sysloger process.
109
+ # I'm the syslogger process.
110
110
  else
111
111
  # Close the pipe in the syslogger process.
112
112
  ready_pipe.close rescue nil
@@ -437,18 +437,16 @@ module OverSIP::Launcher
437
437
  log_system_info "exiting, thank you for tasting #{::OverSIP::PROGRAM_NAME}"
438
438
  end
439
439
 
440
+ # Kill Stud processes.
441
+ kill_stud_processes
442
+
440
443
  # Wait a bit so pending log messages in the Posix MQ can be queued.
441
444
  sleep 0.05
442
445
  delete_pid_file
443
446
  ::OverSIP::Logger.close
444
- kill_syslogger_process
445
447
 
446
- # Kill Stud processes.
447
- pid = Process.spawn "killall oversip_stud 2>/dev/null"
448
- Process.wait(pid)
449
- sleep 0.5
450
- pid = Process.spawn "killall -9 oversip_stud 2>/dev/null"
451
- Process.wait(pid)
448
+ # Fill the syslogger process.
449
+ kill_syslogger_process
452
450
 
453
451
  # Exit by preventing any exception.
454
452
  exit!( error ? false : true )
@@ -501,10 +499,53 @@ module OverSIP::Launcher
501
499
  ssl_option = ( ssl ? "--ssl" : "" )
502
500
 
503
501
  bin_dir = ::File.join(::File.absolute_path(::File.dirname(__FILE__)), "../../bin/")
504
- Dir.chdir(bin_dir) do
505
- pid = POSIX::Spawn.spawn "./oversip_stud #{stud_user_group} #{ssl_option} -f '#{listen_ip},#{listen_port}' -b '#{bg_ip},#{bg_port}' -n 2 -s --daemon --write-proxy #{::OverSIP.configuration[:tls][:full_cert]}"
502
+ stdout_file = "/tmp/stud.#{listen_ip}:#{listen_port}.out"
503
+
504
+ ::Dir.chdir(bin_dir) do
505
+ pid = POSIX::Spawn.spawn "./oversip_stud #{stud_user_group} #{ssl_option} -f '#{listen_ip},#{listen_port}' -b '#{bg_ip},#{bg_port}' -n 2 -s --daemon --write-proxy #{::OverSIP.configuration[:tls][:full_cert]}", :out => stdout_file, :err => "/dev/null"
506
506
  Process.waitpid(pid)
507
507
  end
508
+
509
+ # Get the PID of the daemonized stud process.
510
+ stdout = ::File.read stdout_file
511
+ pid = nil
512
+ stdout.each_line do |line|
513
+ pid = line.split(" ")[4]
514
+ if pid
515
+ pid = pid.gsub(/\./,"").to_i
516
+ break if pid > 0
517
+ end
518
+ end
519
+ ::File.delete stdout_file rescue nil
520
+
521
+ unless pid
522
+ fatal "error spawning stud server"
523
+ end
524
+
525
+ ::OverSIP.stud_pids ||= []
526
+ ::OverSIP.stud_pids << pid
527
+
528
+ log_system_info "spawned stud server (PID #{pid}) listening into #{listen_ip} : #{listen_port}"
529
+ end
530
+
531
+
532
+ def self.kill_stud_processes
533
+ return false unless ::OverSIP.master_pid
534
+
535
+ ::OverSIP.stud_pids.each do |pid|
536
+ begin
537
+ log_system_info "killing stud server with PID #{pid}..."
538
+ ::Process.kill(:TERM, pid)
539
+ 10.times do |i|
540
+ sleep 0.05
541
+ ::Process.wait(pid, ::Process::WNOHANG) rescue nil
542
+ ::Process.kill(0, pid) rescue break
543
+ end
544
+ ::Process.kill(0, pid)
545
+ ::Process.kill(:KILL, pid) rescue nil
546
+ rescue ::Errno::ESRCH
547
+ end
548
+ end
508
549
  end
509
550
 
510
551
  end
@@ -16,7 +16,7 @@ module OverSIP
16
16
  "emerg" => 7
17
17
  }
18
18
 
19
- def self.init_logger_mq(group = nil)
19
+ def self.init_logger_mq num_instances, group=nil
20
20
  OverSIP.syslogger_mq_name = "/#{OverSIP.master_name}_syslogger"
21
21
 
22
22
  @@logger_mq = ::OverSIP::PosixMQ.create_queue({
@@ -24,6 +24,7 @@ module OverSIP
24
24
  :mode => :write,
25
25
  :maxmsg => 1000,
26
26
  :msgsize => 2000,
27
+ :num_instances => num_instances,
27
28
  :group => group
28
29
  })
29
30
  end
@@ -6,7 +6,6 @@ module OverSIP
6
6
 
7
7
  def self.create_queue options={}
8
8
  @log_id = "PosixMQ #{options[:name]}"
9
- @total_size ||= 0
10
9
 
11
10
  # Queue attributes.
12
11
  mq_name = options[:name]
@@ -42,7 +41,6 @@ module OverSIP
42
41
  Process::GID.change_privilege(gid)
43
42
  end
44
43
 
45
- ### TODO: Este tamaño debe multiplicarse por el num de queues!
46
44
  # System limits required size (ulimit -q).
47
45
  mq_size = case 1.size
48
46
  # 32 bits OS.
@@ -50,17 +48,20 @@ module OverSIP
50
48
  # 64 bits OS.
51
49
  when 8 then mq_attr.maxmsg * 8 + mq_attr.maxmsg * mq_attr.msgsize
52
50
  end
51
+
52
+ # If --num-instances is given, then multiply it by its value.
53
+ mq_size *= options[:num_instances]
54
+
53
55
  log_system_debug "queue requires #{mq_size} bytes" if $oversip_debug
54
56
 
55
57
  # Set RLIMIT_MSGQUEUE (ulimit) in order to create the queue with required
56
58
  # 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
59
+ if ( current_rlimit = ::Process.getrlimit(12)[1] ) < mq_size
60
+ log_system_debug "incrementing rlimits (currently #{current_rlimit} bytes) to #{mq_size} bytes (ulimit -q)" if $oversip_debug
60
61
  begin
61
- ::Process.setrlimit(12, @total_size)
62
+ ::Process.setrlimit(12, mq_size)
62
63
  rescue Errno::EPERM
63
- fatal "current user has no permissions to increase rlimits to #{@total_size} bytes (ulimit -q)"
64
+ fatal "current user has no permissions to increase rlimits to #{mq_size} bytes (ulimit -q)"
64
65
  end
65
66
  end
66
67
 
@@ -5,7 +5,7 @@ module OverSIP
5
5
  module Version
6
6
  MAJOR = 1
7
7
  MINOR = 0
8
- TINY = 2
8
+ TINY = 3
9
9
  end
10
10
 
11
11
  PROGRAM_NAME = "OverSIP"
data/lib/oversip.rb CHANGED
@@ -37,7 +37,8 @@ module OverSIP
37
37
  :syslogger_pid, :syslogger_mq_name,
38
38
  :configuration,
39
39
  :proxies,
40
- :tls, :tls_public_cert, :tls_private_cert, :tls_proxy_ipv4, :tls_proxy_ipv6
40
+ :tls, :tls_public_cert, :tls_private_cert, :tls_proxy_ipv4, :tls_proxy_ipv6,
41
+ :stud_pids
41
42
 
42
43
  def master?
43
44
  @master_pid == $$
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oversip
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.0.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-07-16 00:00:00.000000000 Z
12
+ date: 2012-07-25 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: eventmachine-le
16
- requirement: &8648800 !ruby/object:Gem::Requirement
16
+ requirement: &13970320 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 1.1.2
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *8648800
24
+ version_requirements: *13970320
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: iobuffer
27
- requirement: &8648320 !ruby/object:Gem::Requirement
27
+ requirement: &13969800 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 1.1.2
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *8648320
35
+ version_requirements: *13969800
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: em-posixmq
38
- requirement: &8647860 !ruby/object:Gem::Requirement
38
+ requirement: &13969120 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: 0.2.3
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *8647860
46
+ version_requirements: *13969120
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: em-udns
49
- requirement: &8647340 !ruby/object:Gem::Requirement
49
+ requirement: &13968220 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: 0.3.6
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *8647340
57
+ version_requirements: *13968220
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: escape_utils
60
- requirement: &8646840 !ruby/object:Gem::Requirement
60
+ requirement: &13967120 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: 0.2.4
66
66
  type: :runtime
67
67
  prerelease: false
68
- version_requirements: *8646840
68
+ version_requirements: *13967120
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: term-ansicolor
71
- requirement: &8646380 !ruby/object:Gem::Requirement
71
+ requirement: &13966420 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,18 +76,29 @@ dependencies:
76
76
  version: '0'
77
77
  type: :runtime
78
78
  prerelease: false
79
- version_requirements: *8646380
79
+ version_requirements: *13966420
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: posix-spawn
82
- requirement: &8645760 !ruby/object:Gem::Requirement
82
+ requirement: &13965860 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ! '>='
86
86
  - !ruby/object:Gem::Version
87
- version: '0'
87
+ version: 0.3.6
88
88
  type: :runtime
89
89
  prerelease: false
90
- version_requirements: *8645760
90
+ version_requirements: *13965860
91
+ - !ruby/object:Gem::Dependency
92
+ name: rake
93
+ requirement: &13965060 !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ~>
97
+ - !ruby/object:Gem::Version
98
+ version: 0.9.2
99
+ type: :development
100
+ prerelease: false
101
+ version_requirements: *13965060
91
102
  description: ! "OverSIP is an async SIP server. Built on top of Ruby EventMachine\n
92
103
  \ library it follows the Reactor Pattern, allowing thousands of concurrent connections
93
104
  and requests\n handled by a single processor in a never-blocking fashion. It