oversip 1.1.2 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/oversip.rb CHANGED
@@ -13,6 +13,10 @@ require "tempfile"
13
13
  require "term/ansicolor"
14
14
  require "posix_mq"
15
15
  require "syslog"
16
+ # Load EventMachine-LE here to avoid som EM based gem in server.rb to be loaded first
17
+ # (and load eventmachine instead of eventmachine-le).
18
+ gem "eventmachine-le", ">= 1.1.3"
19
+ require "eventmachine-le"
16
20
 
17
21
 
18
22
  # OverSIP files.
@@ -29,6 +33,7 @@ require "oversip/utils.so"
29
33
  require "oversip/utils.rb"
30
34
  require "oversip/posix_mq.rb"
31
35
  require "oversip/default_server.rb"
36
+ require "oversip/system_callbacks.rb"
32
37
 
33
38
 
34
39
 
@@ -59,5 +64,9 @@ module OverSIP
59
64
  # Pre-declare internal modules.
60
65
  module SIP ; end
61
66
  module WebSocket ; end
67
+ module Modules ; end
68
+
69
+ # Allow OverSIP::M::MODULE_NAME usage.
70
+ M = Modules
62
71
 
63
72
  end
data/test/test_uri.rb CHANGED
@@ -6,23 +6,27 @@ require "oversip_test_helper"
6
6
  class TestUri < OverSIPTest
7
7
 
8
8
  def test_sip_uri
9
- full_uri = "sip:alice@atlanta.com:5060;transport=tcp;foo=123;baz?X-Header-1=qwe&X-Header-2=asd"
9
+ full_uri = "sips:i%C3%B1aki@aliax.net:5060;transport=tcp;foo=123;baz?X-Header-1=qwe&X-Header-2=asd"
10
+ aor = "sip:i%C3%B1aki@aliax.net"
10
11
 
11
12
  uri = ::OverSIP::SIP::Uri.new
12
- uri.instance_variable_set :@scheme, :sip
13
- uri.user = "alice"
14
- uri.host = "atlanta.com"
13
+ uri.instance_variable_set :@scheme, :sips
14
+ uri.user = "iñaki"
15
+ uri.host = "aliax.net"
15
16
  uri.host_type = :domain
16
17
  uri.port = 5060
17
18
  uri.transport_param = :tcp
18
19
  uri.instance_variable_set :@params, {"transport"=>"tcp", "foo"=>"123", "baz"=>nil}
19
20
  uri.headers = "?X-Header-1=qwe&X-Header-2=asd"
20
21
 
22
+ assert_equal "iñaki", uri.user
23
+ assert_equal aor, uri.aor
21
24
  assert_equal full_uri, uri.to_s
22
25
  end
23
26
 
24
27
  def test_tel_uri
25
28
  full_uri = "tel:944991212;foo=bar;phone-context=+34"
29
+ aor = "tel:944991212"
26
30
 
27
31
  uri = ::OverSIP::SIP::Uri.new
28
32
  uri.instance_variable_set :@scheme, :tel
@@ -30,15 +34,18 @@ class TestUri < OverSIPTest
30
34
  uri.instance_variable_set :@params, {"foo"=>"bar"}
31
35
  uri.phone_context_param = "+34"
32
36
 
37
+ assert_equal aor, uri.aor
33
38
  assert_equal full_uri, uri.to_s
34
39
  end
35
40
 
36
41
  def test_http_uri
37
42
  full_uri = "http://oversip.net/authors/"
43
+ aor = nil
38
44
 
39
45
  uri = ::OverSIP::SIP::Uri.new
40
46
  uri.instance_variable_set :@uri, full_uri
41
47
 
48
+ assert_nil uri.aor
42
49
  assert_equal full_uri, uri.to_s
43
50
  end
