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 +1 -1
- data/bin/oversip +22 -10
- data/debian/preinst +1 -1
- data/lib/oversip/config.rb +19 -32
- data/lib/oversip/launcher.rb +51 -10
- data/lib/oversip/logger.rb +2 -1
- data/lib/oversip/posix_mq.rb +8 -7
- data/lib/oversip/version.rb +1 -1
- data/lib/oversip.rb +2 -1
- metadata +28 -17
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
<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/
|
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
|
-
:
|
29
|
+
:num_instances => 1,
|
30
|
+
:colorize => true
|
32
31
|
}
|
33
32
|
|
34
|
-
OptionParser.new("",
|
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", "--
|
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("-
|
50
|
-
options[:
|
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[:
|
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
data/lib/oversip/config.rb
CHANGED
@@ -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
|
-
|
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
|
138
|
-
@
|
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
|
129
|
+
conf_yaml = ::YAML.load_file @config_file
|
142
130
|
rescue => e
|
143
|
-
fatal "error loading configuration file '#{
|
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(@
|
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(@
|
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(@
|
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
|
data/lib/oversip/launcher.rb
CHANGED
@@ -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
|
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
|
-
#
|
447
|
-
|
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
|
-
|
505
|
-
|
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
|
data/lib/oversip/logger.rb
CHANGED
@@ -16,7 +16,7 @@ module OverSIP
|
|
16
16
|
"emerg" => 7
|
17
17
|
}
|
18
18
|
|
19
|
-
def self.init_logger_mq
|
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
|
data/lib/oversip/posix_mq.rb
CHANGED
@@ -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
|
-
|
58
|
-
|
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,
|
62
|
+
::Process.setrlimit(12, mq_size)
|
62
63
|
rescue Errno::EPERM
|
63
|
-
fatal "current user has no permissions to increase rlimits to #{
|
64
|
+
fatal "current user has no permissions to increase rlimits to #{mq_size} bytes (ulimit -q)"
|
64
65
|
end
|
65
66
|
end
|
66
67
|
|
data/lib/oversip/version.rb
CHANGED
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.
|
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-
|
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: &
|
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: *
|
24
|
+
version_requirements: *13970320
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: iobuffer
|
27
|
-
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: *
|
35
|
+
version_requirements: *13969800
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: em-posixmq
|
38
|
-
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: *
|
46
|
+
version_requirements: *13969120
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: em-udns
|
49
|
-
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: *
|
57
|
+
version_requirements: *13968220
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: escape_utils
|
60
|
-
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: *
|
68
|
+
version_requirements: *13967120
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: term-ansicolor
|
71
|
-
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: *
|
79
|
+
version_requirements: *13966420
|
80
80
|
- !ruby/object:Gem::Dependency
|
81
81
|
name: posix-spawn
|
82
|
-
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:
|
87
|
+
version: 0.3.6
|
88
88
|
type: :runtime
|
89
89
|
prerelease: false
|
90
|
-
version_requirements: *
|
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
|