diameter 0.1.0.beta → 0.1.0.pre1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 155d66671781834056b72ee9fca500a317dd2580
4
- data.tar.gz: d2233fc23a94125190656b1f13b73d193e178082
3
+ metadata.gz: e140baae5544d85586d01a9dbd1000c63d95aab0
4
+ data.tar.gz: c8407d154a3498d9d159acf99c1222043a288760
5
5
  SHA512:
6
- metadata.gz: 0193a6fee32495c1566fe839cc3cdfb44f65ce7de5730cc4753b344c8809ea7afe2ce72b385d30f098544586e79c7543005c0198eb453c67cbf19cd3c7199428
7
- data.tar.gz: cbed37f246b89602d463fc4cd5ce04d84a464c79e0ea3a054e47b78e37a2b54b3b3516c8c650194ebafd4cf78683b6f61b4b34f70e4db1ef8a68d924aab5c9a3
6
+ metadata.gz: 5e8e0a512e7b9ec8111a7e8d8e70252a6e0deaad7b966013a8a80be8bfb8f0d84dcfcfa65caa7264e7798ab4b39f08ed1fdcb616cc0307914b4ff9534e86722b
7
+ data.tar.gz: 44f4430b63e1c4a02c6f477ac89e37a2f0b94897a39e51ccae13eee62e73c0eba8f48ac7a35f74106b8d4cfa01312fa59b9128d40c53dd7be70cc57160d05a29
data/lib/diameter/avp.rb CHANGED
@@ -51,14 +51,12 @@ module Diameter
51
51
 
52
52
  include AVPParser
53
53
 
54
- # @api private
55
- #
56
- # Prefer {AVP.create} where possible.
57
54
  def initialize(code, options = {})
58
55
  @code = code
59
56
  @vendor_id = options[:vendor_id] || 0
60
57
  @content = options[:content] || ''
61
- @mandatory = options.fetch(:mandatory, true)
58
+ @mandatory = options[:mandatory]
59
+ @mandatory = true if @mandatory.nil?
62
60
  end
63
61
 
64
62
  # Creates an AVP by name, and assigns it a value.
@@ -68,10 +66,6 @@ module Diameter
68
66
  # that AVP - e.g. a Fixnum for an AVP defined as Unsigned32, a
69
67
  # String for an AVP defined as OctetString, or an IPAddr for an AVP
70
68
  # defined as IPAddress.
71
- # @option opts [true, false] mandatory
72
- # Whether understanding this AVP is mandatory within this
73
- # application.
74
- #
75
69
  # @return [AVP] The AVP that was created.
76
70
  def self.create(name, val, options = {})
77
71
  code, type, vendor = AVPNames.get(name)
@@ -109,7 +103,22 @@ module Diameter
109
103
  to_wire_novendor
110
104
  end
111
105
  end
106
+
107
+ def to_wire_novendor
108
+ length_8, length_16 = UInt24.to_u8_and_u16(@content.length + 8)
109
+ avp_flags = @mandatory ? '01000000' : '00000000'
110
+ header = [@code, avp_flags, length_8, length_16].pack('NB8Cn')
111
+ header + padded_content
112
+ end
113
+
114
+ def to_wire_vendor
115
+ length_8, length_16 = UInt24.to_u8_and_u16(@content.length + 12)
116
+ avp_flags = @mandatory ? '11000000' : '10000000'
117
+ header = [@code, avp_flags, length_8, length_16, @vendor_id].pack('NB8CnN')
118
+ header + padded_content
119
+ end
112
120
 
121
+
113
122
  # Guessing the type of an AVP and displaying it sensibly is complex,
114
123
  # so this is a complex method (but one that has a unity of purpose,
115
124
  # so can't easily be broken down). Disable several Rubocop
@@ -207,8 +216,6 @@ module Diameter
207
216
  grouped_value.select { |a| a.code == code }
208
217
  end
209
218
 
210
- alias_method :[], :inner_avp
211
-
212
219
  # Even though it is just "the raw bytes in the content",
213
220
  # octet_string is only one way of interpreting the AVP content and
214
221
  # shouldn't be treated differently to the others, so disable the
@@ -364,20 +371,6 @@ module Diameter
364
371
  end
