oversip 1.0.2 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
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