oversip_p 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (132) hide show
  1. checksums.yaml +7 -0
  2. data/AUTHORS +22 -0
  3. data/LICENSE +25 -0
  4. data/README.md +43 -0
  5. data/Rakefile +54 -0
  6. data/bin/oversip +184 -0
  7. data/etc/oversip.conf +274 -0
  8. data/etc/proxies.conf +145 -0
  9. data/etc/server.rb +315 -0
  10. data/etc/tls/ca/cacert.pem +3894 -0
  11. data/etc/tls/demo-tls.oversip.net.crt +17 -0
  12. data/etc/tls/demo-tls.oversip.net.key +15 -0
  13. data/etc/tls/upgrade-cacert.sh +12 -0
  14. data/etc/tls/utils/create-cert.rb +162 -0
  15. data/etc/tls/utils/get-sip-identities.rb +95 -0
  16. data/ext/common/c_util.h +74 -0
  17. data/ext/common/ruby_c_util.h +88 -0
  18. data/ext/sip_parser/common_headers.h +210 -0
  19. data/ext/sip_parser/ext_help.h +18 -0
  20. data/ext/sip_parser/extconf.rb +3 -0
  21. data/ext/sip_parser/sip_message_parser.c +29741 -0
  22. data/ext/sip_parser/sip_parser.h +250 -0
  23. data/ext/sip_parser/sip_parser_ruby.c +1370 -0
  24. data/ext/sip_parser/sip_uri_parser.c +39699 -0
  25. data/ext/stud/extconf.rb +43 -0
  26. data/ext/stun/ext_help.h +16 -0
  27. data/ext/stun/extconf.rb +3 -0
  28. data/ext/stun/stun_ruby.c +394 -0
  29. data/ext/utils/ext_help.h +14 -0
  30. data/ext/utils/extconf.rb +3 -0
  31. data/ext/utils/haproxy_protocol.c +6163 -0
  32. data/ext/utils/haproxy_protocol.h +27 -0
  33. data/ext/utils/ip_utils.c +5952 -0
  34. data/ext/utils/ip_utils.h +64 -0
  35. data/ext/utils/outbound_utils.c +3227 -0
  36. data/ext/utils/outbound_utils.h +27 -0
  37. data/ext/utils/utils_ruby.c +392 -0
  38. data/ext/utils/utils_ruby.h +76 -0
  39. data/ext/websocket_framing_utils/ext_help.h +18 -0
  40. data/ext/websocket_framing_utils/extconf.rb +3 -0
  41. data/ext/websocket_framing_utils/ws_framing_utils.h +47 -0
  42. data/ext/websocket_framing_utils/ws_framing_utils_ruby.c +135 -0
  43. data/ext/websocket_http_parser/ext_help.h +18 -0
  44. data/ext/websocket_http_parser/extconf.rb +3 -0
  45. data/ext/websocket_http_parser/ws_http_parser.c +1635 -0
  46. data/ext/websocket_http_parser/ws_http_parser.h +87 -0
  47. data/ext/websocket_http_parser/ws_http_parser_ruby.c +630 -0
  48. data/lib/oversip/config.rb +597 -0
  49. data/lib/oversip/config_validators.rb +126 -0
  50. data/lib/oversip/default_server.rb +52 -0
  51. data/lib/oversip/errors.rb +10 -0
  52. data/lib/oversip/fiber_pool.rb +56 -0
  53. data/lib/oversip/launcher.rb +635 -0
  54. data/lib/oversip/logger.rb +84 -0
  55. data/lib/oversip/modules/outbound_mangling.rb +56 -0
  56. data/lib/oversip/modules/user_assertion.rb +73 -0
  57. data/lib/oversip/proxies_config.rb +189 -0
  58. data/lib/oversip/ruby_ext/eventmachine.rb +38 -0
  59. data/lib/oversip/sip/client.rb +428 -0
  60. data/lib/oversip/sip/client_transaction.rb +586 -0
  61. data/lib/oversip/sip/constants.rb +88 -0
  62. data/lib/oversip/sip/core.rb +217 -0
  63. data/lib/oversip/sip/launcher.rb +221 -0
  64. data/lib/oversip/sip/listeners/connection.rb +54 -0
  65. data/lib/oversip/sip/listeners/ipv4_tcp_client.rb +21 -0
  66. data/lib/oversip/sip/listeners/ipv4_tcp_server.rb +22 -0
  67. data/lib/oversip/sip/listeners/ipv4_tls_client.rb +21 -0
  68. data/lib/oversip/sip/listeners/ipv4_tls_server.rb +22 -0
  69. data/lib/oversip/sip/listeners/ipv4_tls_tunnel_server.rb +22 -0
  70. data/lib/oversip/sip/listeners/ipv4_udp_server.rb +21 -0
  71. data/lib/oversip/sip/listeners/ipv6_tcp_client.rb +21 -0
  72. data/lib/oversip/sip/listeners/ipv6_tcp_server.rb +22 -0
  73. data/lib/oversip/sip/listeners/ipv6_tls_client.rb +21 -0
  74. data/lib/oversip/sip/listeners/ipv6_tls_server.rb +22 -0
  75. data/lib/oversip/sip/listeners/ipv6_tls_tunnel_server.rb +22 -0
  76. data/lib/oversip/sip/listeners/ipv6_udp_server.rb +21 -0
  77. data/lib/oversip/sip/listeners/tcp_client.rb +97 -0
  78. data/lib/oversip/sip/listeners/tcp_connection.rb +202 -0
  79. data/lib/oversip/sip/listeners/tcp_server.rb +71 -0
  80. data/lib/oversip/sip/listeners/tls_client.rb +125 -0
  81. data/lib/oversip/sip/listeners/tls_server.rb +88 -0
  82. data/lib/oversip/sip/listeners/tls_tunnel_connection.rb +89 -0
  83. data/lib/oversip/sip/listeners/tls_tunnel_server.rb +61 -0
  84. data/lib/oversip/sip/listeners/udp_connection.rb +214 -0
  85. data/lib/oversip/sip/listeners.rb +24 -0
  86. data/lib/oversip/sip/message.rb +177 -0
  87. data/lib/oversip/sip/message_processor.rb +213 -0
  88. data/lib/oversip/sip/name_addr.rb +51 -0
  89. data/lib/oversip/sip/proxy.rb +324 -0
  90. data/lib/oversip/sip/request.rb +179 -0
  91. data/lib/oversip/sip/response.rb +37 -0
  92. data/lib/oversip/sip/rfc3263.rb +643 -0
  93. data/lib/oversip/sip/server_transaction.rb +295 -0
  94. data/lib/oversip/sip/sip.rb +76 -0
  95. data/lib/oversip/sip/tags.rb +39 -0
  96. data/lib/oversip/sip/timers.rb +55 -0
  97. data/lib/oversip/sip/transport_manager.rb +130 -0
  98. data/lib/oversip/sip/uac.rb +89 -0
  99. data/lib/oversip/sip/uac_request.rb +84 -0
  100. data/lib/oversip/sip/uri.rb +208 -0
  101. data/lib/oversip/syslog.rb +68 -0
  102. data/lib/oversip/system_callbacks.rb +45 -0
  103. data/lib/oversip/tls.rb +172 -0
  104. data/lib/oversip/utils.rb +30 -0
  105. data/lib/oversip/version.rb +21 -0
  106. data/lib/oversip/websocket/constants.rb +55 -0
  107. data/lib/oversip/websocket/http_request.rb +59 -0
  108. data/lib/oversip/websocket/launcher.rb +183 -0
  109. data/lib/oversip/websocket/listeners/connection.rb +51 -0
  110. data/lib/oversip/websocket/listeners/ipv4_ws_server.rb +22 -0
  111. data/lib/oversip/websocket/listeners/ipv4_wss_server.rb +22 -0
  112. data/lib/oversip/websocket/listeners/ipv4_wss_tunnel_server.rb +22 -0
  113. data/lib/oversip/websocket/listeners/ipv6_ws_server.rb +22 -0
  114. data/lib/oversip/websocket/listeners/ipv6_wss_server.rb +22 -0
  115. data/lib/oversip/websocket/listeners/ipv6_wss_tunnel_server.rb +22 -0
  116. data/lib/oversip/websocket/listeners/ws_server.rb +331 -0
  117. data/lib/oversip/websocket/listeners/wss_server.rb +88 -0
  118. data/lib/oversip/websocket/listeners/wss_tunnel_server.rb +133 -0
  119. data/lib/oversip/websocket/listeners.rb +13 -0
  120. data/lib/oversip/websocket/websocket.rb +13 -0
  121. data/lib/oversip/websocket/ws_framing.rb +545 -0
  122. data/lib/oversip/websocket/ws_sip_app.rb +120 -0
  123. data/lib/oversip.rb +127 -0
  124. data/test/oversip_test_helper.rb +19 -0
  125. data/test/test_http_parser.rb +73 -0
  126. data/test/test_name_addr.rb +27 -0
  127. data/test/test_name_addr_parser.rb +24 -0
  128. data/test/test_sip_message_parser.rb +168 -0
  129. data/test/test_sip_uri_parser.rb +56 -0
  130. data/test/test_uri.rb +68 -0
  131. data/thirdparty/stud/stud.tar.gz +0 -0
  132. metadata +334 -0