365
372
  end
366
373
 
367
- def to_wire_novendor
368
- length_8, length_16 = UInt24.to_u8_and_u16(@content.length + 8)
369
- avp_flags = @mandatory ? '01000000' : '00000000'
370
- header = [@code, avp_flags, length_8, length_16].pack('NB8Cn')
371
- header + padded_content
372
- end
373
-
374
- def to_wire_vendor
375
- length_8, length_16 = UInt24.to_u8_and_u16(@content.length + 12)
376
- avp_flags = @mandatory ? '11000000' : '10000000'
377
- header = [@code, avp_flags, length_8, length_16, @vendor_id].pack('NB8CnN')
378
- header + padded_content
379
- end
380
-
381
374
  protected
382
375
 
383
376
  def padded_content
@@ -1,7 +1,6 @@
1
1
  require 'diameter/avp_parser'
2
2
  require 'diameter/u24'
3
3
 
4
- # The Diameter module
5
4
  module Diameter
6
5
  # A Diameter message.
7
6
  #
@@ -18,14 +17,16 @@ module Diameter
18
17
  # The end-to-end identifier of this message.
19
18
  # @!attribute [r] request
20
19
  # Whether this message is a request.
21
- # @!attribute [r] answer
22
- # Whether this message is an answer.
23
20
  class Message
24
- attr_reader :version, :command_code, :app_id, :hbh, :ete, :request, :answer
21
+ attr_reader :version, :command_code, :app_id, :hbh, :ete, :request
25
22
  include Internals
23
+
24
+ # @!attribute [r] answer
25
+ # Whether this message is an answer.
26
+ def answer
27
+ !@request
28
+ end
26
29
 
27
- # Creates a new Diameter message.
28
- #
29
30
  # @option opts [Fixnum] command_code
30
31
  # The Diameter Command-Code of this messsage.
31
32
  # @option opts [Fixnum] app_id
@@ -51,7 +52,6 @@ module Diameter
51
52
  @ete = options[:ete] || Message.next_ete
52
53
 
53
54
  @request = options.fetch(:request, true)
54
- @answer = !@request
55
55
  @proxyable = options.fetch(:proxyable, false)
56
56
  @retransmitted = false
57
57
  @error = false
@@ -90,10 +90,8 @@ module Diameter
90
90
  # Returns the first AVP with the given name. Only covers "top-level"
91
91
  # AVPs - it won't look inside Grouped AVPs.
92
92
  #
93
- # Also available as [], e.g. message['Result-Code']
94
- #
95
93
  # @param name [String] The AVP name, either one predefined in
96
- # {Constants::AVAILABLE_AVPS} or user-defined with {AVP.define}
94
+ # {AVPNames::AVAILABLE_AVPS} or user-defined with {AVP.define}
97
95
  #
98
96
  # @return [AVP] if there is an AVP with that name
99
97
  # @return [nil] if there is not an AVP with that name
@@ -106,7 +104,7 @@ module Diameter
106
104
  # AVPs - it won't look inside Grouped AVPs.
107
105
  #
108
106
  # @param name [String] The AVP name, either one predefined in
109
- # {Constants::AVAILABLE_AVPS} or user-defined with {AVP.define}
107
+ # {AVPNames::AVAILABLE_AVPS} or user-defined with {AVP.define}
110
108
  #
111
109
  # @return [Array<AVP>]
112
110
  def all_avps_by_name(name)
@@ -115,12 +113,8 @@ module Diameter
115
113
  end
116
114
 
117
115
  alias_method :avp, :avp_by_name
118
- alias_method :[], :avp_by_name
119
- alias_method :avps, :all_avps_by_name
120
-
121
- # @private
122
- # Prefer AVP.define and the by-name versions to this
123
- #
116
+ alias_method :[], :all_avps_by_name
117
+
124
118
  # Returns the first AVP with the given code and vendor. Only covers "top-level"
125
119
  # AVPs - it won't look inside Grouped AVPs.
126
120
  #
@@ -138,9 +132,6 @@ module Diameter
138
132
  end
139
133
  end
140
134
 
141
- # @private
142
- # Prefer AVP.define and the by-name versions to this
143
- #
144
135
  # Returns all AVPs with the given code and vendor. Only covers "top-level"
