oversip_p 1.0.0

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.
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