44
51
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oversip
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.2
4
+ version: 1.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-08-29 00:00:00.000000000 Z
12
+ date: 2012-09-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: eventmachine-le
16
- requirement: &19734060 !ruby/object:Gem::Requirement
16
+ requirement: &18819520 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 1.1.3
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *19734060
24
+ version_requirements: *18819520
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: iobuffer
27
- requirement: &19733500 !ruby/object:Gem::Requirement
27
+ requirement: &18819060 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 1.1.2
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *19733500
35
+ version_requirements: *18819060
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: em-posixmq
38
- requirement: &19732980 !ruby/object:Gem::Requirement
38
+ requirement: &18818600 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: 0.2.3
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *19732980
46
+ version_requirements: *18818600
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: em-udns
49
- requirement: &19732500 !ruby/object:Gem::Requirement
49
+ requirement: &18818140 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: 0.3.6
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *19732500
57
+ version_requirements: *18818140
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: escape_utils
60
- requirement: &19732040 !ruby/object:Gem::Requirement
60
+ requirement: &18587760 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: 0.2.4
66
66
  type: :runtime
67
67
  prerelease: false
68
- version_requirements: *19732040
68
+ version_requirements: *18587760
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: term-ansicolor
71
- requirement: &19731660 !ruby/object:Gem::Requirement
71
+ requirement: &18587300 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: '0'
77
77
  type: :runtime
78
78
  prerelease: false
79
- version_requirements: *19731660
79
+ version_requirements: *18587300
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: posix-spawn
82
- requirement: &19731120 !ruby/object:Gem::Requirement
82
+ requirement: &18586620 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ! '>='
@@ -87,10 +87,10 @@ dependencies:
87
87
  version: 0.3.6
88
88
  type: :runtime
89
89
  prerelease: false
90
- version_requirements: *19731120
90
+ version_requirements: *18586620
91
91
  - !ruby/object:Gem::Dependency
92
92
  name: rake
93
- requirement: &19730620 !ruby/object:Gem::Requirement
93
+ requirement: &18585920 !ruby/object:Gem::Requirement
94
94
  none: false
95
95
  requirements:
96
96
  - - ~>
@@ -98,7 +98,7 @@ dependencies:
98
98
  version: 0.9.2
99
99
  type: :development
100
100
  prerelease: false
101
- version_requirements: *19730620
101
+ version_requirements: *18585920
102
102
  description: ! 'OverSIP is an async SIP proxy/server programmable in Ruby language.
103
103
  Some features of OverSIP are:
104
104
 
@@ -148,6 +148,7 @@ files:
148
148
  - lib/oversip/logger.rb
149
149
  - lib/oversip/fiber_pool.rb
150
150
  - lib/oversip/syslogger_process.rb
151
+ - lib/oversip/system_callbacks.rb
151
152
  - lib/oversip/config.rb
152
153
  - lib/oversip/launcher.rb
153
154
  - lib/oversip/ruby_ext/eventmachine.rb
@@ -162,6 +163,7 @@ files:
162
163
  - lib/oversip/sip/message_processor.rb
163
164
  - lib/oversip/sip/response.rb
164
165
  - lib/oversip/sip/transport_manager.rb
166
+ - lib/oversip/sip/core.rb
165
167
  - lib/oversip/sip/client_transaction.rb
166
168
  - lib/oversip/sip/message.rb
167
169
  - lib/oversip/sip/constants.rb
@@ -189,9 +191,6 @@ files:
189
191
  - lib/oversip/sip/listeners/tls_tunnel_connection.rb
190
192
  - lib/oversip/sip/grammar/uri.rb
191
193
  - lib/oversip/sip/grammar/name_addr.rb
192
- - lib/oversip/sip/modules/registrar_without_path.rb
193
- - lib/oversip/sip/modules/core.rb
194
- - lib/oversip/sip/modules/user_assertion.rb
195
194
  - lib/oversip/websocket/listeners.rb
196
195
  - lib/oversip/websocket/http_request.rb
197
196
  - lib/oversip/websocket/ws_framing.rb
@@ -209,6 +208,8 @@ files:
209
208
  - lib/oversip/websocket/listeners/ipv4_ws_server.rb
210
209
  - lib/oversip/websocket/listeners/ipv6_wss_server.rb
211
210
  - lib/oversip/websocket/listeners/wss_tunnel_server.rb
211
+ - lib/oversip/modules/outbound_mangling.rb
212
+ - lib/oversip/modules/user_assertion.rb
212
213
  - ext/common/ruby_c_util.h
213
214
  - ext/common/c_util.h
214
215
  - ext/sip_parser/extconf.rb
