diameter 0.2.0pre2 → 0.3.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.
- checksums.yaml +4 -4
- data/lib/diameter/avp_names.rb +1 -1
- data/lib/diameter/message.rb +3 -1
- data/lib/diameter/peer.rb +2 -1
- data/lib/diameter/stack.rb +53 -49
- metadata +35 -8
- data/lib/diameter/fsm.rb +0 -27
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 78fdef7d94263e4950aec0b5c1dbf6e18925c817
|
4
|
+
data.tar.gz: 6d2d7d32b7701e73474c048cc39cb5e9c0263311
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f1cf4fe297f2f6dfa12ccb5645282b4c59bc7f8df21f8a16ec00cfd59580ad02981000d0feac28a0e8afb46a771740917fd4a05c7753557e31f003d66400dde3
|
7
|
+
data.tar.gz: 75d82606e30f397720fd18bbc950cd3e7ce2f00891e79f2983d93a9a94cb93788d3e59f164012317a3d84e620a73fb310fc4e6707c548e20b660c28a7e0b3812
|
data/lib/diameter/avp_names.rb
CHANGED
@@ -10,7 +10,7 @@ module Diameter
|
|
10
10
|
'NAS-Port' => [5, Unsigned32],
|
11
11
|
'Service-Type' => [6, Enumerated],
|
12
12
|
'Framed-Protocol' => [7, Enumerated],
|
13
|
-
'Framed-IP-Address' => [8,
|
13
|
+
'Framed-IP-Address' => [8, OctetString],
|
14
14
|
'Framed-IP-Netmask' => [9, IPAddress],
|
15
15
|
'Framed-Routing' => [10, Enumerated],
|
16
16
|
'Filter-Id' => [11, UTF8String],
|
data/lib/diameter/message.rb
CHANGED
@@ -233,7 +233,9 @@ module Diameter
|
|
233
233
|
def create_answer(result_code, opts={})
|
234
234
|
fail "Cannot answer an answer" if answer
|
235
235
|
|
236
|
-
avps =
|
236
|
+
avps = []
|
237
|
+
avps << avp_by_name("Session-Id") unless avp_by_name("Session-Id").nil?
|
238
|
+
avps += opts.fetch(:avps, [])
|
237
239
|
avps << if opts[:experimental_result_vendor]
|
238
240
|
AVP.create("Experimental-Result",
|
239
241
|
[AVP.create("Experimental-Result-Code", result_code),
|
data/lib/diameter/peer.rb
CHANGED
@@ -25,8 +25,9 @@ module Diameter
|
|
25
25
|
attr_accessor :identity, :static, :cxn, :realm, :expiry_time, :last_message_seen
|
26
26
|
attr_reader :state
|
27
27
|
|
28
|
-
def initialize(identity)
|
28
|
+
def initialize(identity, realm)
|
29
29
|
@identity = identity
|
30
|
+
@realm = realm
|
30
31
|
@state = :CLOSED
|
31
32
|
@state_change_q = Queue.new
|
32
33
|
end
|
data/lib/diameter/stack.rb
CHANGED
@@ -8,21 +8,6 @@ require 'concurrent'
|
|
8
8
|
require 'dnsruby'
|
9
9
|
|
10
10
|
module Diameter
|
11
|
-
class Realm
|
12
|
-
def initialize(peer_name)
|
13
|
-
@peers = []
|
14
|
-
add_peer(peer_name)
|
15
|
-
end
|
16
|
-
|
17
|
-
def add_peer(name)
|
18
|
-
@peers << name
|
19
|
-
end
|
20
|
-
|
21
|
-
def best_peer
|
22
|
-
@peers[0]
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
11
|
class Stack
|
27
12
|
include Internals
|
28
13
|
|
@@ -51,7 +36,6 @@ module Diameter
|
|
51
36
|
|
52
37
|
@tcp_helper = TCPStackHelper.new(self)
|
53
38
|
@peer_table = {}
|
54
|
-
@realm_table = {}
|
55
39
|
@handlers = {}
|
56
40
|
|
57
41
|
@answer_timeout = opts.fetch(:timeout, 60)
|
@@ -60,7 +44,7 @@ module Diameter
|
|
60
44
|
min_threads: 5,
|
61
45
|
max_threads: 5,
|
62
46
|
max_queue: 1,
|
63
|
-
|
47
|
+
fallback_policy: :caller_runs
|
64
48
|
)
|
65
49
|
|
66
50
|
@res = Dnsruby::Resolver.new
|
@@ -187,9 +171,7 @@ module Diameter
|
|
187
171
|
cer_bytes = Message.new(version: 1, command_code: 257, app_id: 0, request: true, proxyable: false, retransmitted: false, error: false, avps: avps).to_wire
|
188
172
|
@tcp_helper.send(cer_bytes, cxn)
|
189
173
|
|
190
|
-
@
|
191
|
-
|
192
|
-
@peer_table[peer_host] = Peer.new(peer_host)
|
174
|
+
@peer_table[peer_host] = Peer.new(peer_host, realm)
|
193
175
|
@peer_table[peer_host].state = :WAITING
|
194
176
|
# Will move to :UP when the CEA is received
|
195
177
|
@peer_table[peer_host].cxn = cxn
|
@@ -205,31 +187,40 @@ module Diameter
|
|
205
187
|
# those AVPs don't already exist.
|
206
188
|
#
|
207
189
|
# @param req [Message] The request to send.
|
208
|
-
|
190
|
+
# @param peer [Peer] (Optional) A peer to use as the first hop for the message
|
191
|
+
def send_request(req, options={})
|
209
192
|
fail "Must pass a request" unless req.request
|
210
193
|
req.add_origin_host_and_realm(@local_host, @local_realm)
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
194
|
+
|
195
|
+
peer = options[:peer]
|
196
|
+
|
197
|
+
if peer.nil?
|
198
|
+
peer = if req['Destination-Host']
|
199
|
+
peer_identity = req['Destination-Host'].octet_string
|
200
|
+
Diameter.logger.debug("Selecting peer by Destination-Host (#{peer_identity})")
|
201
|
+
@peer_table[peer_identity]
|
202
|
+
elsif req['Destination-Realm']
|
203
|
+
realm = req['Destination-Realm'].octet_string
|
204
|
+
Diameter.logger.debug("Selecting peer by Destination-Realm (#{realm})")
|
205
|
+
@peer_table.values.select { |p| p.realm == realm }.sample
|
206
|
+
else
|
207
|
+
fail "Request must have Destination-Host or Destination-Realm"
|
208
|
+
end
|
209
|
+
else
|
210
|
+
Diameter.logger.debug("Peer selection forced to #{peer.identity}")
|
211
|
+
end
|
212
|
+
|
213
|
+
if peer.nil?
|
214
|
+
Diameter.logger.warn("No peer is available to send message - cannot route")
|
215
|
+
fail "No acceptable peer"
|
216
|
+
elsif peer.state == :UP
|
227
217
|
q = Queue.new
|
228
218
|
@pending_ete[req.ete] = q
|
219
|
+
@tcp_helper.send(req.to_wire, peer.cxn)
|
229
220
|
|
221
|
+
=begin
|
230
222
|
# Time this request out if no answer is received
|
231
223
|
Diameter.logger.debug("Scheduling timeout for #{@answer_timeout}s time")
|
232
|
-
=begin
|
233
224
|
Concurrent::timer(@answer_timeout) do
|
234
225
|
Diameter.logger.debug("Timing out message with EtE #{req.ete}")
|
235
226
|
q = @pending_ete.delete(req.ete)
|
@@ -247,7 +238,7 @@ module Diameter
|
|
247
238
|
}
|
248
239
|
return p
|
249
240
|
else
|
250
|
-
Diameter.logger.
|
241
|
+
Diameter.logger.warn("Peer #{peer.identity} is in state #{peer.state} - cannot route")
|
251
242
|
end
|
252
243
|
end
|
253
244
|
|
@@ -302,7 +293,7 @@ module Diameter
|
|
302
293
|
end
|
303
294
|
|
304
295
|
if msg.command_code == 257 && msg.answer
|
305
|
-
handle_cea(msg)
|
296
|
+
handle_cea(msg, cxn)
|
306
297
|
elsif msg.command_code == 257 && msg.request
|
307
298
|
handle_cer(msg, cxn)
|
308
299
|
elsif msg.command_code == 280 && msg.request
|
@@ -381,8 +372,9 @@ module Diameter
|
|
381
372
|
|
382
373
|
if rc == 2001
|
383
374
|
peer = cer.avp_by_name('Origin-Host').octet_string
|
384
|
-
|
385
|
-
|
375
|
+
realm = cer.avp_by_name('Origin-Realm').octet_string
|
376
|
+
Diameter.logger.debug("Creating peer table entry for peer #{peer} in realm #{realm}")
|
377
|
+
@peer_table[peer] = Peer.new(peer, realm)
|
386
378
|
@peer_table[peer].state = :UP
|
387
379
|
@peer_table[peer].reset_timer
|
388
380
|
@peer_table[peer].cxn = cxn
|
@@ -391,14 +383,26 @@ module Diameter
|
|
391
383
|
end
|
392
384
|
end
|
393
385
|
|
394
|
-
def handle_cea(cea)
|
395
|
-
|
396
|
-
if @peer_table.has_key?
|
397
|
-
@peer_table[
|
398
|
-
@peer_table[
|
386
|
+
def handle_cea(cea, cxn)
|
387
|
+
host = cea.avp_by_name('Origin-Host').octet_string
|
388
|
+
if @peer_table.has_key? host
|
389
|
+
@peer_table[host].state = :UP
|
390
|
+
@peer_table[host].reset_timer
|
399
391
|
else
|
400
|
-
|
401
|
-
|
392
|
+
entry = @peer_table.find { |h, p| p.cxn == cxn }
|
393
|
+
if entry.nil?
|
394
|
+
Diameter.logger.warn("Ignoring CEA from unknown peer #{host}")
|
395
|
+
Diameter.logger.debug("Known peers are #{@peer_table.keys}")
|
396
|
+
else
|
397
|
+
old_host, peer = entry
|
398
|
+
Diameter.logger.warn("Peer identity changed #{old_host} => #{host}")
|
399
|
+
|
400
|
+
@peer_table.delete(old_host)
|
401
|
+
peer.identity = host
|
402
|
+
@peer_table[host] = peer
|
403
|
+
@peer_table[host].state = :UP
|
404
|
+
@peer_table[host].reset_timer
|
405
|
+
end
|
402
406
|
end
|
403
407
|
end
|
404
408
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: diameter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rob Day
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-03-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '0.
|
19
|
+
version: '0.9'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '0.
|
26
|
+
version: '0.9'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: dnsruby
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '1'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '10'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '10'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: rubocop
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -108,6 +122,20 @@ dependencies:
|
|
108
122
|
- - '='
|
109
123
|
- !ruby/object:Gem::Version
|
110
124
|
version: 0.0.3
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: minitest
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - '='
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: 5.8.0
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - '='
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: 5.8.0
|
111
139
|
description:
|
112
140
|
email: ruby-diameter@rkd.me.uk
|
113
141
|
executables: []
|
@@ -120,7 +148,6 @@ files:
|
|
120
148
|
- lib/diameter/avp_parser.rb
|
121
149
|
- lib/diameter/constants.rb
|
122
150
|
- lib/diameter/diameter_logger.rb
|
123
|
-
- lib/diameter/fsm.rb
|
124
151
|
- lib/diameter/message.rb
|
125
152
|
- lib/diameter/peer.rb
|
126
153
|
- lib/diameter/stack.rb
|
@@ -141,12 +168,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
141
168
|
version: '0'
|
142
169
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
143
170
|
requirements:
|
144
|
-
- - "
|
171
|
+
- - ">="
|
145
172
|
- !ruby/object:Gem::Version
|
146
|
-
version:
|
173
|
+
version: '0'
|
147
174
|
requirements: []
|
148
175
|
rubyforge_project:
|
149
|
-
rubygems_version: 2.4.
|
176
|
+
rubygems_version: 2.4.8
|
150
177
|
signing_key:
|
151
178
|
specification_version: 4
|
152
179
|
summary: Pure-Ruby Diameter stack
|
data/lib/diameter/fsm.rb
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
require 'micromachine'
|
2
|
-
|
3
|
-
machine = MicroMachine.new(:closed) # Initial state.
|
4
|
-
|
5
|
-
# Define the possible transitions for each event.
|
6
|
-
machine.when(:closed, :start => :wait_conn_ack)
|
7
|
-
machine.when(:closed, :r_conn_cer => :r_open)
|
8
|
-
|
9
|
-
machine.when(:wait_conn_ack, :i_rcv_conn_ack => :wait_i_cea)
|
10
|
-
machine.when(:wait_conn_ack, :i_rcv_conn_nack => :closed)
|
11
|
-
machine.when(:wait_conn_ack, :r_conn_cer => :wait_conn_ack_elect)
|
12
|
-
machine.when(:wait_conn_ack, :timeout => :closed)
|
13
|
-
|
14
|
-
|
15
|
-
machine.when(:reset, :confirmed => :new, :ignored => :new)
|
16
|
-
|
17
|
-
machine.trigger(:confirm) #=> true
|
18
|
-
machine.state #=> :confirmed
|
19
|
-
|
20
|
-
machine.trigger(:ignore) #=> false
|
21
|
-
machine.state #=> :confirmed
|
22
|
-
|
23
|
-
machine.trigger(:reset) #=> true
|
24
|
-
machine.state #=> :new
|
25
|
-
|
26
|
-
machine.trigger(:ignore) #=> true
|
27
|
-
machine.state #=> :ignored
|