@@ -0,0 +1,597 @@
1
+ module OverSIP
2
+
3
+ module Config
4
+
5
+ # Pre-declaration of Validators module (defined in other file).
6
+ module Config::Validators ; end
7
+
8
+ extend ::OverSIP::Logger
9
+ extend ::OverSIP::Config::Validators
10
+
11
+ DEFAULT_CONFIG_DIR = "/etc/oversip"
12
+ DEFAULT_TLS_DIR = "tls"
13
+ DEFAULT_TLS_CA_DIR = "tls/ca"
14
+ DEFAULT_CONFIG_FILE = "oversip.conf"
15
+ PROXIES_FILE = "proxies.conf"
16
+ SERVER_FILE = "server.rb"
17
+
18
+ def self.log_id
19
+ @log_id ||= "Config"
20
+ end
21
+
22
+
23
+ @configuration = {
24
+ :core => {
25
+ :nameservers => nil,
26
+ :syslog_facility => "user",
27
+ :syslog_level => "info"
28
+ },
29
+ :sip => {
30
+ :sip_udp => true,
31
+ :sip_tcp => true,
32
+ :sip_tls => false,
33
+ :enable_ipv4 => true,
34
+ :listen_ipv4 => nil,
35
+ :advertised_ipv4 => nil,
36
+ :enable_ipv6 => true,
37
+ :listen_ipv6 => nil,
38
+ :advertised_ipv6 => nil,
39
+ :listen_port => 5060,
40
+ :listen_port_tls => 5061,
41
+ :use_tls_tunnel => false,
42
+ :listen_port_tls_tunnel => 5062,
43
+ :callback_on_client_tls_handshake => true,
44
+ :local_domains => nil,
45
+ :tcp_keepalive_interval => nil,
46
+ :record_route_hostname_tls_ipv4 => nil,
47
+ :record_route_hostname_tls_ipv6 => nil
48
+ },
49
+ :websocket => {
50
+ :sip_ws => false,
51
+ :sip_wss => false,
52
+ :enable_ipv4 => true,
53
+ :listen_ipv4 => nil,
54
+ :advertised_ipv4 => nil,
55
+ :enable_ipv6 => true,
56
+ :listen_ipv6 => nil,
57
+ :advertised_ipv6 => nil,
58
+ :listen_port => 10080,
59
+ :listen_port_tls => 10443,
60
+ :use_tls_tunnel => false,
61
+ :listen_port_tls_tunnel => 10444,
62
+ :callback_on_client_tls_handshake => true,
63
+ :max_ws_message_size => 65536,
64
+ :max_ws_frame_size => 65536,
65
+ :ws_keepalive_interval => nil
66
+ },
67
+ :tls => {
68
+ :public_cert => nil,
69
+ :private_cert => nil,
70
+ :ca_dir => nil
71
+ }
72
+ }
73
+
74
+ CONFIG_VALIDATIONS = {
75
+ :core => {
76
+ :nameservers => [ :ipv4, :multi_value ],
77
+ :syslog_facility => [
78
+ [ :choices,
79
+ %w{ kern user daemon local0 local1 local2 local3 local4 local5 local6 local7 } ]
80
+ ],
81
+ :syslog_level => [
82
+ [ :choices,
83
+ %w{ debug info notice warn error crit } ]
84
+ ],
85
+ },
86
+ :sip => {
87
+ :sip_udp => :boolean,
88
+ :sip_tcp => :boolean,
89
+ :sip_tls => :boolean,
90
+ :enable_ipv4 => :boolean,
91
+ :listen_ipv4 => :ipv4,
92
+ :advertised_ipv4 => :ipv4,
93
+ :enable_ipv6 => :boolean,
94
+ :listen_ipv6 => :ipv6,
95
+ :advertised_ipv6 => :ipv6,
96
+ :listen_port => :port,
97
+ :listen_port_tls => :port,
98
+ :use_tls_tunnel => :boolean,
99
+ :listen_port_tls_tunnel => :port,
100
+ :callback_on_client_tls_handshake => :boolean,
101
+ :local_domains => [ :domain, :multi_value ],
102
+ :tcp_keepalive_interval => [ :fixnum, [ :greater_equal_than, 180 ] ],
103
+ :record_route_hostname_tls_ipv4 => :domain,
104
+ :record_route_hostname_tls_ipv6 => :domain,
105
+ },
106
+ :websocket => {
107
+ :sip_ws => :boolean,
108
+ :sip_wss => :boolean,
109
+ :enable_ipv4 => :boolean,
110
+ :listen_ipv4 => :ipv4,
111
+ :advertised_ipv4 => :ipv4,
112
+ :enable_ipv6 => :boolean,
113
+ :listen_ipv6 => :ipv6,
114
+ :advertised_ipv6 => :ipv6,
115
+ :listen_port => :port,
116
+ :listen_port_tls => :port,
117
+ :use_tls_tunnel => :boolean,
118
+ :listen_port_tls_tunnel => :port,
119
+ :callback_on_client_tls_handshake => :boolean,
120
+ :max_ws_message_size => [ :fixnum, [ :minor_than, 1048576 ] ],
121
+ :max_ws_frame_size => [ :fixnum, [ :minor_than, 1048576 ] ],
122
+ :ws_keepalive_interval => [ :fixnum, [ :greater_equal_than, 180 ] ]
123
+ },
124
+ :tls => {
125
+ :public_cert => [ :readable_file, :tls_pem_chain ],
126
+ :private_cert => [ :readable_file, :tls_pem_private ],
127
+ :ca_dir => :readable_dir
128
+ }
129
+ }
130
+
131
+
132
+ def self.load config_dir=nil, config_file=nil
133
+ @config_dir = (::File.expand_path(config_dir) if config_dir) || DEFAULT_CONFIG_DIR
134
+ @config_file = ::File.join(@config_dir, config_file || DEFAULT_CONFIG_FILE)
135
+ @proxies_file = ::File.join(@config_dir, PROXIES_FILE)
136
+ @server_file = ::File.join(@config_dir, SERVER_FILE)
137
+
138
+ # Load the oversip.conf YAML file.
139
+ begin
140
+ conf_yaml = ::YAML.load_file @config_file
141
+ rescue ::Exception => e
142
+ log_system_crit "error loading Main Configuration file '#{@config_file}':"
143
+ ::OverSIP::Launcher.fatal e
144
+ end
145
+
146
+ # Load the proxies.conf YAML file.
147
+ begin
148
+ proxies_yaml = ::YAML.load_file @proxies_file
149
+ rescue ::Exception => e
150
+ log_system_crit "error loading Proxies Configuration file '#{@proxies_file}':"
151
+ ::OverSIP::Launcher.fatal e
152
+ end
153
+
154
+ # Load the server.rb file.
155
+ begin
156
+ require @server_file
157
+ rescue ::Exception => e
158
+ log_system_crit "error loading Server file '#{@server_file}':"
159
+ ::OverSIP::Launcher.fatal e
160
+ end
161
+
162
+ # Process the oversip.conf file.
163
+ begin
164
+ pre_check(conf_yaml)
165
+
166
+ CONFIG_VALIDATIONS.each_key do |section|
167
+ CONFIG_VALIDATIONS[section].each do |parameter, validations|
168
+ values = conf_yaml[section.to_s][parameter.to_s] rescue nil
169
+ validations = [ validations ] unless validations.is_a?(Array)
170
+
171
+ if values == nil
172
+ if validations.include? :required
173
+ ::OverSIP::Launcher.fatal "#{section}[#{parameter}] requires a value"
174
+ end
175
+ next
176
+ end
177
+
178
+ if values.is_a? ::Array
179
+ unless validations.include? :multi_value
180
+ ::OverSIP::Launcher.fatal "#{section}[#{parameter}] does not allow multiple values"
181
+ end
182
+
183
+ if validations.include? :non_empty and values.empty?
184
+ ::OverSIP::Launcher.fatal "#{section}[#{parameter}] does not allow empty values"
185
+ end
186
+ end
187
+
188
+ values = ( values.is_a?(::Array) ? values : [ values ] )
189
+
190
+ values.each do |value|
191
+ validations.each do |validation|
192
+
193
+ if validation.is_a? ::Symbol
194
+ args = []
195
+ elsif validation.is_a? ::Array
196
+ args = validation[1..-1]
197
+ validation = validation[0]
198
+ end
199
+
200
+ next if [:required, :multi_value, :non_empty].include? validation
201
+
202
+ unless send validation, value, *args
203
+ ::OverSIP::Launcher.fatal "#{section}[#{parameter}] has invalid value '#{humanize_value value}' (does not satisfy '#{validation}' validation requirement)"
204
+ end
205
+ end
206
+
207
+ @configuration[section][parameter] = ( validations.include?(:multi_value) ? values : values[0] )
208
+ end
209
+
210
+ end # CONFIG_VALIDATIONS[section].each
211
+ end # CONFIG_VALIDATIONS.each_key
212
+
213
+ post_process
214
+ post_check
215
+
216
+ rescue ::OverSIP::ConfigurationError => e
217
+ ::OverSIP::Launcher.fatal "configuration error: #{e.message}"
218
+ rescue => e
219
+ ::OverSIP::Launcher.fatal e
220
+ end
221
+
222
+ ::OverSIP.configuration = @configuration
223
+
224
+ # Process the proxies.conf file.
225
+ begin
226
+ ::OverSIP::ProxiesConfig.load proxies_yaml
227
+ rescue ::OverSIP::ConfigurationError => e
228
+ ::OverSIP::Launcher.fatal "error loading Proxies Configuration file '#{@proxies_file}': #{e.message}"
229
+ rescue ::Exception => e
230
+ log_system_crit "error loading Proxies Configuration file '#{@proxies_file}':"
231
+ ::OverSIP::Launcher.fatal e
232
+ end
233
+ end
234
+
235
+
236
+ def self.pre_check conf_yaml
237
+ # If TLS files/directories are given as relative path, convert them into absolute paths.
238
+
239
+ tls_public_cert = conf_yaml["tls"]["public_cert"] rescue nil
240
+ tls_private_cert = conf_yaml["tls"]["private_cert"] rescue nil
241
+ tls_ca_dir = conf_yaml["tls"]["ca_dir"] rescue nil
242
+
243
+ if tls_public_cert.is_a?(::String) and tls_public_cert[0] != "/"
244
+ conf_yaml["tls"]["public_cert"] = ::File.join(@config_dir, DEFAULT_TLS_DIR, tls_public_cert)
245
+ end
246
+
247
+ if tls_private_cert.is_a?(::String) and tls_private_cert[0] != "/"
248
+ conf_yaml["tls"]["private_cert"] = ::File.join(@config_dir, DEFAULT_TLS_DIR, tls_private_cert)
249
+ end
250
+
251
+ if tls_ca_dir.is_a?(::String) and tls_ca_dir[0] != "/"
252
+ conf_yaml["tls"]["ca_dir"] = ::File.join(@config_dir, DEFAULT_TLS_DIR, tls_ca_dir)
253
+ end
254
+ end
255
+
256
+ def self.post_process
257
+ if @configuration[:tls][:public_cert] and @configuration[:tls][:private_cert]
258
+ @use_tls = true
259
+ # Generate a full PEM file containing both the public and private certificate (for Stud).
260
+ full_cert = ::Tempfile.new("oversip_full_cert_")
261
+ full_cert.puts ::File.read(@configuration[:tls][:public_cert])
262
+ full_cert.puts ::File.read(@configuration[:tls][:private_cert])
263
+ @configuration[:tls][:full_cert] = full_cert.path
264
+ full_cert.close
265
+ else
266
+ @configuration[:sip][:sip_tls] = false
267
+ @configuration[:websocket][:sip_wss] = false
268
+ end
269
+
270
+ if @configuration[:sip][:sip_udp] or @configuration[:sip][:sip_tcp]
271
+ @use_sip_udp_or_tcp = true
272
+ else
273
+ @configuration[:sip][:listen_port] = nil
274
+ end
275
+
276
+ if @configuration[:sip][:sip_tls] and @use_tls
277
+ @use_sip_tls = true
278
+ else
279
+ @configuration[:sip][:listen_port_tls] = nil
280
+ end
281
+
282
+ unless @use_sip_udp_or_tcp or @use_sip_tls
283
+ @configuration[:sip][:listen_ipv4] = nil
284
+ @configuration[:sip][:listen_ipv6] = nil
285
+ @configuration[:sip][:enable_ipv4] = nil
286
+ @configuration[:sip][:enable_ipv6] = nil
287
+ end
288
+
289
+ unless @configuration[:sip][:enable_ipv4]
290
+ @configuration[:sip][:listen_ipv4] = nil
291
+ @configuration[:sip][:advertised_ipv4] = nil
292
+ @configuration[:sip][:record_route_hostname_tls_ipv4] = nil
293
+ end
294
+
295
+ unless @configuration[:sip][:enable_ipv6]
296
+ @configuration[:sip][:listen_ipv6] = nil
297
+ @configuration[:sip][:advertised_ipv6] = nil
298
+ @configuration[:sip][:record_route_hostname_tls_ipv6] = nil
299
+ end
300
+
301
+ if @configuration[:websocket][:sip_ws]
302
+ @use_sip_ws = true
303
+ else
304
+ @configuration[:websocket][:listen_port] = nil
305
+ end
306
+
307
+ if @configuration[:websocket][:sip_wss] and @use_tls
308
+ @use_sip_wss = true
309
+ else
310
+ @configuration[:websocket][:listen_port_tls] = nil
311
+ end
312
+
313
+ unless @use_sip_ws or @use_sip_wss
314
+ @configuration[:websocket][:listen_ipv4] = nil
315
+ @configuration[:websocket][:listen_ipv6] = nil
316
+ @configuration[:websocket][:enable_ipv4] = nil
317
+ @configuration[:websocket][:enable_ipv6] = nil
318
+ end
319
+
320
+ unless @configuration[:websocket][:enable_ipv4]
321
+ @configuration[:websocket][:listen_ipv4] = nil
322
+ @configuration[:websocket][:advertised_ipv4] = nil
323
+ end
324
+
325
+ unless @configuration[:websocket][:enable_ipv6]
326
+ @configuration[:websocket][:listen_ipv6] = nil
327
+ @configuration[:websocket][:advertised_ipv6] = nil
328
+ end
329
+
330
+ if ( @use_sip_udp_or_tcp or @use_sip_tls ) and @configuration[:sip][:listen_ipv4] == nil and @configuration[:sip][:enable_ipv4]
331
+ unless (@configuration[:sip][:listen_ipv4] = discover_local_ip(:ipv4))
332
+ # log_system_notice "disabling IPv4 for SIP"
333
+ @configuration[:sip][:listen_ipv4] = nil
334
+ @configuration[:sip][:enable_ipv4] = false
335
+ end
336
+ end
337
+
338
+ if ( @use_sip_udp_or_tcp or @use_sip_tls ) and @configuration[:sip][:listen_ipv6] == nil and @configuration[:sip][:enable_ipv6]
339
+ unless (@configuration[:sip][:listen_ipv6] = discover_local_ip(:ipv6))
340
+ # log_system_notice "disabling IPv6 for SIP"
341
+ @configuration[:sip][:listen_ipv6] = nil
342
+ @configuration[:sip][:enable_ipv6] = false
343
+ end
344
+ end
345
+
346
+ if ( @use_sip_ws or @use_sip_wss ) and @configuration[:websocket][:listen_ipv4] == nil and @configuration[:websocket][:enable_ipv4]
347
+ unless (@configuration[:websocket][:listen_ipv4] = discover_local_ip(:ipv4))
348
+ # log_system_notice "disabling IPv4 for WebSocket"
349
+ @configuration[:websocket][:listen_ipv4] = nil
350
+ @configuration[:websocket][:enable_ipv4] = false
351
+ end
352
+ end
353
+
354
+ if ( @use_sip_ws or @use_sip_wss ) and @configuration[:websocket][:listen_ipv6] == nil and @configuration[:websocket][:enable_ipv6]
355
+ unless (@configuration[:websocket][:listen_ipv6] = discover_local_ip(:ipv6))
356
+ # log_system_notice "disabling IPv6 for WebSocket"
357
+ @configuration[:websocket][:listen_ipv6] = nil
358
+ @configuration[:websocket][:enable_ipv6] = false
359
+ end
360
+ end
361
+
362
+ if @configuration[:sip][:local_domains]
363
+ if @configuration[:sip][:local_domains].is_a? ::String
364
+ @configuration[:sip][:local_domains] = [ @configuration[:sip][:local_domains].downcase ]
365
+ end
366
+ @configuration[:sip][:local_domains].each {|local_domain| local_domain.downcase!}
367
+ end
368
+ end # def self.post_process
369
+
370
+
371
+ def self.post_check
372
+ binds = { :udp => [], :tcp => [] }
373
+
374
+ if @configuration[:sip][:enable_ipv4]
375
+ ipv4 = @configuration[:sip][:listen_ipv4]
376
+
377
+ if @configuration[:sip][:sip_udp]
378
+ binds[:udp] << [ ipv4, @configuration[:sip][:listen_port] ]
379
+ end
380
+
381
+ if @configuration[:sip][:sip_tcp]
382
+ binds[:tcp] << [ ipv4, @configuration[:sip][:listen_port] ]
383
+ end
384
+
385
+ if @configuration[:sip][:sip_tls]
386
+ unless @configuration[:sip][:use_tls_tunnel]
387
+ binds[:tcp] << [ ipv4, @configuration[:sip][:listen_port_tls] ]
388
+ else
389
+ binds[:tcp] << [ "127.0.0.1", @configuration[:sip][:listen_port_tls_tunnel] ]
390
+ end
391
+ end
392
+ end
393
+
394
+ if @configuration[:sip][:enable_ipv6]
395
+ ipv6 = @configuration[:sip][:listen_ipv6]
396
+
397
+ if @configuration[:sip][:sip_udp]
398
+ binds[:udp] << [ ipv6, @configuration[:sip][:listen_port] ]
399
+ end
400
+
401
+ if @configuration[:sip][:sip_tcp]
402
+ binds[:tcp] << [ ipv6, @configuration[:sip][:listen_port] ]
403
+ end
404
+
405
+ if @configuration[:sip][:sip_tls]
406
+ unless @configuration[:sip][:use_tls_tunnel]
407
+ binds[:tcp] << [ ipv6, @configuration[:sip][:listen_port_tls] ]
408
+ else
409
+ binds[:tcp] << [ "::1", @configuration[:sip][:listen_port_tls_tunnel] ]
410
+ end
411
+ end
412
+ end
413
+
414
+ if @configuration[:websocket][:enable_ipv4]
415
+ ipv4 = @configuration[:websocket][:listen_ipv4]
416
+
417
+ if @configuration[:websocket][:sip_ws]
418
+ binds[:tcp] << [ ipv4, @configuration[:websocket][:listen_port] ]
419
+ end
420
+
421
+ if @configuration[:websocket][:sip_wss]
422
+ unless @configuration[:sip][:use_tls_tunnel]
423
+ binds[:tcp] << [ ipv4, @configuration[:websocket][:listen_port_tls] ]
424
+ else
425
+ binds[:tcp] << [ "127.0.0.1", @configuration[:websocket][:listen_port_tls_tunnel] ]
426
+ end
427
+ end
428
+ end
429
+
430
+ if @configuration[:websocket][:enable_ipv6]
431
+ ipv6 = @configuration[:websocket][:listen_ipv6]
432
+
433
+ if @configuration[:websocket][:sip_ws]
434
+ binds[:tcp] << [ ipv6, @configuration[:websocket][:listen_port] ]
435
+ end
436
+
437
+ if @configuration[:websocket][:sip_wss]
438
+ unless @configuration[:sip][:use_tls_tunnel]
439
+ binds[:tcp] << [ ipv6, @configuration[:websocket][:listen_port_tls] ]
440
+ else
441
+ binds[:tcp] << [ "::1", @configuration[:websocket][:listen_port_tls_tunnel] ]
442
+ end
443
+ end
444
+ end
445
+
446
+ unless @configuration[:sip][:use_tls_tunnel]
447
+ @configuration[:sip][:listen_port_tls_tunnel] = nil
448
+ end
449
+
450
+ unless @configuration[:websocket][:use_tls_tunnel]
451
+ @configuration[:websocket][:listen_port_tls_tunnel] = nil
452
+ end
453
+
454
+ [:udp, :tcp].each do |transport|
455
+ transport_str = transport.to_s.upcase
456
+ binds[transport].each do |ip, port|
457
+ begin
458
+ unless (ip_type = ::OverSIP::Utils.ip_type(ip))
459
+ raise ::OverSIP::ConfigurationError, "given IP '#{ip}' is not IPv4 nor IPv6"
460
+ end
461
+
462
+ case transport
463
+ when :udp
464
+ case ip_type
465
+ when :ipv4
466
+ socket = ::UDPSocket.new ::Socket::AF_INET
467
+ when :ipv6
468
+ socket = ::UDPSocket.new ::Socket::AF_INET6
469
+ end
470
+ socket.bind ip, port
471
+ when :tcp
472
+ socket = ::TCPServer.open ip, port
473
+ end
474
+
475
+ socket.close
476
+
477
+ rescue ::Errno::EADDRNOTAVAIL
478
+ raise ::OverSIP::ConfigurationError, "cannot bind in #{transport_str} IP '#{ip}', address not available"
479
+ rescue ::Errno::EADDRINUSE
480
+ raise ::OverSIP::ConfigurationError, "#{transport_str} IP '#{ip}' and port #{port} already in use"
481
+ rescue ::Errno::EACCES
482
+ raise ::OverSIP::ConfigurationError, "no permission to bind in #{transport_str} IP '#{ip}' and port #{port}"
483
+ rescue => e
484
+ raise e.class, "error binding in #{transport_str} IP '#{ip}' and port #{port} (#{e.class}: #{e.message})"
485
+ end
486
+ end
487
+ end
488
+ end # def self.post_check
489
+
490
+
491
+ def self.print colorize=true
492
+ color = ::Term::ANSIColor if colorize
493
+
494
+ puts
495
+ @configuration.each_key do |section|
496
+ if colorize
497
+ puts " #{color.bold(section.to_s)}:"
498
+ else
499
+ puts " #{section.to_s}:"
500
+ end
501
+ @configuration[section].each do |parameter, value|
502
+ humanized_value = humanize_value value
503
+ color_value = case value
504
+ when ::TrueClass
505
+ colorize ? color.bold(color.green(humanized_value)) : humanized_value
506
+ when ::FalseClass
507
+ colorize ? color.bold(color.red(humanized_value)) : humanized_value
508
+ when ::NilClass
509
+ humanized_value
510
+ when ::String, ::Symbol
511
+ colorize ? color.yellow(humanized_value) : humanized_value
512
+ when ::Array
513
+ colorize ? color.yellow(humanized_value) : humanized_value
514
+ when ::Fixnum, ::Float
515
+ colorize ? color.bold(color.blue(humanized_value)) : humanized_value
516
+ else
517
+ humanized_value
518
+ end
519
+ printf(" %-32s: %s\n", parameter, color_value)
520
+ end
521
+ puts
522
+ end
523
+ end
524
+
525
+ def self.humanize_value value
526
+ case value
527
+ when ::TrueClass ; "yes"
528
+ when ::FalseClass ; "no"
529
+ when ::NilClass ; "null"
530
+ when ::String ; value
531
+ when ::Symbol ; value.to_s
532
+ when ::Array ; value.join(", ")
533
+ when ::Fixnum, ::Float ; value.to_s
534
+ else ; value.to_s
535
+ end
536
+ end
537
+
538
+ def self.discover_local_ip(type)
539
+ begin
540
+ if type == :ipv4
541
+ socket = ::UDPSocket.new ::Socket::AF_INET
542
+ socket.connect("1.2.3.4", 1)
543
+ ip = socket.local_address.ip_address
544
+ socket.close
545
+ socket = ::UDPSocket.new ::Socket::AF_INET
546
+ elsif type == :ipv6
547
+ socket = ::UDPSocket.new ::Socket::AF_INET6
548
+ socket.connect("2001::1", 1)
549
+ ip = socket.local_address.ip_address
550
+ socket.close
551
+ socket = ::UDPSocket.new ::Socket::AF_INET6
552
+ end
553
+ # Test whether the IP is in fact bindeable (not true for link-scope IPv6 addresses).
554
+ begin
555
+ socket.bind ip, 0
556
+ rescue => e
557
+ # log_system_debug "cannot bind in autodiscovered local #{type == :ipv4 ? "IPv4" : "IPv6"} '#{ip}': #{e.message} (#{e.class})"
558
+ return false
559
+ ensure
560
+ socket.close
561
+ end
562
+ # Valid IP, return it.
563
+ return ip
564
+ rescue => e
565
+ # log_system_debug "cannot autodiscover local #{type == :ipv4 ? "IPv4" : "IPv6"}: #{e.message} (#{e.class})"
566
+ return false
567
+ end
568
+ end
569
+
570
+ def self.system_reload
571
+ log_system_notice "reloading OverSIP..."
572
+
573
+ # Load and process the proxies.conf file.
574
+ begin
575
+ proxies_yaml = ::YAML.load_file @proxies_file
576
+ ::OverSIP::ProxiesConfig.load proxies_yaml, reload=true
577
+ log_system_notice "Proxies Configuration file '#{@proxies_file}' reloaded"
578
+ rescue ::OverSIP::ConfigurationError => e
579
+ log_system_crit "error reloading Proxies Configuration file '#{@proxies_file}': #{e.message}"
580
+ rescue ::Exception => e
581
+ log_system_crit "error reloading Proxies Configuration file '#{@proxies_file}':"
582
+ log_system_crit e
583
+ end
584
+
585
+ # Load the server.rb file.
586
+ begin
587
+ ::Kernel.load @server_file
588
+ log_system_notice "Server file '#{@server_file}' reloaded"
589
+ rescue ::Exception => e
590
+ log_system_crit "error reloading Server file '#{@server_file}':"
591
+ log_system_crit e
592
+ end
593
+ end
594
+
595
+ end
596
+
597
+ end