145
136
  # AVPs - it won't look inside Grouped AVPs.
146
137
  #
@@ -162,24 +153,25 @@ module Diameter
162
153
 
163
154
  # Does this message contain a (top-level) AVP with this name?
164
155
  # @param name [String] The AVP name, either one predefined in
165
- # {Constants::AVAILABLE_AVPS} or user-defined with {AVP.define}
156
+ # {AVPNames::AVAILABLE_AVPS} or user-defined with {AVP.define}
166
157
  #
167
158
  # @return [true, false]
168
159
  def has_avp?(name)
169
160
  !!avp(name)
170
161
  end
171
162
 
172
- # @private
173
- #
174
- # Not recommended for normal use - all AVPs should be given to the
175
- # constructor. Used to allow the stack to add appropriate
176
- # Origin-Host/Origin-Realm AVPs to outbound messages.
163
+ # @api private
177
164
  #
178
- # @param host [String] The Diameter Identity for the stack.
179
- # @param realm [String] The Diameter realm for the stack.
180
- def add_origin_host_and_realm(host, realm)
181
- @avps << AVP.create("Origin-Host", host) unless has_avp? 'Origin-Host'
182
- @avps << AVP.create("Origin-Realm", realm) unless has_avp? 'Origin-Realm'
165
+ # Adds an AVP to this message. Not recommended for normal use -
166
+ # all AVPs should be given to the constructor. Used to allow the
167
+ # stack to add appropriate Origin-Host/Origin-Realm AVPs to outbound
168
+ # messages.
169
+ # @param name [String] The AVP name, either one predefined in
170
+ # {AVPNames::AVAILABLE_AVPS} or user-defined with {AVP.define}
171
+ # @param value [Object] The AVP value, with type dependent on the
172
+ # AVP itself.
173
+ def add_avp(name, value)
174
+ @avps << AVP.create(name, value)
183
175
  end
184
176
 
185
177
  # @!endgroup
@@ -214,7 +206,6 @@ module Diameter
214
206
  avps = Internals::AVPParser.parse_avps_int(bytes[20..-1])
215
207
  Message.new(version: version, command_code: command_code, app_id: app_id, hbh: hbh, ete: ete, request: request, proxyable: proxyable, retransmitted: false, error: false, avps: avps)
216
208
  end
217
-
218
209
  # @!endgroup
219
210
 
220
211
  # Generates an answer to this request, filling in a Result-Code or
@@ -9,21 +9,10 @@ require 'concurrent'
9
9
  module Diameter
10
10
  class Stack
11
11
  include Internals
12
-
13
- # @!group Setup methods
14
-
15
- # Stack constructor.
16
- #
17
- # @note The stack does not advertise any applications to peers by
18
- # default - {#add_handler} must be called early on.
19
- #
20
- # @param host [String] The Diameter Identity of this stack (for
21
- # the Origin-Host AVP).
22
- # @param realm [String] The Diameter realm of this stack (for
23
- # the Origin-Realm AVP).
24
- def initialize(host, realm)
12
+ def initialize(host, realm, opts={})
25
13
  @local_host = host
26
14
  @local_realm = realm
15
+ @local_port = opts[:port] || 3868
27
16
 
28
17
  @auth_apps = []
29
18
  @acct_apps = []
@@ -33,55 +22,18 @@ module Diameter
33
22
  @tcp_helper = TCPStackHelper.new(self)
34
23
  @peer_table = {}
35
24
  @handlers = {}
36
-
37
- @threadpool = pool = Concurrent::ThreadPoolExecutor.new(
38
- min_threads: 5,
39
- max_threads: 5,
40
- max_queue: 100,
41
- overflow_policy: :caller_runs
42
- )
43
-
44
-
45
25
  Diameter.logger.log(Logger::INFO, 'Stack initialized')
46
26
  end
47
27
 
48
- # Complete the stack initialization and begin reading from the TCP connections.
28
+ # @!group Setup methods
49
29
  def start
50
30
  @tcp_helper.start_main_loop
51
31
  end
52
32
 
