oversip 1.2.1 → 1.3.0.dev1
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 +28 -4
- data/bin/oversip +1 -1
- data/etc/proxies.conf +10 -0
- data/etc/server.rb +13 -9
- data/ext/utils/haproxy_protocol.c +0 -3
- data/ext/utils/outbound_utils.c +1 -1
- data/ext/utils/utils_ruby.c +0 -1
- data/ext/websocket_http_parser/ws_http_parser.c +940 -1903
- data/ext/websocket_http_parser/ws_http_parser.h +1 -0
- data/lib/oversip/config_validators.rb +2 -2
- data/lib/oversip/launcher.rb +275 -240
- data/lib/oversip/master_process.rb +7 -2
- data/lib/oversip/proxies_config.rb +8 -1
- data/lib/oversip/sip/client.rb +304 -0
- data/lib/oversip/sip/client_transaction.rb +31 -36
- data/lib/oversip/sip/core.rb +7 -4
- data/lib/oversip/sip/launcher.rb +30 -30
- data/lib/oversip/sip/listeners/connection.rb +4 -0
- data/lib/oversip/sip/listeners/ipv4_tcp_server.rb +1 -0
- data/lib/oversip/sip/listeners/ipv4_tls_server.rb +1 -0
- data/lib/oversip/sip/listeners/ipv4_tls_tunnel_server.rb +1 -0
- data/lib/oversip/sip/listeners/ipv4_udp_server.rb +1 -0
- data/lib/oversip/sip/listeners/ipv6_tcp_server.rb +1 -0
- data/lib/oversip/sip/listeners/ipv6_tls_server.rb +1 -0
- data/lib/oversip/sip/listeners/ipv6_tls_tunnel_server.rb +1 -0
- data/lib/oversip/sip/listeners/ipv6_udp_server.rb +1 -0
- data/lib/oversip/sip/listeners/tcp_client.rb +26 -0
- data/lib/oversip/sip/listeners/tcp_connection.rb +7 -1
- data/lib/oversip/sip/listeners/tcp_server.rb +1 -1
- data/lib/oversip/sip/listeners/tls_client.rb +28 -24
- data/lib/oversip/sip/listeners/tls_server.rb +25 -8
- data/lib/oversip/sip/listeners/tls_tunnel_connection.rb +1 -24
- data/lib/oversip/sip/message.rb +2 -2
- data/lib/oversip/sip/message_processor.rb +23 -13
- data/lib/oversip/sip/{grammar/name_addr.rb → name_addr.rb} +11 -0
- data/lib/oversip/sip/proxy.rb +53 -227
- data/lib/oversip/sip/request.rb +15 -11
- data/lib/oversip/sip/response.rb +3 -3
- data/lib/oversip/sip/rfc3263.rb +2 -3
- data/lib/oversip/sip/tags.rb +1 -1
- data/lib/oversip/sip/transport_manager.rb +6 -5
- data/lib/oversip/sip/uac.rb +93 -0
- data/lib/oversip/sip/uac_request.rb +82 -0
- data/lib/oversip/sip/{grammar/uri.rb → uri.rb} +22 -0
- data/lib/oversip/version.rb +3 -3
- data/lib/oversip/websocket/launcher.rb +25 -25
- data/lib/oversip/websocket/listeners/connection.rb +4 -0
- data/lib/oversip/websocket/listeners/ipv4_ws_server.rb +1 -0
- data/lib/oversip/websocket/listeners/ipv4_wss_server.rb +1 -0
- data/lib/oversip/websocket/listeners/ipv4_wss_tunnel_server.rb +1 -0
- data/lib/oversip/websocket/listeners/ipv6_ws_server.rb +1 -0
- data/lib/oversip/websocket/listeners/ipv6_wss_server.rb +1 -0
- data/lib/oversip/websocket/listeners/ipv6_wss_tunnel_server.rb +1 -0
- data/lib/oversip/websocket/listeners/ws_server.rb +55 -26
- data/lib/oversip/websocket/listeners/wss_server.rb +26 -9
- data/lib/oversip/websocket/listeners/wss_tunnel_server.rb +14 -11
- data/lib/oversip/websocket/ws_framing.rb +6 -2
- data/lib/oversip.rb +3 -1
- data/test/test_http_parser.rb +3 -3
- data/test/test_uri.rb +18 -12
- metadata +91 -77
@@ -18,6 +18,8 @@ gem "escape_utils", ">= 0.2.4"
|
|
18
18
|
require "escape_utils"
|
19
19
|
gem "posix-spawn", ">= 0.3.6"
|
20
20
|
require "posix-spawn"
|
21
|
+
gem "em-synchrony", ">=1.0.2"
|
22
|
+
require "em-synchrony"
|
21
23
|
|
22
24
|
|
23
25
|
# OverSIP files.
|
@@ -29,8 +31,8 @@ require "oversip/sip/core.rb"
|
|
29
31
|
require "oversip/sip/message.rb"
|
30
32
|
require "oversip/sip/request.rb"
|
31
33
|
require "oversip/sip/response.rb"
|
32
|
-
require "oversip/sip/
|
33
|
-
require "oversip/sip/
|
34
|
+
require "oversip/sip/uri.rb"
|
35
|
+
require "oversip/sip/name_addr.rb"
|
34
36
|
require "oversip/sip/message_processor.rb"
|
35
37
|
require "oversip/sip/listeners.rb"
|
36
38
|
require "oversip/sip/launcher.rb"
|
@@ -40,7 +42,10 @@ require "oversip/sip/transport_manager.rb"
|
|
40
42
|
require "oversip/sip/timers.rb"
|
41
43
|
require "oversip/sip/tags.rb"
|
42
44
|
require "oversip/sip/rfc3263.rb"
|
45
|
+
require "oversip/sip/client.rb"
|
43
46
|
require "oversip/sip/proxy.rb"
|
47
|
+
require "oversip/sip/uac.rb"
|
48
|
+
require "oversip/sip/uac_request.rb"
|
44
49
|
|
45
50
|
require "oversip/websocket/websocket.rb"
|
46
51
|
require "oversip/websocket/ws_http_parser.so"
|
@@ -14,6 +14,8 @@ module OverSIP
|
|
14
14
|
:use_dns => true,
|
15
15
|
:use_dns_cache => true,
|
16
16
|
:dns_cache_time => 300,
|
17
|
+
:use_blacklist => true,
|
18
|
+
:blacklist_time => 10,
|
17
19
|
:use_naptr => true,
|
18
20
|
:use_srv => true,
|
19
21
|
:transport_preference => ["tls", "tcp", "udp"],
|
@@ -31,6 +33,8 @@ module OverSIP
|
|
31
33
|
:use_dns => :boolean,
|
32
34
|
:use_dns_cache => :boolean,
|
33
35
|
:dns_cache_time => [ :fixnum, [ :greater_equal_than, 300 ] ],
|
36
|
+
:use_blacklist => :boolean,
|
37
|
+
:blacklist_time => [ :fixnum, [ :greater_equal_than, 2 ], [ :minor_equal_than, 600 ] ],
|
34
38
|
:use_naptr => :boolean,
|
35
39
|
:use_srv => :boolean,
|
36
40
|
:transport_preference => [ [ :choices, %w{tls tcp udp}], :multi_value, :non_empty ],
|
@@ -163,7 +167,10 @@ module OverSIP
|
|
163
167
|
@proxies[proxy][:has_sip_tls] = @proxies[proxy][:transport_preference].include?(:tls)
|
164
168
|
|
165
169
|
# Add a hash for the DNS cache.
|
166
|
-
@proxies[proxy][:dns_cache] = {}
|
170
|
+
@proxies[proxy][:dns_cache] = {}
|
171
|
+
|
172
|
+
# Add a hash for the blacklist.
|
173
|
+
@proxies[proxy][:blacklist] = {}
|
167
174
|
end
|
168
175
|
end
|
169
176
|
|
@@ -0,0 +1,304 @@
|
|
1
|
+
module OverSIP::SIP
|
2
|
+
|
3
|
+
class Client
|
4
|
+
|
5
|
+
include ::OverSIP::Logger
|
6
|
+
|
7
|
+
attr_reader :current_target
|
8
|
+
|
9
|
+
def initialize proxy_profile=:default_proxy
|
10
|
+
unless (@conf = ::OverSIP.proxies[proxy_profile.to_sym])
|
11
|
+
raise ::OverSIP::RuntimeError, "proxy profile '#{proxy_profile}' is not defined"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def on_provisional_response &block
|
16
|
+
@on_provisional_response_block = block
|
17
|
+
end
|
18
|
+
|
19
|
+
def on_success_response &block
|
20
|
+
@on_success_response_block = block
|
21
|
+
end
|
22
|
+
|
23
|
+
def on_failure_response &block
|
24
|
+
@on_failure_response_block = block
|
25
|
+
end
|
26
|
+
|
27
|
+
def on_canceled &block
|
28
|
+
@on_canceled_block = block
|
29
|
+
end
|
30
|
+
|
31
|
+
def on_invite_timeout &block
|
32
|
+
@on_invite_timeout_block = block
|
33
|
+
end
|
34
|
+
|
35
|
+
def on_error &block
|
36
|
+
@on_error_block = block
|
37
|
+
end
|
38
|
+
|
39
|
+
def on_target &block
|
40
|
+
@on_target_block = block
|
41
|
+
end
|
42
|
+
|
43
|
+
# By calling this method the request routing is aborted, no more DNS targets are tryed,
|
44
|
+
# a local 403 response is generated and on_error() callback is called with status 403.
|
45
|
+
def abort_routing
|
46
|
+
@aborted = true
|
47
|
+
end
|
48
|
+
|
49
|
+
# Manually insert the last target into the blacklist. Optionally a timeout value can be given
|
50
|
+
# (otherwise the proxy blacklist_time is used). The timeout must be between 2 and 600 seconds.
|
51
|
+
# Also the SIP code and reason can be passed.
|
52
|
+
def add_target_to_blacklist timeout=nil, status_code=403, reason_phrase="Destination Blacklisted"
|
53
|
+
return false unless @current_target
|
54
|
+
|
55
|
+
if timeout
|
56
|
+
timeout = timeout.to_i
|
57
|
+
if timeout < 2 or timeout > 600
|
58
|
+
raise ::OverSIP::RuntimeError, "timeout must be between a and 600 seconds"
|
59
|
+
end
|
60
|
+
else
|
61
|
+
timeout = @conf[:blacklist_time]
|
62
|
+
end
|
63
|
+
|
64
|
+
blacklist_entry = @current_target.to_s
|
65
|
+
@conf[:blacklist][blacklist_entry] = [status_code, reason_phrase, nil, :destination_blacklisted]
|
66
|
+
::EM.add_timer(timeout) { @conf[:blacklist].delete blacklist_entry }
|
67
|
+
end
|
68
|
+
|
69
|
+
|
70
|
+
### Methods called by the client transaction.
|
71
|
+
|
72
|
+
def client_timeout
|
73
|
+
# Store the target and error in the blacklist.
|
74
|
+
if @conf[:use_blacklist]
|
75
|
+
blacklist_entry = @current_target.to_s
|
76
|
+
@conf[:blacklist][blacklist_entry] = [408, "Client Timeout", nil, :client_timeout]
|
77
|
+
::EM.add_timer(@conf[:blacklist_time]) { @conf[:blacklist].delete blacklist_entry }
|
78
|
+
end
|
79
|
+
|
80
|
+
try_next_target 408, "Client Timeout", nil, :client_timeout
|
81
|
+
end
|
82
|
+
|
83
|
+
def connection_failed
|
84
|
+
# Store the target and error in the blacklist.
|
85
|
+
if @conf[:use_blacklist]
|
86
|
+
blacklist_entry = @current_target.to_s
|
87
|
+
@conf[:blacklist][blacklist_entry] = [500, "Connection Error", nil, :connection_error]
|
88
|
+
::EM.add_timer(@conf[:blacklist_time]) { @conf[:blacklist].delete blacklist_entry }
|
89
|
+
end
|
90
|
+
|
91
|
+
try_next_target 500, "Connection Error", nil, :connection_error
|
92
|
+
end
|
93
|
+
|
94
|
+
def tls_validation_failed
|
95
|
+
# Store the target and error in the blacklist.
|
96
|
+
if @conf[:use_blacklist]
|
97
|
+
blacklist_entry = @current_target.to_s
|
98
|
+
@conf[:blacklist][blacklist_entry] = [500, "TLS Validation Failed", nil, :tls_validation_failed]
|
99
|
+
::EM.add_timer(@conf[:blacklist_time]) { @conf[:blacklist].delete blacklist_entry }
|
100
|
+
end
|
101
|
+
|
102
|
+
try_next_target 500, "TLS Validation Failed", nil, :tls_validation_failed
|
103
|
+
end
|
104
|
+
|
105
|
+
# Timer C for INVITE.
|
106
|
+
def invite_timeout
|
107
|
+
@on_invite_timeout_block && @on_invite_timeout_block.call
|
108
|
+
end
|
109
|
+
|
110
|
+
|
111
|
+
|
112
|
+
private
|
113
|
+
|
114
|
+
|
115
|
+
def add_routing_headers
|
116
|
+
end
|
117
|
+
|
118
|
+
|
119
|
+
# Check the given URI into the DNS cache.
|
120
|
+
# - If the cache is not enabled it returns nil.
|
121
|
+
# - If present it returns true.
|
122
|
+
# - If not it returns dns_cache_key (String).
|
123
|
+
def check_dns_cache dst_scheme, dst_host, dst_host_type, dst_port, dst_transport
|
124
|
+
if dst_host_type == :domain and @conf[:use_dns_cache]
|
125
|
+
dns_cache_key = "#{dst_scheme}|#{dst_host}|#{dst_port}|#{dst_transport}"
|
126
|
+
if (result = @conf[:dns_cache][dns_cache_key])
|
127
|
+
log_system_debug "destination found in the DNS cache" if $oversip_debug
|
128
|
+
if result.is_a? ::Symbol
|
129
|
+
rfc3263_failed result
|
130
|
+
else
|
131
|
+
rfc3263_succeeded result
|
132
|
+
end
|
133
|
+
return true
|
134
|
+
else
|
135
|
+
return dns_cache_key
|
136
|
+
end
|
137
|
+
else
|
138
|
+
return nil
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
|
143
|
+
def do_dns dns_cache_key, id, dst_scheme, dst_host, dst_host_type, dst_port, dst_transport
|
144
|
+
# Perform RFC 3261 procedures.
|
145
|
+
dns_query = ::OverSIP::SIP::RFC3263::Query.new @conf, id, dst_scheme, dst_host, dst_host_type, dst_port, dst_transport
|
146
|
+
case result = dns_query.resolve
|
147
|
+
|
148
|
+
# Async result so DNS took place.
|
149
|
+
when nil
|
150
|
+
# Async success.
|
151
|
+
dns_query.callback do |result|
|
152
|
+
# Store the result in the DNS cache.
|
153
|
+
if dns_cache_key
|
154
|
+
@conf[:dns_cache][dns_cache_key] = result
|
155
|
+
::EM.add_timer(@conf[:dns_cache_time]) { @conf[:dns_cache].delete dns_cache_key }
|
156
|
+
end
|
157
|
+
rfc3263_succeeded result
|
158
|
+
end
|
159
|
+
# Async error.
|
160
|
+
dns_query.errback do |result|
|
161
|
+
# Store the result in the DNS cache.
|
162
|
+
if dns_cache_key
|
163
|
+
@conf[:dns_cache][dns_cache_key] = result
|
164
|
+
::EM.add_timer(@conf[:dns_cache_time]) { @conf[:dns_cache].delete dns_cache_key }
|
165
|
+
end
|
166
|
+
rfc3263_failed result
|
167
|
+
end
|
168
|
+
# Instant error.
|
169
|
+
when ::Symbol
|
170
|
+
# Store the result in the DNS cache.
|
171
|
+
if dns_cache_key
|
172
|
+
@conf[:dns_cache][dns_cache_key] = result
|
173
|
+
::EM.add_timer(@conf[:dns_cache_time]) { @conf[:dns_cache].delete dns_cache_key }
|
174
|
+
end
|
175
|
+
rfc3263_failed result
|
176
|
+
# Instant success so it's not a domain (no DNS performed).
|
177
|
+
else
|
178
|
+
rfc3263_succeeded result
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
|
183
|
+
def rfc3263_succeeded result
|
184
|
+
# After RFC 3263 (DNS) resolution we get N targets.
|
185
|
+
@num_target = 0 # First target is 0 (rather than 1).
|
186
|
+
@target = @targets = nil # Avoid conflicts if same Proxy is used for serial forking to a new destination.
|
187
|
+
|
188
|
+
case result
|
189
|
+
|
190
|
+
when RFC3263::Target
|
191
|
+
@target = result # Single Target.
|
192
|
+
|
193
|
+
when RFC3263::SrvTargets
|
194
|
+
log_system_debug "DNS result has multiple values, randomizing" if $oversip_debug
|
195
|
+
@targets = result.randomize # Array of Targets.
|
196
|
+
|
197
|
+
# This can contain Target and SrvTargets entries.
|
198
|
+
when RFC3263::MultiTargets
|
199
|
+
log_system_debug "DNS result has multiple values, randomizing" if $oversip_debug
|
200
|
+
@targets = result.flatten # Array of Targets.
|
201
|
+
|
202
|
+
end
|
203
|
+
|
204
|
+
try_next_target
|
205
|
+
end # rfc3263_succeeded
|
206
|
+
|
207
|
+
|
208
|
+
def try_next_target status=nil, reason=nil, full_response=nil, code=nil
|
209
|
+
# Single target.
|
210
|
+
if @target and @num_target == 0
|
211
|
+
@current_target = @target
|
212
|
+
log_system_debug "trying single target: #{@current_target}" if $oversip_debug
|
213
|
+
@num_target = 1
|
214
|
+
use_target @current_target
|
215
|
+
|
216
|
+
# Multiple targets (so @targets is set).
|
217
|
+
elsif @targets and @num_target < @targets.size
|
218
|
+
@current_target = @targets[@num_target]
|
219
|
+
log_system_debug "trying target #{@num_target+1} of #{@targets.size}: #{@current_target}" if $oversip_debug
|
220
|
+
@num_target += 1
|
221
|
+
use_target @current_target
|
222
|
+
|
223
|
+
# No more targets.
|
224
|
+
else
|
225
|
+
no_more_targets status, reason, full_response, code
|
226
|
+
end
|
227
|
+
end # try_next_target
|
228
|
+
|
229
|
+
|
230
|
+
def use_target target
|
231
|
+
# Lookup the target in the blacklist.
|
232
|
+
if @conf[:blacklist].any? and (blacklist_entry = @conf[:blacklist][target.to_s])
|
233
|
+
log_system_notice "destination found in the blacklist" if $oversip_debug
|
234
|
+
try_next_target blacklist_entry[0], blacklist_entry[1], blacklist_entry[2], blacklist_entry[3]
|
235
|
+
return
|
236
|
+
end
|
237
|
+
|
238
|
+
# Call the on_target() callback if set by the user.
|
239
|
+
@on_target_block && @on_target_block.call(target)
|
240
|
+
|
241
|
+
# If the user has called to proxy.abort_routing() then stop next targets
|
242
|
+
# and call to on_error() callback.
|
243
|
+
if @aborted
|
244
|
+
log_system_notice "routing aborted for target #{target}"
|
245
|
+
@aborted = @target = @targets = nil
|
246
|
+
try_next_target 403, "Destination Aborted", nil, :destination_aborted
|
247
|
+
return
|
248
|
+
end
|
249
|
+
|
250
|
+
@client_transaction = (::OverSIP::SIP::ClientTransaction.get_class @request).new self, @request, @conf, target.transport, target.ip, target.ip_type, target.port
|
251
|
+
add_routing_headers
|
252
|
+
@client_transaction.send_request
|
253
|
+
end
|
254
|
+
|
255
|
+
|
256
|
+
def no_more_targets status, reason, full_response, code
|
257
|
+
end
|
258
|
+
|
259
|
+
|
260
|
+
def rfc3263_failed error
|
261
|
+
case error
|
262
|
+
when :rfc3263_domain_not_found
|
263
|
+
log_system_debug "no resolution" if $oversip_debug
|
264
|
+
status = 404
|
265
|
+
reason = "No DNS Resolution"
|
266
|
+
code = :no_dns_resolution
|
267
|
+
when :rfc3263_unsupported_scheme
|
268
|
+
log_system_debug "unsupported URI scheme" if $oversip_debug
|
269
|
+
status = 416
|
270
|
+
reason = "Unsupported URI scheme"
|
271
|
+
code = :unsupported_uri_scheme
|
272
|
+
when :rfc3263_unsupported_transport
|
273
|
+
log_system_debug "unsupported transport" if $oversip_debug
|
274
|
+
status = 478
|
275
|
+
reason = "Unsupported Transport"
|
276
|
+
code = :unsupported_transport
|
277
|
+
when :rfc3263_no_ipv4
|
278
|
+
log_system_debug "destination requires unsupported IPv4" if $oversip_debug
|
279
|
+
status = 478
|
280
|
+
reason = "Destination Requires Unsupported IPv4"
|
281
|
+
code = :no_ipv4
|
282
|
+
when :rfc3263_no_ipv6
|
283
|
+
log_system_debug "destination requires unsupported IPv6" if $oversip_debug
|
284
|
+
status = 478
|
285
|
+
reason = "Destination Requires Unsupported IPv6"
|
286
|
+
code = :no_ipv6
|
287
|
+
when :rfc3263_no_dns
|
288
|
+
log_system_debug "destination requires unsupported DNS query" if $oversip_debug
|
289
|
+
status = 478
|
290
|
+
reason = "Destination Requires Unsupported DNS Query"
|
291
|
+
code = :no_dns
|
292
|
+
end
|
293
|
+
|
294
|
+
do_dns_fail status, reason, code
|
295
|
+
end # def rfc3263_failed
|
296
|
+
|
297
|
+
|
298
|
+
def do_dns_fail status, reason, code
|
299
|
+
@on_error_block && @on_error_block.call(status, reason, code)
|
300
|
+
end
|
301
|
+
|
302
|
+
end # class Client
|
303
|
+
|
304
|
+
end
|
@@ -22,7 +22,7 @@ module OverSIP::SIP
|
|
22
22
|
@transaction_id = ::SecureRandom.hex(4) << @request.antiloop_id
|
23
23
|
|
24
24
|
# A client transaction for using an existing Outbound connection.
|
25
|
-
if transport.is_a? String
|
25
|
+
if transport.is_a? ::String
|
26
26
|
@connection, @ip, @port = ::OverSIP::SIP::TransportManager.get_outbound_connection transport
|
27
27
|
if @connection
|
28
28
|
@server_klass = @connection.class
|
@@ -59,10 +59,13 @@ module OverSIP::SIP
|
|
59
59
|
end
|
60
60
|
|
61
61
|
# Ensure the request has Content-Length. Add it otherwise.
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
62
|
+
# NOTE: Don't do this for UAcRequest instances!
|
63
|
+
if @request.is_a? ::OverSIP::SIP::Request
|
64
|
+
if @request.body
|
65
|
+
@request.headers["Content-Length"] = [ @request.body.bytesize.to_s ]
|
66
|
+
else
|
67
|
+
@request.headers["Content-Length"] = HDR_ARRAY_CONTENT_LENGTH_0
|
68
|
+
end
|
66
69
|
end
|
67
70
|
|
68
71
|
end # def initialize
|
@@ -107,24 +110,20 @@ module OverSIP::SIP
|
|
107
110
|
when :both_outbound_rr
|
108
111
|
@out_rr = :rr
|
109
112
|
@request.insert_header "Record-Route", "<sip:" << @request.route_outbound_flow_token << @server_klass.outbound_record_route_fragment
|
110
|
-
end
|
111
|
-
|
112
|
-
@request_leg_b = @request.to_s
|
113
|
+
end if @request.in_rr
|
113
114
|
|
114
|
-
|
115
|
-
# and when a connection is terminated its value is automatically deleted from such hash.
|
116
|
-
@connection.send_sip_msg @request_leg_b, @ip, @port
|
115
|
+
@outgoing_request_str = @request.to_s
|
117
116
|
|
118
117
|
@request.delete_header_top "Via"
|
119
118
|
if @out_rr == :rr
|
120
119
|
@request.delete_header_top "Record-Route"
|
121
120
|
end
|
122
121
|
|
122
|
+
@connection.send_sip_msg @outgoing_request_str, @ip, @port
|
123
|
+
|
123
124
|
start_timer_A if @transport == :udp
|
124
125
|
start_timer_B
|
125
126
|
start_timer_C
|
126
|
-
|
127
|
-
true
|
128
127
|
end
|
129
128
|
|
130
129
|
def start_timer_A
|
@@ -177,7 +176,7 @@ module OverSIP::SIP
|
|
177
176
|
end
|
178
177
|
|
179
178
|
def retransmit_request
|
180
|
-
@connection.send_sip_msg @
|
179
|
+
@connection.send_sip_msg @outgoing_request_str, @ip, @port
|
181
180
|
end
|
182
181
|
|
183
182
|
def receive_response response
|
@@ -284,21 +283,21 @@ module OverSIP::SIP
|
|
284
283
|
@ack << "Via: #{@top_via}\r\n"
|
285
284
|
|
286
285
|
@request.hdr_route.each do |route|
|
287
|
-
@ack << "Route: " << route <<
|
286
|
+
@ack << "Route: " << route << CRLF
|
288
287
|
end if @request.hdr_route
|
289
288
|
|
290
|
-
@ack << "From: " << @request.hdr_from <<
|
289
|
+
@ack << "From: " << @request.hdr_from << CRLF
|
291
290
|
@ack << "To: " << @request.hdr_to
|
292
291
|
unless @request.to_tag
|
293
292
|
@ack << ";tag=#{response.to_tag}" if response.to_tag
|
294
293
|
end
|
295
|
-
@ack <<
|
294
|
+
@ack << CRLF
|
296
295
|
|
297
|
-
@ack << "Call-ID: " << @request.call_id <<
|
296
|
+
@ack << "Call-ID: " << @request.call_id << CRLF
|
298
297
|
@ack << "CSeq: " << @request.cseq.to_s << " ACK\r\n"
|
299
298
|
@ack << "Content-Length: 0\r\n"
|
300
|
-
@ack << HDR_USER_AGENT <<
|
301
|
-
@ack <<
|
299
|
+
@ack << HDR_USER_AGENT << CRLF
|
300
|
+
@ack << CRLF
|
302
301
|
end
|
303
302
|
|
304
303
|
log_system_debug "sending ACK for [3456]XX response" if $oversip_debug
|
@@ -315,21 +314,21 @@ module OverSIP::SIP
|
|
315
314
|
@cancel << "Via: #{@top_via}\r\n"
|
316
315
|
|
317
316
|
@request.hdr_route.each do |route|
|
318
|
-
@cancel << "Route: " << route <<
|
317
|
+
@cancel << "Route: " << route << CRLF
|
319
318
|
end if @request.hdr_route
|
320
319
|
|
321
320
|
# RFC 3326. Copy Reason headers if present in the received CANCEL.
|
322
321
|
cancel.header_all("Reason").each do |reason|
|
323
|
-
@cancel << "Reason: " << reason <<
|
322
|
+
@cancel << "Reason: " << reason << CRLF
|
324
323
|
end if cancel
|
325
324
|
|
326
|
-
@cancel << "From: " << @request.hdr_from <<
|
327
|
-
@cancel << "To: " << @request.hdr_to <<
|
328
|
-
@cancel << "Call-ID: " << @request.call_id <<
|
325
|
+
@cancel << "From: " << @request.hdr_from << CRLF
|
326
|
+
@cancel << "To: " << @request.hdr_to << CRLF
|
327
|
+
@cancel << "Call-ID: " << @request.call_id << CRLF
|
329
328
|
@cancel << "CSeq: " << @request.cseq.to_s << " CANCEL\r\n"
|
330
329
|
@cancel << "Content-Length: 0\r\n"
|
331
|
-
@cancel << HDR_USER_AGENT <<
|
332
|
-
@cancel <<
|
330
|
+
@cancel << HDR_USER_AGENT << CRLF
|
331
|
+
@cancel << CRLF
|
333
332
|
|
334
333
|
# Just send the ACK inmediately if the branch has replied a 1XX response.
|
335
334
|
send_cancel if @state == :proceeding
|
@@ -437,11 +436,9 @@ module OverSIP::SIP
|
|
437
436
|
when :both_outbound_path
|
438
437
|
@out_rr = :rr
|
439
438
|
@request.insert_header "Path", "<sip:" << @request.route_outbound_flow_token << @server_klass.outbound_path_fragment
|
440
|
-
end
|
441
|
-
|
442
|
-
@request_leg_b = @request.to_s
|
439
|
+
end if @core.is_a? ::OverSIP::SIP::Proxy
|
443
440
|
|
444
|
-
@
|
441
|
+
@outgoing_request_str = @request.to_s
|
445
442
|
|
446
443
|
@request.delete_header_top "Via"
|
447
444
|
case @out_rr
|
@@ -451,10 +448,10 @@ module OverSIP::SIP
|
|
451
448
|
@request.delete_header_top "Path"
|
452
449
|
end
|
453
450
|
|
451
|
+
@connection.send_sip_msg @outgoing_request_str, @ip, @port
|
452
|
+
|
454
453
|
start_timer_E if @transport == :udp
|
455
454
|
start_timer_F
|
456
|
-
|
457
|
-
true
|
458
455
|
end
|
459
456
|
|
460
457
|
def start_timer_E
|
@@ -493,7 +490,7 @@ module OverSIP::SIP
|
|
493
490
|
end
|
494
491
|
|
495
492
|
def retransmit_request
|
496
|
-
@connection.send_sip_msg @
|
493
|
+
@connection.send_sip_msg @outgoing_request_str, @ip, @port
|
497
494
|
end
|
498
495
|
|
499
496
|
def receive_response response
|
@@ -570,8 +567,6 @@ module OverSIP::SIP
|
|
570
567
|
@request.insert_header "Via", "#{@server_klass.via_core};branch=z9hG4bK#{@transaction_id}"
|
571
568
|
|
572
569
|
@connection.send_sip_msg @request.to_s, @ip, @port
|
573
|
-
|
574
|
-
true
|
575
570
|
end
|
576
571
|
|
577
572
|
def connection_failed
|
data/lib/oversip/sip/core.rb
CHANGED
@@ -63,13 +63,16 @@ module OverSIP::SIP
|
|
63
63
|
|
64
64
|
# Outgoing initial request asking for Outbound. Just valid when:
|
65
65
|
# - It's an initial request.
|
66
|
+
# - The request comes via UDP or comes via TCP/TLS/WS/WSS but through a connection
|
67
|
+
# opened by the peer (and not by OverSIP).
|
66
68
|
# - Single Via (so there is no a proxy in front of us).
|
67
69
|
# - It's an INVITE, REGISTER, SUBSCRIBE or REFER request.
|
68
70
|
# - Has a preloaded top Route with ;ob param pointing to us, or has Contact with ;ob, or
|
69
|
-
# it's a REGISTER with ;+sip.instance
|
71
|
+
# it's a REGISTER with ;+sip.instance..
|
70
72
|
#
|
71
73
|
if (
|
72
|
-
initial? and
|
74
|
+
initial? and
|
75
|
+
@connection.class.outbound_listener? and (
|
73
76
|
@force_outgoing_outbound or (
|
74
77
|
@num_vias == 1 and
|
75
78
|
outbound_aware? and (
|
@@ -164,8 +167,8 @@ module OverSIP::SIP
|
|
164
167
|
def connection_outbound_flow_token
|
165
168
|
@connection_outbound_flow_token ||= if @transport == :udp
|
166
169
|
# NOTE: Add "_" so later we can figure that this is for UDP.
|
167
|
-
# NOTE: Replace "=" with "-" so it can be added as a SIP URI param (
|
168
|
-
#
|
170
|
+
# NOTE: Replace "=" with "-" so it can be added as a SIP URI param (needed i.e.
|
171
|
+
# for the OutboundMangling module).
|
169
172
|
"_" << ::Base64.strict_encode64("#{@source_ip}_#{@source_port}").gsub(/=/,"-")
|
170
173
|
else
|
171
174
|
@connection.outbound_flow_token
|