oversip 1.1.2 → 1.2.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.
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