53
- # Begins listening for inbound Diameter connections (making this a
54
- # Diameter server instead of just a client).
55
- #
56
- # @param port [Fixnum] The TCP port to listen on (default 3868)
57
- def listen_for_tcp(port=3868)
58
- @tcp_helper.setup_new_listen_connection("0.0.0.0", port)
33
+ def listen_for_tcp
34
+ @tcp_helper.setup_new_listen_connection("0.0.0.0", @local_port)
59
35
  end
60
36
 
61
- # Adds a handler for a specific Diameter application.
62
- #
63
- # @note If you expect to only send requests for this application,
64
- # not receive them, the block can be a no-op (e.g. `{ nil }`)
65
- #
66
- # @param app_id [Fixnum] The Diameter application ID.
67
- # @option opts [true, false] auth
68
- # Whether we should advertise support for this application in
69
- # the Auth-Application-ID AVP. Note that at least one of auth or
70
- # acct must be specified.
71
- # @option opts [true, false] acct
72
- # Whether we should advertise support for this application in
73
- # the Acct-Application-ID AVP. Note that at least one of auth or
74
- # acct must be specified.
75
- # @option opts [Fixnum] vendor
76
- # If we should advertise support for this application in a
77
- # Vendor-Specific-Application-Id AVP, this specifies the
78
- # associated Vendor-Id.
79
- #
80
- # @yield [req, cxn] Passes a Diameter message (and its originating
81
- # connection) for application-specific handling.
82
- # @yieldparam [Message] req The parsed Diameter message from the peer.
83
- # @yieldparam [Socket] cxn The TCP connection to the peer, to be
84
- # passed to {Stack#send_answer}.
85
37
  def add_handler(app_id, opts={}, &blk)
86
38
  vendor = opts.fetch(:vendor, 0)
87
39
  auth = opts.fetch(:auth, false)
@@ -97,24 +49,10 @@ module Diameter
97
49
 
98
50
  # @!endgroup
99
51
 
100
- # This shuts the stack down, closing all TCP connections and
101
- # terminating any background threads still waiting for an answer.
102
52
  def shutdown
103
53
  @tcp_helper.shutdown
104
- @pending_ete.each do |ete, q|
105
- Diameter.logger.debug("Shutting down queue #{q} as no answer has been received with EtE #{ete}")
106
- q.push :shutdown
107
- end
108
- @threadpool.kill
109
- @threadpool.wait_for_termination(5)
110
54
  end
111
55
 
112
- # Closes the given connection, blanking out any internal data
113
- # structures associated with it.
114
- #
115
- # Likely to be moved to the Peer object in a future release/
116
- #
117
- # @param connection [Socket] The connection to close.
118
56
  def close(connection)
119
57
  @tcp_helper.close(connection)
120
58
  end
@@ -125,11 +63,12 @@ module Diameter
125
63
  # network location indicated by peer_uri.
126
64
  #
127
65
  # @param peer_uri [URI] The aaa:// URI identifying the peer. Should
128
- # contain a hostname/IP; may contain a port (default 3868).
66
+ # contain a hostname/IP; may contain a port (default 3868) and a
67
+ # transport param indicating TCP or SCTP (default TCP).
129
68
  # @param peer_host [String] The DiameterIdentity of this peer, which
130
69
  # will uniquely identify it in the peer table.
131
70
  # @param realm [String] The Diameter realm of this peer.
132
- def connect_to_peer(peer_uri, peer_host, realm)
71
+ def connect_to_peer(peer_uri, peer_host, _realm)
133
72
  uri = URI(peer_uri)
134
73
  cxn = @tcp_helper.setup_new_connection(uri.host, uri.port)