@@ -268,7 +269,7 @@ require_paths:
268
269
  required_ruby_version: !ruby/object:Gem::Requirement
269
270
  none: false
270
271
  requirements:
271
- - - ~>
272
+ - - ! '>='
272
273
  - !ruby/object:Gem::Version
273
274
  version: 1.9.2
274
275
  required_rubygems_version: !ruby/object:Gem::Requirement
@@ -1,194 +0,0 @@
1
- module OverSIP::SIP
2
-
3
- module Modules
4
- module Core
5
-
6
- # Create a server transaction for the incoming request.
7
- def create_transaction
8
- return false if @server_transaction
9
-
10
- case @sip_method
11
- when :INVITE
12
- ::OverSIP::SIP::InviteServerTransaction.new self
13
- return true
14
- when :ACK
15
- return nil
16
- when :CANCEL
17
- return nil
18
- else
19
- ::OverSIP::SIP::NonInviteServerTransaction.new self
20
- return true
21
- end
22
- end
23
-
24
-
25
- def check_max_forwards max_forwards
26
- if @max_forwards
27
- unless @max_forwards.zero?
28
- @new_max_forwards = ( @max_forwards > max_forwards ? max_forwards : @max_forwards - 1 )
29
- return true
30
- else
31
- log_system_notice "Max-Forwards is 0 => 483"
32
- reply 483
33
- return false
34
- end
35
- else
36
- @new_max_forwards = max_forwards
37
- return true
38
- end
39
- end
40
-
41
-
42
- def loose_route
43
- num_removes = 0
44
- has_preloaded_route_with_ob_param = false
45
-
46
- # Remove all the Route's pointing to the proxy until a Route not pointing to us is found.
47
- if @routes
48
- @routes.each do |route|
49
- if ::OverSIP::SIP::Tags.check_value_for_route_ovid(route.ovid_param)
50
- num_removes += 1
51
- else
52
- if local_uri? route
53
- has_preloaded_route_with_ob_param = true if route.ob_param?
54
- num_removes += 1
55
- else
56
- break
57
- end
58
- end
59
- end
60
- end
61
-
62
- ### Outbound stuf. RFC 5626 section 5.3.
63
-
64
- # Outgoing initial request asking for Outbound. Just valid when:
65
- # - It's an initial request.
66
- # - Single Via (so there is no a proxy in front of us).
67
- # - It's an INVITE, REGISTER, SUBSCRIBE or REFER request.
68
- # - 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.
70
- #
71
- if (
72
- initial? and (
73
- @force_outgoing_outbound or (
74
- @num_vias == 1 and
75
- outbound_aware? and (
76
- ( has_preloaded_route_with_ob_param or (@contact and @contact.ob_param?) ) or
77
- ( @sip_method == :REGISTER and contact_reg_id?)
78
- )
79
- )
80
- )
81
- )
82
- @outgoing_outbound_requested = true
83
- log_system_debug "applying outgoing Outbound support" if $oversip_debug
84
- end
85
-
86
- # Incoming initial request or in-dialog incoming/outgoing request. Must only perform
87
- # Outbound for the incoming case and just when:
88
- # - There are 2 Route headers.
89
- # - All the Route headers point to us.
90
- # - The latest Route has a flow token and a valid ;ovid param (so has been generated
91
- # previously by us).
92
- # NOTE: But don't check its value so it still would work in case of server reboot.
93
- # - It's an incoming Outbound request (so flow token in the Route does not match the
94
- # flow token of the incoming connection).
95
- if (
96
- num_removes == 2 and
97
- @routes.size == 2 and
98
- (outbound_route = @routes.last) and
99
- outbound_route.ovid_param and
100
- (@route_outbound_flow_token = outbound_route.user) != @connection_outbound_flow_token
101
- )
102
- @incoming_outbound_requested = true
103
- log_system_debug "destination is an incoming Outbound connection" if $oversip_debug
104
- end
105
-
106
- # If there are not Route headers return false.
107
- return false unless @routes
108
-
109
- # Remove the Route values pointintg to us.
110
- unless num_removes == 0
111
- @headers["Route"].shift num_removes
112
- @routes.shift num_removes
113
- end
114
- @routes.empty? and @routes = nil
115
-
116
- # Return true if it is an in-dialog request and the top Route pointed to us.
117
- # False otherwise as we shouldn't receive an in-dialog request with a top Route non
118
- # pointing to us.
119
- if in_dialog?
120
- return ( num_removes > 0 ? true : false )
121
- # Return true if it was an initial request and more Route headers remain after inspection.
122
- elsif @routes
123
- return true
124
- # Return false if it was an initial request and all its Route headers pointed to the proxy.
125
- else
126
- return false
127
- end
128
- end
129
-
130
-
131
- # Checks whether the RURI points to a local domain or address.
132
- # Typically, prior to using this method the user has verified the return value of loose_route()
133
- # in case it's an initial request (if it's _true_ then the request has pre-loaded Route).
134
- def destination_myself?
135
- return true if @destination_myself
136
- return false if @destination_myself == false
137
-
138
- if local_uri? @ruri
139
- log_system_debug "RURI destination is myself" if $oversip_debug
140
- return @destination_myself = true
141
- else
142
- log_system_debug "RURI destination is not myself" if $oversip_debug
143
- return @destination_myself = false
144
- end
145
- end
146
-
147
-
148
- def fix_nat
149
- # Force rport usage for UDP clients.
150
- @via_rport = @source_port
151
-
152
- # Force outgoing Outbound.
153
- if initial? and @num_vias == 1 and outbound_aware?
154
- @force_outgoing_outbound = true
155
- end
156
- end
157
-
158
-
159
- def outgoing_outbound_requested? ; @outgoing_outbound_requested end
160
-
161
- def incoming_outbound_requested? ; @incoming_outbound_requested end
162
-
163
-
164
- def connection_outbound_flow_token
165
- @connection_outbound_flow_token ||= if @transport == :udp
166
- # 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 (when Contact mangling is used
168
- # if the registrar does not support Path).
169
- "_" << ::Base64.strict_encode64("#{@source_ip}_#{@source_port}").gsub(/=/,"-")
170
- else
171
- @connection.outbound_flow_token
172
- end
173
- end
174
-
175
-
176
- private
177
-
178
-
179
- def local_uri? uri
180
- # NOTE: uri.host has been normalized during parsing in case it's an IPv6 and it's
181
- # an :ipv6_reference.
182
- ( uri.port and ::OverSIP::SIP.local_aliases["#{uri.host}:#{uri.port}"] ) or
183
- ( not uri.port and ::OverSIP::SIP.local_aliases[uri.host] )
184
- end
185
-
186
- end # module Core
187
- end # module Modules
188
-
189
-
190
- class Request
191
- include ::OverSIP::SIP::Modules::Core
192
- end
193
-
194
- end
@@ -1,72 +0,0 @@
1
- module OverSIP::SIP
2
-
3
- module Modules
4
- module RegistrarWithoutPath
5
-
6
- extend ::OverSIP::Logger
7
-
8
- def self.log_id
9
- @@log_id ||= "RegistrarWithoutPath module"
10
- end
11
-
12
- def self.add_outbound_to_contact request
13
- unless request.sip_method == :REGISTER
14
- raise ::OverSIP::RuntimeError, "request must be a REGISTER"
15
- end
16
-
17
- if request.contact and request.connection_outbound_flow_token
18
- log_system_debug "performing Contact mangling (adding ;ov-ob Outbound param) for #{request.log_id}" if $oversip_debug
19
-
20
- # Add the ;ov-ob param to the Contact URI.
21
- request.contact.set_param "ov-ob", request.connection_outbound_flow_token
22
- # NOTE: request.contact_params is a String with the original Contact URI params
23
- # so they are added at the end of the new URI with the added ;ov-ob param.
24
- # TODO: This should be done automatically, right?
25
- request.set_header "Contact", "#{request.contact.to_s}#{request.contact_params}"
26
- return true
27
- else
28
- return false
29
- end
30
- end
31
-
32
- def self.extract_outbound_from_ruri request
33
- # Do nothing if the request already contains a Route header with the Outbound flow token (so
34
- # the registrar *does* support Path).
35
- unless request.incoming_outbound_requested?
36
- if (ov_ob = request.ruri.del_param("ov-ob"))
37
- log_system_debug "incoming Outbound flow token extracted from ;ov-ob param in RURI for #{request.log_id}" if $oversip_debug
38
- request.route_outbound_flow_token = ov_ob
39
- request.incoming_outbound_requested = true
40
- return true
41
- else
42
- return false
43
- end
44
-
45
- else
46
- # If the request already contains a proper Outbound Route header, then at least try to remove
47
- # the ;ov-ob param from the RURI.
48
- request.ruri.del_param("ov-ob")
49
- return false
50
- end
51
- end
52
-
53
- def self.remove_outbound_from_contact message
54
- unless message.is_a? ::OverSIP::SIP::Message
55
- raise ::OverSIP::RuntimeError, "message must be a OverSIP::SIP::Request or OverSIP::SIP::Response"
56
- end
57
-
58
- if (contacts = message.headers["Contact"])
59
- log_system_debug "reverting original Contact value (removing ;ov-ob Outbound param) for response" if $oversip_debug
60
- contacts.each do |contact|
61
- contact.gsub! /;ov-ob=[_\-0-9A-Za-z]+/, ""
62
- end
63
- return true
64
- else
65
- return false
66
- end
67
- end
68
-
69
- end # module RegistrarWithoutPath
70
- end # module Modules
71
-
72
- end # module OverSIP::SIP
@@ -1,77 +0,0 @@
1
- module OverSIP::SIP
2
-
3
- module Modules
4
- module UserAssertion
5
-
6
- extend ::OverSIP::Logger
7
-
8
- def self.log_id
9
- @@log_id ||= "UserAssertion module"
10
- end
11
-
12
- def self.assert_connection message
13
- case message
14
- when ::OverSIP::SIP::Request
15
- request = message
16
- when ::OverSIP::SIP::Response
17
- request = message.request
18
- else
19
- raise ::OverSIP::RuntimeError, "message must be a OverSIP::SIP::Request or OverSIP::SIP::Response"
20
- end
21
-
22
- # Don't do this stuf for UDP or for outbound connections.
23
- return false unless request.connection.class.reliable_transport_listener?
24
- # Return if already set.
25
- return request.cvars[:asserted_user] if request.cvars[:asserted_user]
26
- # Don't do this stuf in case of P-Preferred-Identity header is present.
27
- return false if request.headers["P-Preferred-Identity"]
28
-
29
- log_system_debug "user #{request.from.uri} asserted to connection" if $oversip_debug
30
- # Store the request From URI as "asserted_user" for this connection.
31
- request.cvars[:asserted_user] = request.from.uri
32
- end
33
-
34
- def self.revoke_assertion message
35
- case message
36
- when ::OverSIP::SIP::Request
37
- request = message
38
- when ::OverSIP::SIP::Response
39
- request = message.request
40
- else
41
- raise ::OverSIP::RuntimeError, "message must be a OverSIP::SIP::Request or OverSIP::SIP::Response"
42
- end
43
-
44
- request.cvars.delete :asserted_user
45
- true
46
- end
47
-
48
- def self.add_pai request
49
- # Add P-Asserted-Identity if the user has previously been asserted but JUST
50
- # in case it matches request From URI !
51
- # NOTE: If the connection is not asserted (it's null) then it will not match this
52
- # comparisson, so OK.
53
- if request.cvars[:asserted_user] == request.from.uri
54
- # Don't add P-Asserted-Identity if the request contains P-Preferred-Identity header.
55
- unless request.headers["P-Preferred-Identity"]
56
- log_system_debug "user asserted, adding P-Asserted-Identity for #{request.log_id}" if $oversip_debug
57
- request.set_header "P-Asserted-Identity", "<" << request.cvars[:asserted_user] << ">"
58
- return true
59
- else
60
- # Remove posible P-Asserted-Identity header!
61
- log_system_debug "user asserted but P-Preferred-Identity header present, P-Asserted-Identity not added for #{request.log_id}" if $oversip_debug
62
- request.headers.delete "P-Asserted-Identity"
63
- return nil
64
- end
65
-
66
- # Otherwise ensure the request has no spoofed P-Asserted-Identity headers!
67
- else
68
- request.headers.delete "P-Asserted-Identity"
69
- return false
70
-
71
- end
72
- end
73
-
74
- end # module UserAssertion
75
- end # module Modules
76
-
77
- end