diameter 0.2.0pre1 → 0.2.0pre2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/diameter/stack.rb +47 -5
- data/lib/diameter/stack_transport_helpers.rb +4 -0
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5f3f9bf79194a1bf46cdeb9f5554f4d6b1e12969
|
4
|
+
data.tar.gz: a652abd1f5e36bb61de18851e17fc097fab8c806
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9ba23cea6ecdb922d02f9d2bd0589054e4e098fe3b522442835f36deb59649f83baa56ab84592c5fb2ae053bd0408838eebc732de2d6f1c73501ef12436780f5
|
7
|
+
data.tar.gz: 1cd7b01d9b41dff2608da114711b83cad13b9fd196eff9bbc8b6eddff325bff9d3515674ed7be0157e29a591faa7c9b56b700ad320e3d1444305b9f89b8d2c20
|
data/lib/diameter/stack.rb
CHANGED
@@ -8,6 +8,21 @@ 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
|
+
|
11
26
|
class Stack
|
12
27
|
include Internals
|
13
28
|
|
@@ -36,6 +51,7 @@ module Diameter
|
|
36
51
|
|
37
52
|
@tcp_helper = TCPStackHelper.new(self)
|
38
53
|
@peer_table = {}
|
54
|
+
@realm_table = {}
|
39
55
|
@handlers = {}
|
40
56
|
|
41
57
|
@answer_timeout = opts.fetch(:timeout, 60)
|
@@ -127,6 +143,11 @@ module Diameter
|
|
127
143
|
|
128
144
|
# @!group Peer connections and message sending
|
129
145
|
|
146
|
+
# Looks up the given Diameter realm with DNS-SRV, and establishes
|
147
|
+
# a connection to one peer in that realm.
|
148
|
+
#
|
149
|
+
# @param realm [String] The Diameter realm to connect to.
|
150
|
+
# @return [Peer] The Diameter peer chosen.
|
130
151
|
def connect_to_realm(realm)
|
131
152
|
possible_peers = []
|
132
153
|
@res.query("_diameter._tcp.#{realm}", "SRV").each_answer do |a|
|
@@ -152,6 +173,7 @@ module Diameter
|
|
152
173
|
# @param peer_host [String] The DiameterIdentity of this peer, which
|
153
174
|
# will uniquely identify it in the peer table.
|
154
175
|
# @param realm [String] The Diameter realm of this peer.
|
176
|
+
# @return [Peer] The Diameter peer chosen.
|
155
177
|
def connect_to_peer(peer_uri, peer_host, realm)
|
156
178
|
uri = URI(peer_uri)
|
157
179
|
cxn = @tcp_helper.setup_new_connection(uri.host, uri.port)
|
@@ -164,15 +186,20 @@ module Diameter
|
|
164
186
|
avps += app_avps
|
165
187
|
cer_bytes = Message.new(version: 1, command_code: 257, app_id: 0, request: true, proxyable: false, retransmitted: false, error: false, avps: avps).to_wire
|
166
188
|
@tcp_helper.send(cer_bytes, cxn)
|
189
|
+
|
190
|
+
@realm_table[realm] = Realm.new(peer_host)
|
191
|
+
|
167
192
|
@peer_table[peer_host] = Peer.new(peer_host)
|
168
193
|
@peer_table[peer_host].state = :WAITING
|
194
|
+
# Will move to :UP when the CEA is received
|
169
195
|
@peer_table[peer_host].cxn = cxn
|
196
|
+
|
170
197
|
@peer_table[peer_host]
|
171
|
-
# Will move to :UP when the CEA is received
|
172
198
|
end
|
173
199
|
|
174
200
|
# Sends a Diameter request. This is routed to an appropriate peer
|
175
|
-
# based on the Destination-Host AVP
|
201
|
+
# based on the Destination-Host AVP (or, if that is absent, on the
|
202
|
+
# Destination-Realm AVP).
|
176
203
|
#
|
177
204
|
# This adds this stack's Origin-Host and Origin-Realm AVPs, if
|
178
205
|
# those AVPs don't already exist.
|
@@ -180,8 +207,19 @@ module Diameter
|
|
180
207
|
# @param req [Message] The request to send.
|
181
208
|
def send_request(req)
|
182
209
|
fail "Must pass a request" unless req.request
|
183
|
-
req.add_origin_host_and_realm(@local_host, @local_realm)
|
184
|
-
peer_name = req
|
210
|
+
req.add_origin_host_and_realm(@local_host, @local_realm)
|
211
|
+
peer_name = if req['Destination-Host']
|
212
|
+
req['Destination-Host'].octet_string
|
213
|
+
elsif req['Destination-Realm']
|
214
|
+
realm = req['Destination-Realm'].octet_string
|
215
|
+
if @realm_table.has_key? realm
|
216
|
+
@realm_table[realm].best_peer
|
217
|
+
else
|
218
|
+
fail "No connection to realm #{realm}"
|
219
|
+
end
|
220
|
+
else
|
221
|
+
fail "Request must have Destination-Host or Destination-Realm"
|
222
|
+
end
|
185
223
|
state = peer_state(peer_name)
|
186
224
|
if state == :UP
|
187
225
|
peer = @peer_table[peer_name]
|
@@ -190,13 +228,17 @@ module Diameter
|
|
190
228
|
@pending_ete[req.ete] = q
|
191
229
|
|
192
230
|
# Time this request out if no answer is received
|
231
|
+
Diameter.logger.debug("Scheduling timeout for #{@answer_timeout}s time")
|
232
|
+
=begin
|
193
233
|
Concurrent::timer(@answer_timeout) do
|
234
|
+
Diameter.logger.debug("Timing out message with EtE #{req.ete}")
|
194
235
|
q = @pending_ete.delete(req.ete)
|
195
236
|
if q
|
196
237
|
q.push(:timeout)
|
197
238
|
end
|
198
239
|
end
|
199
|
-
|
240
|
+
=end
|
241
|
+
|
200
242
|
p = Concurrent::Promise.execute(executor: @threadpool) {
|
201
243
|
Diameter.logger.debug("Waiting for answer to message with EtE #{req.ete}, queue #{q}")
|
202
244
|
val = q.pop
|
@@ -48,7 +48,9 @@ module Diameter
|
|
48
48
|
rs, _ws, es = IO.select(@all_connections + [@wakeup_pipe_rd], [], @all_connections)
|
49
49
|
|
50
50
|
es.each do |e|
|
51
|
+
# :nocov:
|
51
52
|
Diameter.logger.log(Logger::WARN, "Exception on connection #{e}")
|
53
|
+
# :nocov:
|
52
54
|
end
|
53
55
|
|
54
56
|
rs.each do |r|
|
@@ -134,7 +136,9 @@ module Diameter
|
|
134
136
|
def accept_loop
|
135
137
|
rs, _ws, es = IO.select(@listen_connections, [], @listen_connections)
|
136
138
|
es.each do |e|
|
139
|
+
# :nocov:
|
137
140
|
Diameter.logger.log(Logger::WARN, "Exception on connection #{e}")
|
141
|
+
# :nocov:
|
138
142
|
end
|
139
143
|
|
140
144
|
rs.each do |r|
|