135
74
  avps = [AVP.create('Origin-Host', @local_host),
@@ -148,25 +87,19 @@ module Diameter
148
87
  # Will move to :UP when the CEA is received
149
88
  end
150
89
 
151
- # Sends a Diameter request. This is routed to an appropriate peer
152
- # based on the Destination-Host AVP.
153
- #
154
- # This adds this stack's Origin-Host and Origin-Realm AVPs, if
155
- # those AVPs don't already exist.
156
- #
157
- # @param req [Message] The request to send.
158
90
  def send_request(req)
159
91
  fail "Must pass a request" unless req.request
160
- req.add_origin_host_and_realm(@local_host, @local_realm)
92
+ req.add_avp('Origin-Host', @local_host) unless req.has_avp? 'Origin-Host'
93
+ req.add_avp('Origin-Realm', @local_realm) unless req.has_avp? 'Origin-Realm'
94
+ q = Queue.new
95
+ @pending_ete[req.ete] = q
161
96
  peer_name = req.avp_by_name('Destination-Host').octet_string
162
97
  state = peer_state(peer_name)
163
98
  if state == :UP
164
99
  peer = @peer_table[peer_name]
165
100
  @tcp_helper.send(req.to_wire, peer.cxn)
166
- q = Queue.new
167
- @pending_ete[req.ete] = q
168
- p = Concurrent::Promise.execute(executor: @threadpool) {
169
- Diameter.logger.debug("Waiting for answer to message with EtE #{req.ete}, queue #{q}")
101
+ p = Concurrent::Promise.execute {
102
+ Diameter.logger.debug("Waiting for answer to message with EtE #{req.ete}")
170
103
  val = q.pop
171
104
  Diameter.logger.debug("Promise fulfilled for message with EtE #{req.ete}")
172
105
  val
@@ -177,28 +110,13 @@ module Diameter
177
110
  end
178
111
  end
179
112
 
180
- # Sends a Diameter answer. This is sent over the same connection
181
- # the request was received on (which needs to be passed into to
182
- # this method).
183
- #
184
- # This adds this stack's Origin-Host and Origin-Realm AVPs, if
185
- # those AVPs don't already exist.
186
- #
187
- # @param ans [Message] The Diameter answer
188
- # @param original_cxn [Socket] The connection which the request
189
- # came in on. This will have been passed to the block registered
190
- # with {Stack#add_handler}.
191
113
  def send_answer(ans, original_cxn)
192
114
  fail "Must pass an answer" unless ans.answer
193
- ans.add_origin_host_and_realm(@local_host, @local_realm)
115
+ ans.add_avp('Origin-Host', @local_host) unless ans.has_avp? 'Origin-Host'
116
+ ans.add_avp('Origin-Realm', @local_realm) unless ans.has_avp? 'Origin-Realm'
194
117
  @tcp_helper.send(ans.to_wire, original_cxn)
195
118
  end
196
119
 
197
- # Retrieves the current state of a peer, defaulting to :CLOSED if
198
- # the peer does not exist.
199
- #
200
- # @param id [String] The Diameter identity of the peer.
201
- # @return [Keyword] The state of the peer (:UP, :WAITING or :CLOSED).
202
120
  def peer_state(id)
203
121
  if !@peer_table.key? id
204
122
  :CLOSED
@@ -210,9 +128,6 @@ module Diameter
210
128
  # @!endgroup
211
129
 
212
130
  # @private
213
- # Handles a Diameter request straight from a network connection.
214
- # Intended to be called by TCPStackHelper after it retrieves a
215
- # message, not directly by users.
216
131
  def handle_message(msg_bytes, cxn)
217
132
  # Common processing - ensure that this message has come in on this
218
133
  # peer's expected connection, and update the last time we saw
@@ -318,6 +233,7 @@ module Diameter
318
233
 
319
234
  def handle_cea(cea)
320
235
  peer = cea.avp_by_name('Origin-Host').octet_string
236
+ # puts peer
321
237
  if @peer_table.has_key? peer
322
238
  @peer_table[peer].state = :UP
323
239
  @peer_table[peer].reset_timer
@@ -3,10 +3,6 @@ require 'socket'
3
3
  require 'diameter/message'
4
4
  require 'diameter/avp'
5
5
 
6
- if RUBY_ENGINE != 'jruby'
7
- ServerSocket = Socket
8
- end
9
-
10
6
  module Diameter
11
7
  module Internals
12
8
  # @private
@@ -19,7 +15,6 @@ module Diameter
19
15
  @loop_thread = nil
20
16
  @accept_loop_thread = nil
21
17
  @connection_lock = Mutex.new
22
- @wakeup_pipe_rd, @wakeup_pipe_wr = IO.pipe
23
18
  end
24
19
 
25
20
  def start_main_loop
@@ -32,25 +27,25 @@ module Diameter
32
27
  end
33
28
 
34
29
  def wakeup
35
- @wakeup_pipe_wr.puts "wakeup"
30
+ @loop_thread.raise
36
31
  end
37
32
 
38
33
  def main_loop
39
- rs, _ws, es = IO.select(@all_connections + [@wakeup_pipe_rd], [], @all_connections)
34
+ begin
35
+ rs, _ws, es = IO.select(@all_connections, [], @all_connections)
36
+ rescue RuntimeError
37
+ return
38
+ end
40
39
 
41
40
  es.each do |e|
42
41
  Diameter.logger.log(Logger::WARN, "Exception on connection #{e}")
43
42
  end
44
43
 
45
44
  rs.each do |r|
46
- if r == @wakeup_pipe_rd
47
- r.gets
48
- next
49
- end
50
45
 
51
46
  existing_data = @data[r]
52
47
  if existing_data.length < 4
53
- msg, _src = r.recv_nonblock(4 - existing_data.length)
48
+ msg, _src = r.recvfrom_nonblock(4 - existing_data.length)
54
49
  if msg == ''
55
50
  Diameter.logger.warn('Received 0 bytes on read, closing connection')
56
51
  close(r)
@@ -64,7 +59,7 @@ module Diameter
64
59
  expected_len = Message.length_from_header(existing_data[0..4])
65
60
  Diameter.logger.debug("Read 4 bytes #{existing_data[0..4].inspect}, " \
66
61
  "reading full message of length #{expected_len}")
67
- msg, _src = r.recv_nonblock(expected_len - existing_data.length)
62
+ msg, _src = r.recvfrom_nonblock(expected_len - existing_data.length)
68
63
  existing_data += msg
69
64
  if msg == ''
70
65
  # Connection closed
@@ -83,7 +78,7 @@ module Diameter
83
78
  end
84
79
 
85
80
  def send(bytes, connection)
86
- connection.send(bytes, 0)
81
+ connection.sendmsg(bytes)
87
82
  end
88
83
  end
89
84
 
@@ -118,7 +113,7 @@ module Diameter
118
113
  end
119
114
 
120
115
  def setup_new_listen_connection(host, port)
121
- sd = ServerSocket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
116
+ sd = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
122
117
  # reuse = [1,0].pack('ii')
123
118
  sd.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEADDR, true)
124
119
  sd.bind(Socket.pack_sockaddr_in(port, host))
metadata CHANGED
@@ -1,106 +1,105 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: diameter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0.beta
4
+ version: 0.1.0.pre1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rob Day
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-12-15 00:00:00.000000000 Z
11
+ date: 2014-12-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '0.7'
19
+ version: '0'
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.7'
26
+ version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rubocop
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '0.28'
33
+ version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '0.28'
40
+ version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: yard
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - '='
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: '0.8'
47
+ version: '0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - '='
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: '0.8'
54
+ version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: simplecov
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - '='
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
- version: '0.9'
61
+ version: '0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - '='
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
- version: '0.9'
68
+ version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: mocha
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - '='
73
+ - - ">="
74
74
  - !ruby/object:Gem::Version
75
- version: '1.1'
75
+ version: '0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - '='
80
+ - - ">="
81
81
  - !ruby/object:Gem::Version
82
- version: '1.1'
82
+ version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: minitest-spec-context
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - '='
87
+ - - ">="
88
88
  - !ruby/object:Gem::Version
89
- version: 0.0.3
89
+ version: '0'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - '='
94
+ - - ">="
95
95
  - !ruby/object:Gem::Version
96
- version: 0.0.3
96
+ version: '0'
97
97
  description:
98
98
  email: ruby-diameter@rkd.me.uk
99
99
  executables: []
100
100
  extensions: []
101
101
  extra_rdoc_files: []
102
102
  files:
103
- - lib/diameter.rb
104
103
  - lib/diameter/avp.rb
105
104
  - lib/diameter/avp_parser.rb
106
105
  - lib/diameter/constants.rb
data/lib/diameter.rb DELETED
@@ -1,2 +0,0 @@
1
- require 'diameter/stack'
2
- require 'diameter/message'