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
data/etc/proxies.conf ADDED
@@ -0,0 +1,145 @@
1
+ #
2
+ # OverSIP - Proxies Configuration.
3
+ #
4
+ #
5
+ # IMPORTANT:
6
+ # This is a YAML [1] format configuration file. DON'T USE tab for indentation
7
+ # as it's not allowed and would raise unexpected errors. Instead, respect
8
+ # the existing indentation spaces.
9
+ # [1] http://en.wikipedia.org/wiki/YAML
10
+
11
+
12
+ # Default proxy configuration.
13
+ #
14
+ default_proxy:
15
+
16
+ # For initial INVITE, SUBSCRIBE and REFER requests and in-dialog NOTIFY the proxy adds Record-Route header(s).
17
+ # For REGISTER requests the proxy adds Path header(s).
18
+ # By default _yes_.
19
+ #
20
+ do_record_routing: yes
21
+
22
+ # Enable DNS cache. By default _yes_.
23
+ #
24
+ use_dns_cache: yes
25
+
26
+ # DNS cache time (in seconds). A DNS result is removed from the cache after the given time.
27
+ # Minimum value is 300. Default value is 300.
28
+ #
29
+ dns_cache_time: 300
30
+
31
+ # Enable destination blacklist. When a destination (target) fails due to timeout, connection error
32
+ # or TLS validation error, the target is added to a temporal blacklist and requests to same
33
+ # targets are not tryed again until the entry in the blacklist expires. By default _yes_.
34
+ #
35
+ use_blacklist: yes
36
+
37
+ # Blacklist expiration time (in seconds). The time of live of failed targets within the blacklist.
38
+ #
39
+ blacklist_time: 400
40
+
41
+ # Use DNS NAPTR. If set, NAPTR query is performed when URI host is a domain, has no port nor
42
+ # ;transport param.
43
+ # Default value is _yes_.
44
+ #
45
+ use_naptr: yes
46
+
47
+ # Use DNS SRV. If set, SRV query is performed when URI host is a domain and has no port.
48
+ # If this is set to _no_ then _use_naptr_ is also set to _no_.
49
+ # Default value is _yes_.
50
+ #
51
+ use_srv: yes
52
+
53
+ # Transport preference. The list of supported transports in order of preference.
54
+ # When there is NAPTR record, its SRV records are tryed in this order just in the case
55
+ # _force_transport_preference_ is _yes_.
56
+ # If there is not NAPTR record, SRV records are then tryed in this order.
57
+ # Valid transports are "udp", "tcp" and "tls".
58
+ # Default value is ["tls", "tcp", "udp"] (first try "tls").
59
+ #
60
+ transport_preference: ["tls", "tcp", "udp"]
61
+
62
+ # Force transport preference. If _no_, transport preference is taken from NAPTR records
63
+ # (when present). If _yes_, transport preferences are taken from transport_preference
64
+ # parameter even for NAPTR records.
65
+ # Default value is _no_.
66
+ #
67
+ force_transport_preference: no
68
+
69
+ # IP type preference. When both IPv4 and IPv6 are available, this parameter determines
70
+ # whether to try first DNS A or AAAA queries. It also determines the IP type this proxy
71
+ # is allowed to use for routing requests.
72
+ # Valid IP types are "ipv4" and "ipv6".
73
+ # Default value is ["ipv4", "ipv6"] (first try "ipv4").
74
+ #
75
+ ip_type_preference: ["ipv4", "ipv6"]
76
+
77
+ # DNS failover on received 503.
78
+ # If a DNS query retrieves more than a single destinations and the first attempt
79
+ # receives a 503 response, then OverSIP tries the next destination (when this parameter
80
+ # is set) or replies a 500 error upstream (when not set).
81
+ # Default value is _yes_.
82
+ #
83
+ dns_failover_on_503: yes
84
+
85
+ # INVITE transaction timeout (in seconds).
86
+ # Time waiting for a provisional or final response.
87
+ # Minimum value is 2, maximum value is 64.
88
+ # Default value is 32.
89
+ #
90
+ timer_B: 32
91
+
92
+ # Proxy INVITE transaction timeout (in seconds).
93
+ # Time waiting for a final response.
94
+ # Minimum value is 8, maximum value is 180.
95
+ # Default value is 120.
96
+ #
97
+ timer_C: 120
98
+
99
+ # Non-INVITE transaction timeout (in seconds).
100
+ # Time waiting for a final response.
101
+ # Minimum value is 2, maximum value is 64.
102
+ # Default value is 32.
103
+ #
104
+ timer_F: 32
105
+
106
+ # Call the OverSIP::SIP.on_server_tls_handshake() callback when
107
+ # establishing an outbound SIP TLS connection with a remote SIP peer.
108
+ # By default _yes_.
109
+ #
110
+ callback_on_server_tls_handshake: yes
111
+
112
+
113
+ # Proxy configuration for routing in-dialog requests.
114
+ #
115
+ proxy_in_dialog:
116
+
117
+ use_dns: yes
118
+ use_dns_cache: yes
119
+ dns_cache_time: 300
120
+ use_naptr: no
121
+ use_srv: no
122
+ timer_B: 32
123
+ timer_C: 60
124
+ timer_F: 32
125
+
126
+
127
+ # Proxy configuration for routing initial requests to clients.
128
+ proxy_to_users:
129
+
130
+ use_dns: no
131
+ dns_failover_on_503: no
132
+ timer_B: 32
133
+ timer_F: 32
134
+
135
+
136
+ # Proxy configuration for routing initial requests to the external world.
137
+ proxy_out:
138
+
139
+ dns_failover_on_503: yes
140
+ timer_B: 6
141
+ timer_C: 60
142
+ timer_F: 6
143
+
144
+
145
+ # Add your own proxy configurations here and/or replace the above ones.
data/etc/server.rb ADDED
@@ -0,0 +1,315 @@
1
+ # coding: utf-8
2
+
3
+ #
4
+ # OverSIP - Server Logic.
5
+ #
6
+
7
+
8
+
9
+
10
+ ### Custom Application Code:
11
+
12
+
13
+ # Define here your custom code for the application running on top of OverSIP.
14
+ # Here you can load thirdy-party libraries and so on.
15
+ #
16
+ # require "some-gem"
17
+ #
18
+ module MyExampleApp
19
+ extend ::OverSIP::Logger
20
+
21
+ class << self
22
+ attr_reader :do_outbound_mangling, :do_user_assertion
23
+ end
24
+
25
+ # Set this to _true_ if the SIP registrar behind OverSIP does not support Path.
26
+ # OverSIP::Modules::OutboundMangling methods will be used.
27
+ @do_outbound_mangling = true
28
+
29
+ # Set this to _true_ if the SIP proxy/server behind OverSIP performing the authentication
30
+ # is ready to accept a P-Asserted-Identity header from OverSIP indicating the already
31
+ # asserted SIP user of the client's connection (this avoids authenticating all the requests
32
+ # but the first one).
33
+ # OverSIP::Modules::UserAssertion methods will be used.
34
+ @do_user_assertion = true
35
+ end
36
+
37
+
38
+
39
+
40
+ ### OverSIP System Events:
41
+
42
+
43
+ # This method is called when the main configuration files have been loaded.
44
+ # Place here 3rd party modules initializer code.
45
+ # This method is not executed again when OverSIP is reloaded (HUP signal).
46
+ #
47
+ # def (OverSIP::SystemEvents).on_initialize
48
+ # [...]
49
+ # end
50
+
51
+
52
+ # This method is called once the OverSIP reactor has been started.
53
+ #
54
+ # def (OverSIP::SystemEvents).on_started
55
+ # [...]
56
+ # end
57
+
58
+
59
+ # This method is called when a USR1 signal is received by OverSIP main
60
+ # process and allows the user to set custom code to be executed
61
+ # or reloaded.
62
+ #
63
+ # def (OverSIP::SystemEvents).on_user_reload
64
+ # [...]
65
+ # end
66
+
67
+
68
+ # This method is called after OverSIP has been terminated. It's called
69
+ # with argument "error" which is _true_ in case OverSIP has died in an
70
+ # unexpected way.
71
+ #
72
+ # def (OverSIP::SystemEvents).on_terminated error
73
+ # [...]
74
+ # end
75
+
76
+
77
+
78
+
79
+ ### OverSIP SIP Events:
80
+
81
+
82
+ # This method is called when a SIP request is received.
83
+ #
84
+ def (OverSIP::SipEvents).on_request request
85
+
86
+ log_info "#{request.sip_method} from #{request.from.uri} (UA: #{request.header("User-Agent")}) to #{request.ruri} via #{request.transport.upcase} #{request.source_ip} : #{request.source_port}"
87
+
88
+ # Check Max-Forwards value (max 10).
89
+ return unless request.check_max_forwards 10
90
+
91
+ # Assume all the traffic is from clients and help them with NAT issues
92
+ # by forcing rport usage and Outbound mechanism.
93
+ request.fix_nat
94
+
95
+ # In-dialog requests.
96
+ if request.in_dialog?
97
+ if request.loose_route
98
+ log_debug "proxying in-dialog #{request.sip_method}"
99
+ proxy = ::OverSIP::SIP::Proxy.new :proxy_in_dialog
100
+ proxy.route request
101
+ else
102
+ unless request.sip_method == :ACK
103
+ log_notice "forbidden in-dialog request without top Route pointing to us => 403"
104
+ request.reply 403, "forbidden in-dialog request without top Route pointing to us"
105
+ else
106
+ log_notice "ignoring not loose routing ACK"
107
+ end
108
+ end
109
+ return
110
+ end
111
+
112
+ # Initial requests.
113
+
114
+ # Check that the request does not contain a top Route pointing to another server.
115
+ if request.loose_route
116
+ unless request.sip_method == :ACK
117
+ log_notice "pre-loaded Route not allowed here => 403"
118
+ request.reply 403, "Pre-loaded Route not allowed"
119
+ else
120
+ log_notice "ignoring ACK initial request"
121
+ end
122
+ return
123
+ end
124
+
125
+ if MyExampleApp.do_outbound_mangling
126
+ # Extract the Outbound flow token from the RURI.
127
+ ::OverSIP::Modules::OutboundMangling.extract_outbound_from_ruri request
128
+ end
129
+
130
+ # The request goes to a client using Outbound through OverSIP.
131
+ if request.incoming_outbound_requested?
132
+ log_info "routing initial request to an Outbound client"
133
+
134
+ proxy = ::OverSIP::SIP::Proxy.new :proxy_to_users
135
+
136
+ proxy.on_success_response do |response|
137
+ log_info "incoming Outbound on_success_response: #{response.status_code} '#{response.reason_phrase}'"
138
+ end
139
+
140
+ proxy.on_failure_response do |response|
141
+ log_info "incoming Outbound on_failure_response: #{response.status_code} '#{response.reason_phrase}'"
142
+ end
143
+
144
+ # on_error() occurs when no SIP response was received fom the peer and, instead, we
145
+ # got some other internal error (timeout, connection error, DNS error....).
146
+ proxy.on_error do |status, reason|
147
+ log_notice "incoming Outbound on_error: #{status} '#{reason}'"
148
+ end
149
+
150
+ # Route the request and return.
151
+ proxy.route request
152
+ return
153
+ end
154
+
155
+ # An initial request with us (OverSIP) as final destination, ok, received, bye...
156
+ if request.destination_myself?
157
+ log_info "request for myself => 404"
158
+ request.reply 404, "Ok, I'm here"
159
+ return
160
+ end
161
+
162
+ # An outgoing initial request.
163
+ case request.sip_method
164
+
165
+ when :INVITE, :MESSAGE, :OPTIONS, :SUBSCRIBE, :PUBLISH, :REFER
166
+
167
+ if MyExampleApp.do_user_assertion
168
+ ::OverSIP::Modules::UserAssertion.add_pai request
169
+ end
170
+
171
+ proxy = ::OverSIP::SIP::Proxy.new :proxy_out
172
+
173
+ proxy.on_provisional_response do |response|
174
+ log_info "on_provisional_response: #{response.status_code} '#{response.reason_phrase}'"
175
+ end
176
+
177
+ proxy.on_success_response do |response|
178
+ log_info "on_success_response: #{response.status_code} '#{response.reason_phrase}'"
179
+ end
180
+
181
+ proxy.on_failure_response do |response|
182
+ log_info "on_failure_response: #{response.status_code} '#{response.reason_phrase}'"
183
+ end
184
+
185
+ proxy.on_error do |status, reason|
186
+ log_notice "on_error: #{status} '#{reason}'"
187
+ end
188
+
189
+ proxy.on_invite_timeout do
190
+ log_notice "INVITE timeout, no final response before Timer C expires."
191
+ end
192
+
193
+ proxy.route request
194
+ return
195
+
196
+ when :REGISTER
197
+
198
+ proxy = ::OverSIP::SIP::Proxy.new :proxy_out
199
+
200
+ if MyExampleApp.do_outbound_mangling
201
+ # Contact mangling for the case in which the registrar does not support Path.
202
+ ::OverSIP::Modules::OutboundMangling.add_outbound_to_contact proxy
203
+ end
204
+
205
+ proxy.on_success_response do |response|
206
+ if MyExampleApp.do_user_assertion
207
+ # The registrar replies 200 after a REGISTER with credentials so let's assert
208
+ # the current SIP user to this connection.
209
+ ::OverSIP::Modules::UserAssertion.assert_connection response
210
+ end
211
+ end
212
+
213
+ proxy.on_failure_response do |response|
214
+ if MyExampleApp.do_user_assertion
215
+ # We don't add PAI for re-REGISTER, so 401 will be replied, and after it let's
216
+ # revoke the current user assertion (will be re-added upon REGISTER with credentials).
217
+ ::OverSIP::Modules::UserAssertion.revoke_assertion response
218
+ end
219
+ end
220
+
221
+ proxy.route request
222
+ return
223
+
224
+ else
225
+
226
+ log_info "method #{request.sip_method} not implemented => 501"
227
+ request.reply 501, "Not Implemented"
228
+ return
229
+
230
+ end
231
+
232
+ end
233
+
234
+
235
+ # This method is called when a client initiates a SIP TLS handshake.
236
+ def (OverSIP::SipEvents).on_client_tls_handshake connection, pems
237
+
238
+ log_info "validating TLS connection from IP #{connection.remote_ip} and port #{connection.remote_port}"
239
+
240
+ cert, validated, tls_error, tls_error_string = ::OverSIP::TLS.validate pems
241
+ identities = ::OverSIP::TLS.get_sip_identities cert
242
+
243
+ if validated
244
+ log_info "client provides a valid TLS certificate with SIP identities #{identities}"
245
+ else
246
+ log_notice "client provides an invalid TLS certificate with SIP identities #{identities} (TLS error: #{tls_error.inspect}, description: #{tls_error_string.inspect})"
247
+ #connection.close
248
+ end
249
+
250
+ end
251
+
252
+
253
+ # This method is called when conntacting a SIP TLS server and the TLS handshake takes place.
254
+ def (OverSIP::SipEvents).on_server_tls_handshake connection, pems
255
+
256
+ log_info "validating TLS connection to IP #{connection.remote_ip} and port #{connection.remote_port}"
257
+
258
+ cert, validated, tls_error, tls_error_string = ::OverSIP::TLS.validate pems
259
+ identities = ::OverSIP::TLS.get_sip_identities cert
260
+
261
+ if validated
262
+ log_info "server provides a valid TLS certificate with SIP identities #{identities}"
263
+ else
264
+ log_notice "server provides an invalid TLS certificate with SIP identities #{identities} (TLS error: #{tls_error.inspect}, description: #{tls_error_string.inspect})"
265
+ #connection.close
266
+ end
267
+
268
+ end
269
+
270
+
271
+
272
+
273
+ ### OverSIP WebSocket Events:
274
+
275
+
276
+ # This method is called when a new WebSocket connection is being requested.
277
+ # Here you can inspect the connection and the HTTP GET request. If you
278
+ # decide not to accept this connection then call to:
279
+ #
280
+ # connection.http_reject(status_code, reason_phrase=nil, extra_headers=nil)
281
+ #
282
+ # You can also set variables for this connection via the connection.cvars
283
+ # Hash. Later you can access to this Hash in SIP requests from this connection
284
+ # by retrieving request.cvars attribute.
285
+ #
286
+ # def (OverSIP::WebSocketEvents).on_connection connection, http_request
287
+ # [...]
288
+ # end
289
+
290
+
291
+ # This method is called when a WebSocket connection is closed. The connection
292
+ # is given as first argument along with a second argument "client_closed" which
293
+ # is _true_ in case the WebSocket connection was closed by the client.
294
+ #
295
+ # def (OverSIP::WebSocketEvents).on_disconnection connection, client_closed
296
+ # [...]
297
+ # end
298
+
299
+
300
+ # This method is called when a client initiates a WebSocket TLS handshake.
301
+ def (OverSIP::WebSocketEvents).on_client_tls_handshake connection, pems
302
+
303
+ log_info "validating TLS connection from IP #{connection.remote_ip} and port #{connection.remote_port}"
304
+
305
+ cert, validated, tls_error, tls_error_string = ::OverSIP::TLS.validate pems
306
+ identities = ::OverSIP::TLS.get_sip_identities cert
307
+
308
+ if validated
309
+ log_info "client provides a valid TLS certificate with SIP identities #{identities}"
310
+ else
311
+ log_notice "client provides an invalid TLS certificate with SIP identities #{identities} (TLS error: #{tls_error.inspect}, description: #{tls_error_string.inspect})"
312
+ #connection.close
313
+ end
314
+
315
+ end