quaff 0.5.4 → 0.6.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 +7 -0
- data/lib/auth.rb +1 -1
- data/lib/call.rb +109 -23
- data/lib/endpoint.rb +106 -59
- data/lib/sip_parser.rb +3 -3
- data/lib/sources.rb +5 -12
- data/lib/utils.rb +1 -1
- metadata +17 -25
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 8d866d33ec2df619a80a00ee7aaaf04d70643370
|
4
|
+
data.tar.gz: f321221c8da956aef23e74104f1fd48abdd2dc02
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 761d0fc337cf7e29d4e3c10b1c83e126cb9f95e750312f08f5cd37f21205fb01dd953bb51b6c87370d9f2f10cfb565895b9e626fd9fea42fa34be71b8f700c27
|
7
|
+
data.tar.gz: edccac0984f874d1590efdf2ec8bbf6e9142d9ffdd90531fa11f2ee40f3c19887aa38cf14fd68ba7d2c30e0be64fbb78e22dfa43e35092f34fbafa6926e214f7
|
data/lib/auth.rb
CHANGED
data/lib/call.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# -*- coding: us-ascii -*-
|
2
2
|
require 'securerandom'
|
3
|
+
require 'timeout'
|
3
4
|
require_relative './utils.rb'
|
4
5
|
require_relative './sources.rb'
|
5
6
|
require_relative './auth.rb'
|
@@ -29,7 +30,7 @@ class Call
|
|
29
30
|
def initialize(cxn,
|
30
31
|
cid,
|
31
32
|
instance_id=nil,
|
32
|
-
uri=
|
33
|
+
uri=nil,
|
33
34
|
destination=nil,
|
34
35
|
target_uri=nil)
|
35
36
|
@cxn = cxn
|
@@ -37,14 +38,11 @@ class Call
|
|
37
38
|
@retrans = nil
|
38
39
|
@t1, @t2 = 0.5, 32
|
39
40
|
@instance_id = instance_id
|
40
|
-
set_default_headers cid, uri, target_uri
|
41
|
-
end
|
42
|
-
|
43
|
-
def change_cid cid
|
44
41
|
@cid = cid
|
45
|
-
|
42
|
+
set_default_headers cid, uri, target_uri
|
46
43
|
end
|
47
44
|
|
45
|
+
# Changes the branch parameter if the Via header, creating a new transaction
|
48
46
|
def update_branch via_hdr=nil
|
49
47
|
via_hdr ||= get_new_via_hdr
|
50
48
|
@last_Via = via_hdr
|
@@ -56,10 +54,6 @@ class Call
|
|
56
54
|
"SIP/2.0/#{@cxn.transport} #{Quaff::Utils.local_ip}:#{@cxn.local_port};rport;branch=#{Quaff::Utils::new_branch}"
|
57
55
|
end
|
58
56
|
|
59
|
-
def create_dialog msg
|
60
|
-
set_callee msg.first_header("Contact")
|
61
|
-
end
|
62
|
-
|
63
57
|
def set_callee uri
|
64
58
|
if /<(.*?)>/ =~ uri
|
65
59
|
uri = $1
|
@@ -67,7 +61,39 @@ class Call
|
|
67
61
|
|
68
62
|
@sip_destination = "#{uri}"
|
69
63
|
end
|
64
|
+
|
65
|
+
def create_dialog msg
|
66
|
+
if @in_dialog
|
67
|
+
return
|
68
|
+
end
|
69
|
+
|
70
|
+
@in_dialog = true
|
71
|
+
|
72
|
+
uri = msg.first_header("Contact")
|
73
|
+
|
74
|
+
if /<(.*?)>/ =~ uri
|
75
|
+
uri = $1
|
76
|
+
end
|
77
|
+
|
78
|
+
@sip_destination = uri
|
79
|
+
|
80
|
+
unless msg.all_headers("Record-Route").nil?
|
81
|
+
if msg.type == :request
|
82
|
+
@routeset = msg.all_headers("Record-Route")
|
83
|
+
else
|
84
|
+
@routeset = msg.all_headers("Record-Route").reverse
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
70
89
|
|
90
|
+
# Sets the Source where messages in this call should be sent to by
|
91
|
+
# default.
|
92
|
+
#
|
93
|
+
# Options:
|
94
|
+
# :recv_from_this - if true, also listens for any incoming
|
95
|
+
# messages over this source's connection. (This is only
|
96
|
+
# meaningful for connection-oriented transports.)
|
71
97
|
def setdest source, options={}
|
72
98
|
@src = source
|
73
99
|
if options[:recv_from_this] and source.sock
|
@@ -78,7 +104,7 @@ class Call
|
|
78
104
|
def recv_request(method, dialog_creating=true)
|
79
105
|
begin
|
80
106
|
msg = recv_something
|
81
|
-
rescue
|
107
|
+
rescue Timeout::Error
|
82
108
|
raise "#{ @uri } timed out waiting for #{ method }"
|
83
109
|
end
|
84
110
|
|
@@ -97,20 +123,85 @@ class Call
|
|
97
123
|
end
|
98
124
|
|
99
125
|
if dialog_creating
|
100
|
-
|
126
|
+
create_dialog msg
|
127
|
+
end
|
128
|
+
msg
|
129
|
+
end
|
101
130
|
|
102
|
-
|
103
|
-
|
104
|
-
|
131
|
+
# Waits until the next message comes in, and handles it if it is one
|
132
|
+
# of possible_messages.
|
133
|
+
#
|
134
|
+
# possible_messages is a list of things that can be received.
|
135
|
+
# Elements can be:
|
136
|
+
# * a string representing the SIP method, e.g. "INVITE"
|
137
|
+
# * a number representing the SIP status code, e.g. 200
|
138
|
+
# * a two-item list, containing one of the above and a boolean
|
139
|
+
# value, which indicates whether this message is dialog-creating. by
|
140
|
+
# default, requests are assumed to be dialog-creating and responses
|
141
|
+
# are not.
|
142
|
+
#
|
143
|
+
# For example, ["INVITE", 301, ["ACK", false], [200, true]] is a
|
144
|
+
# valid value for possible_messages.
|
145
|
+
def recv_any_of(possible_messages)
|
146
|
+
begin
|
147
|
+
msg = recv_something
|
148
|
+
rescue Timeout::Error
|
149
|
+
raise "#{ @uri } timed out waiting for one of these: #{possible_messages}"
|
150
|
+
end
|
151
|
+
|
152
|
+
found_match = false
|
153
|
+
dialog_creating = nil
|
154
|
+
|
155
|
+
possible_messages.each do
|
156
|
+
| what, this_dialog_creating |
|
157
|
+
type = if (what.class == String) then :request else :response end
|
158
|
+
if this_dialog_creating.nil?
|
159
|
+
this_dialog_creating = (type == :request)
|
160
|
+
end
|
161
|
+
|
162
|
+
found_match =
|
163
|
+
if type == :request
|
164
|
+
msg.type == :request and what == msg.method
|
165
|
+
else
|
166
|
+
msg.type == :response and what == msg.status_code
|
167
|
+
end
|
168
|
+
|
169
|
+
if found_match
|
170
|
+
dialog_creating = this_dialog_creating
|
171
|
+
break
|
105
172
|
end
|
106
173
|
end
|
174
|
+
|
175
|
+
unless found_match
|
176
|
+
raise((msg.to_s || "Message is nil!"))
|
177
|
+
end
|
178
|
+
|
179
|
+
if msg.type == :request
|
180
|
+
unless @has_To_tag
|
181
|
+
@has_To_tag = true
|
182
|
+
tospec = ToSpec.new
|
183
|
+
tospec.parse(msg.header("To"))
|
184
|
+
tospec.params['tag'] = generate_random_tag
|
185
|
+
@last_To = tospec.to_s
|
186
|
+
@last_From = msg.header("From")
|
187
|
+
end
|
188
|
+
else
|
189
|
+
if @in_dialog
|
190
|
+
@has_To_tag = true
|
191
|
+
@last_To = msg.header("To")
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
if dialog_creating
|
196
|
+
create_dialog msg
|
197
|
+
end
|
107
198
|
msg
|
108
199
|
end
|
109
200
|
|
110
201
|
def recv_response(code, dialog_creating=false)
|
111
202
|
begin
|
112
203
|
msg = recv_something
|
113
|
-
rescue
|
204
|
+
rescue Timeout::Error
|
114
205
|
raise "#{ @uri } timed out waiting for #{ code }"
|
115
206
|
end
|
116
207
|
unless msg.type == :response \
|
@@ -119,11 +210,7 @@ class Call
|
|
119
210
|
end
|
120
211
|
|
121
212
|
if dialog_creating
|
122
|
-
|
123
|
-
set_callee msg.first_header("Contact")
|
124
|
-
unless msg.all_headers("Record-Route").nil?
|
125
|
-
@routeset = msg.all_headers("Record-Route").reverse
|
126
|
-
end
|
213
|
+
create_dialog msg
|
127
214
|
end
|
128
215
|
|
129
216
|
if @in_dialog
|
@@ -238,14 +325,13 @@ class Call
|
|
238
325
|
|
239
326
|
def set_default_headers cid, uri, target_uri
|
240
327
|
@cseq_number = 1
|
241
|
-
change_cid cid
|
242
328
|
@uri = uri
|
243
329
|
@last_From = "<#{uri}>;tag=" + generate_random_tag
|
244
330
|
@in_dialog = false
|
245
331
|
@has_To_tag = false
|
246
332
|
update_branch
|
247
333
|
@last_To = "<#{target_uri}>"
|
248
|
-
|
334
|
+
@sip_destination = target_uri
|
249
335
|
@routeset = []
|
250
336
|
end
|
251
337
|
|
data/lib/endpoint.rb
CHANGED
@@ -3,7 +3,7 @@ require 'socket'
|
|
3
3
|
require 'thread'
|
4
4
|
require 'timeout'
|
5
5
|
require 'resolv'
|
6
|
-
require '
|
6
|
+
require 'securerandom'
|
7
7
|
#require 'milenage'
|
8
8
|
require_relative './sip_parser.rb'
|
9
9
|
require_relative './sources.rb'
|
@@ -11,53 +11,75 @@ require_relative './sources.rb'
|
|
11
11
|
module Quaff
|
12
12
|
class BaseEndpoint
|
13
13
|
attr_accessor :msg_trace, :uri, :sdp_port, :sdp_socket, :instance_id
|
14
|
-
attr_reader :msg_log
|
14
|
+
attr_reader :msg_log, :local_port
|
15
15
|
|
16
|
+
# Creates an SDP socket bound to an ephemeral port
|
16
17
|
def setup_sdp
|
17
18
|
@sdp_socket = UDPSocket.new
|
18
19
|
@sdp_socket.bind('0.0.0.0', 0)
|
19
20
|
@sdp_port = @sdp_socket.addr[1]
|
20
21
|
end
|
21
22
|
|
22
|
-
|
23
|
-
|
24
|
-
end
|
25
|
-
|
23
|
+
# Cleans up the endpoint - designed to be overriden by
|
24
|
+
# per-transport subclasses
|
26
25
|
def terminate
|
27
26
|
end
|
28
27
|
|
28
|
+
# Adds a socket connection to another UA - designed to be
|
29
|
+
# overriden by per-transport subclasses
|
29
30
|
def add_sock sock
|
30
31
|
end
|
31
32
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
33
|
+
# Retrieves the next unhandled call for this endpoint and returns
|
34
|
+
# a +Call+ object representing it
|
35
|
+
def incoming_call
|
36
|
+
begin
|
37
|
+
call_id = get_new_call_id
|
38
|
+
rescue Timeout::Error
|
39
|
+
raise "#{ @uri } timed out waiting for new incoming call"
|
40
|
+
end
|
41
|
+
|
42
|
+
puts "Call-Id for endpoint on #{@local_port} is #{call_id}" if @msg_trace
|
43
|
+
Call.new(self, call_id, @instance_id, @uri)
|
36
44
|
end
|
37
45
|
|
46
|
+
# Creates a +Call+ object representing a new outbound call
|
38
47
|
def outgoing_call to_uri
|
39
48
|
call_id = generate_call_id
|
40
|
-
puts "Call-Id for endpoint on #{@
|
49
|
+
puts "Call-Id for endpoint on #{@local_port} is #{call_id}" if @msg_trace
|
41
50
|
Call.new(self, call_id, @instance_id, @uri, @outbound_connection, to_uri)
|
42
51
|
end
|
43
52
|
|
44
|
-
|
53
|
+
# Not yet ready for use
|
54
|
+
def create_client(uri, username, password, outbound_proxy, outbound_port=5060) # :nodoc:
|
45
55
|
end
|
46
56
|
|
47
|
-
|
48
|
-
|
57
|
+
# Not yet ready for use
|
58
|
+
def create_server(uri, local_port=5060, outbound_proxy=nil, outbound_port=5060) # :nodoc:
|
49
59
|
end
|
50
60
|
|
51
|
-
|
61
|
+
# Not yet ready for use
|
62
|
+
def create_aka_client(uri, username, key, op, outbound_proxy, outbound_port=5060) # :nodoc:
|
52
63
|
end
|
53
64
|
|
65
|
+
# Constructs a new endpoint
|
66
|
+
# Params:
|
67
|
+
# +uri+:: The SIP URI of this endpoint
|
68
|
+
# +username+:: The authentication username of this endpoint
|
69
|
+
# +password+:: The authentication password of this endpoint
|
70
|
+
# +local_port+:: The port this endpoint should bind to. Use
|
71
|
+
# ':anyport' to bind to an ephemeral port.
|
72
|
+
# +outbound_proxy+:: The outbound proxy where all requests should
|
73
|
+
# be directed. Optional, but it only makes sense to omit it when
|
74
|
+
# Quaff is emulating a server rather than a client.
|
75
|
+
# +outbound_port+:: The port of the outbound proxy
|
54
76
|
def initialize(uri, username, password, local_port, outbound_proxy=nil, outbound_port=5060)
|
55
77
|
@msg_log = Array.new
|
56
78
|
@uri = uri
|
57
79
|
@resolver = Resolv::DNS.new
|
58
80
|
@username = username
|
59
81
|
@password = password
|
60
|
-
@
|
82
|
+
@local_port = local_port
|
61
83
|
initialize_connection
|
62
84
|
if outbound_proxy
|
63
85
|
@outbound_connection = new_connection(outbound_proxy, outbound_port)
|
@@ -66,40 +88,26 @@ module Quaff
|
|
66
88
|
start
|
67
89
|
end
|
68
90
|
|
69
|
-
def
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
def add_call_id cid
|
74
|
-
@messages[cid] ||= Queue.new
|
75
|
-
end
|
76
|
-
|
77
|
-
def get_new_call_id time_limit=30
|
78
|
-
Timeout::timeout(time_limit) { @call_ids.deq }
|
79
|
-
end
|
80
|
-
|
81
|
-
def get_new_message(cid, time_limit=30)
|
82
|
-
Timeout::timeout(time_limit) { @messages[cid].deq }
|
83
|
-
end
|
84
|
-
|
85
|
-
def mark_call_dead(cid)
|
86
|
-
@messages.delete cid
|
87
|
-
now = Time.now
|
88
|
-
@dead_calls[cid] = now + 30
|
89
|
-
@dead_calls = @dead_calls.keep_if {|k, v| v > now}
|
90
|
-
end
|
91
|
-
|
92
|
-
def send_msg(data, source)
|
93
|
-
@msg_log.push "Endpoint on #{@lport} sending:\n\n#{data.strip}\n\nto #{source.inspect}"
|
94
|
-
puts "Endpoint on #{@lport} sending #{data} to #{source.inspect}" if @msg_trace
|
91
|
+
def send_msg(data, source) # :nodoc:
|
92
|
+
@msg_log.push "Endpoint on #{@local_port} sending:\n\n#{data.strip}\n\nto #{source.inspect}"
|
93
|
+
puts "Endpoint on #{@local_port} sending #{data} to #{source.inspect}" if @msg_trace
|
95
94
|
source.send_msg(@cxn, data)
|
96
95
|
end
|
97
96
|
|
98
|
-
|
97
|
+
# Not yet ready for use
|
98
|
+
def set_aka_credentials key, op # :nodoc:
|
99
99
|
@kernel = Milenage.Kernel key
|
100
100
|
@kernel.op = op
|
101
101
|
end
|
102
102
|
|
103
|
+
# Utility method - handles a REGISTER/200 or
|
104
|
+
# REGISTER/401/REGISTER/200 flow to authenticate the subscriber.
|
105
|
+
# Currently only supports SIP Digest authentication. Re-REGISTERs
|
106
|
+
# are not handled; if you need long-running endpoints you should
|
107
|
+
# create a thread to re-REGISTER them yourself.
|
108
|
+
#
|
109
|
+
# Returns the +Message+ representing the 200 OK, or throws an
|
110
|
+
# exception on failure to authenticate successfully.
|
103
111
|
def register expires="3600", aka=false
|
104
112
|
@reg_call ||= outgoing_call(@uri)
|
105
113
|
auth_hdr = Quaff::Auth.gen_empty_auth_header @username
|
@@ -125,7 +133,42 @@ module Quaff
|
|
125
133
|
register 0
|
126
134
|
end
|
127
135
|
|
136
|
+
# Only designed for use by the Call class. Retrieves a new message
|
137
|
+
# on a particular call. If no new message has been received,
|
138
|
+
# blocks for up to time_limit seconds waiting for one. If nothing
|
139
|
+
# arrives, raises a TimeoutError.
|
140
|
+
def get_new_message(cid, time_limit=30) # :nodoc:
|
141
|
+
Timeout::timeout(time_limit) { @messages[cid].deq }
|
142
|
+
end
|
143
|
+
|
144
|
+
|
145
|
+
|
146
|
+
# Flags that a particular call has ended, and any more messages
|
147
|
+
# using it shold be ignored.
|
148
|
+
def mark_call_dead(cid)
|
149
|
+
@messages.delete cid
|
150
|
+
now = Time.now
|
151
|
+
@dead_calls[cid] = now + 30
|
152
|
+
@dead_calls = @dead_calls.keep_if {|k, v| v > now}
|
153
|
+
end
|
128
154
|
private
|
155
|
+
|
156
|
+
# Creates a random Call-ID
|
157
|
+
def generate_call_id
|
158
|
+
call_id = SecureRandom::hex
|
159
|
+
add_call_id call_id
|
160
|
+
return call_id
|
161
|
+
end
|
162
|
+
|
163
|
+
def get_new_call_id time_limit=30
|
164
|
+
Timeout::timeout(time_limit) { @call_ids.deq }
|
165
|
+
end
|
166
|
+
|
167
|
+
# Sets up the internal structures needed to handle calls for a new Call-ID.
|
168
|
+
def add_call_id cid
|
169
|
+
@messages[cid] ||= Queue.new
|
170
|
+
end
|
171
|
+
|
129
172
|
def initialize_queues
|
130
173
|
@messages = {}
|
131
174
|
@call_ids = Queue.new
|
@@ -142,8 +185,8 @@ module Quaff
|
|
142
185
|
end
|
143
186
|
|
144
187
|
def queue_msg(msg, source)
|
145
|
-
@msg_log.push "Endpoint on #{@
|
146
|
-
puts "Endpoint on #{@
|
188
|
+
@msg_log.push "Endpoint on #{@local_port} received:\n\n#{msg.to_s.strip}\n\nfrom #{source.inspect}"
|
189
|
+
puts "Endpoint on #{@local_port} received #{msg} from
|
147
190
|
##{source.inspect}" if @msg_trace
|
148
191
|
msg.source = source
|
149
192
|
cid = @parser.message_identifier msg
|
@@ -160,17 +203,6 @@ module Quaff
|
|
160
203
|
class TCPSIPEndpoint < BaseEndpoint
|
161
204
|
attr_accessor :sockets
|
162
205
|
|
163
|
-
def initialize_connection
|
164
|
-
if @lport != :anyport
|
165
|
-
@cxn = TCPServer.new(@lport)
|
166
|
-
else
|
167
|
-
@cxn = TCPServer.new(0)
|
168
|
-
@lport = @cxn.addr[1]
|
169
|
-
end
|
170
|
-
@parser = SipParser.new
|
171
|
-
@sockets = []
|
172
|
-
end
|
173
|
-
|
174
206
|
def transport
|
175
207
|
"TCP"
|
176
208
|
end
|
@@ -194,7 +226,21 @@ module Quaff
|
|
194
226
|
|
195
227
|
|
196
228
|
alias_method :new_connection, :new_source
|
229
|
+
|
197
230
|
private
|
231
|
+
|
232
|
+
def initialize_connection
|
233
|
+
if @local_port != :anyport
|
234
|
+
@cxn = TCPServer.new(@local_port)
|
235
|
+
else
|
236
|
+
@cxn = TCPServer.new(0)
|
237
|
+
@local_port = @cxn.addr[1]
|
238
|
+
end
|
239
|
+
@parser = SipParser.new
|
240
|
+
@sockets = []
|
241
|
+
end
|
242
|
+
|
243
|
+
|
198
244
|
def recv_msg
|
199
245
|
select_response = IO.select(@sockets, [], [], 0) || [[]]
|
200
246
|
readable = select_response[0]
|
@@ -239,13 +285,14 @@ module Quaff
|
|
239
285
|
alias_method :new_connection, :new_source
|
240
286
|
|
241
287
|
private
|
288
|
+
|
242
289
|
def initialize_connection
|
243
290
|
@cxn = UDPSocket.new
|
244
|
-
if @
|
245
|
-
@cxn.bind('0.0.0.0', @
|
291
|
+
if @local_port != :anyport
|
292
|
+
@cxn.bind('0.0.0.0', @local_port)
|
246
293
|
else
|
247
294
|
@cxn.bind('0.0.0.0', 0)
|
248
|
-
@
|
295
|
+
@local_port = @cxn.addr[1]
|
249
296
|
end
|
250
297
|
@sockets = []
|
251
298
|
@parser = SipParser.new
|
data/lib/sip_parser.rb
CHANGED
@@ -4,7 +4,7 @@ require 'abnf'
|
|
4
4
|
require_relative './message.rb'
|
5
5
|
|
6
6
|
module Quaff
|
7
|
-
class SipParser
|
7
|
+
class SipParser # :nodoc:
|
8
8
|
attr_reader :state
|
9
9
|
def parse_start
|
10
10
|
@buf = ""
|
@@ -99,7 +99,7 @@ module Quaff
|
|
99
99
|
|
100
100
|
end
|
101
101
|
|
102
|
-
class ABNFSipParser
|
102
|
+
class ABNFSipParser # :nodoc:
|
103
103
|
include ABNF
|
104
104
|
|
105
105
|
# Rules
|
@@ -227,7 +227,7 @@ module Quaff
|
|
227
227
|
end
|
228
228
|
end
|
229
229
|
|
230
|
-
class ToSpec < ABNFSipParser
|
230
|
+
class ToSpec < ABNFSipParser # :nodoc:
|
231
231
|
attr_accessor :params, :uri, :displayname, :is_nameaddr
|
232
232
|
def initialize
|
233
233
|
super
|
data/lib/sources.rb
CHANGED
@@ -1,21 +1,15 @@
|
|
1
1
|
require 'socket'
|
2
2
|
module Quaff
|
3
|
+
# A Source is an abstraction representing an IP
|
4
|
+
# address/port/transport where a SIP message originates from or can
|
5
|
+
# be sent to. It allows users to abstract over TCP and UDP sockets.
|
3
6
|
class Source
|
4
|
-
|
5
|
-
@ip
|
6
|
-
end
|
7
|
-
|
8
|
-
def remote_port
|
9
|
-
@port
|
10
|
-
end
|
7
|
+
attr_reader :ip, :port, :transport, :sock
|
11
8
|
|
9
|
+
# Designed to be overriden by subclasses
|
12
10
|
def close cxn
|
13
11
|
end
|
14
12
|
|
15
|
-
def sock
|
16
|
-
nil
|
17
|
-
end
|
18
|
-
|
19
13
|
def to_s
|
20
14
|
"#{@ip}:#{@port} (#{@transport})"
|
21
15
|
end
|
@@ -41,7 +35,6 @@ module Quaff
|
|
41
35
|
|
42
36
|
|
43
37
|
class TCPSource < Source
|
44
|
-
attr_reader :sock
|
45
38
|
|
46
39
|
def initialize ip, port
|
47
40
|
@transport = "TCP"
|
data/lib/utils.rb
CHANGED
metadata
CHANGED
@@ -1,62 +1,55 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: quaff
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.6.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Rob Day
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date: 2014-
|
11
|
+
date: 2014-06-22 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: facter
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- -
|
17
|
+
- - '>='
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: 1.7.3
|
22
20
|
type: :runtime
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- -
|
24
|
+
- - '>='
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: 1.7.3
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: milenage
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
|
-
- -
|
31
|
+
- - '>='
|
36
32
|
- !ruby/object:Gem::Version
|
37
33
|
version: 0.1.0
|
38
34
|
type: :runtime
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
|
-
- -
|
38
|
+
- - '>='
|
44
39
|
- !ruby/object:Gem::Version
|
45
40
|
version: 0.1.0
|
46
41
|
- !ruby/object:Gem::Dependency
|
47
42
|
name: abnf-parsing
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
44
|
requirements:
|
51
|
-
- -
|
45
|
+
- - '>='
|
52
46
|
- !ruby/object:Gem::Version
|
53
47
|
version: 0.2.0
|
54
48
|
type: :runtime
|
55
49
|
prerelease: false
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
51
|
requirements:
|
59
|
-
- -
|
52
|
+
- - '>='
|
60
53
|
- !ruby/object:Gem::Version
|
61
54
|
version: 0.2.0
|
62
55
|
description: A Ruby library for writing SIP test scenarios
|
@@ -65,37 +58,36 @@ executables: []
|
|
65
58
|
extensions: []
|
66
59
|
extra_rdoc_files: []
|
67
60
|
files:
|
68
|
-
- lib/
|
61
|
+
- lib/call.rb
|
69
62
|
- lib/endpoint.rb
|
70
63
|
- lib/message.rb
|
71
|
-
- lib/
|
72
|
-
- lib/auth.rb
|
64
|
+
- lib/quaff.rb
|
73
65
|
- lib/sources.rb
|
66
|
+
- lib/utils.rb
|
74
67
|
- lib/sip_parser.rb
|
75
|
-
- lib/
|
68
|
+
- lib/auth.rb
|
76
69
|
homepage: http://github.com/rkday/quaff
|
77
70
|
licenses:
|
78
71
|
- GPL3
|
72
|
+
metadata: {}
|
79
73
|
post_install_message:
|
80
74
|
rdoc_options: []
|
81
75
|
require_paths:
|
82
76
|
- lib
|
83
77
|
required_ruby_version: !ruby/object:Gem::Requirement
|
84
|
-
none: false
|
85
78
|
requirements:
|
86
|
-
- -
|
79
|
+
- - '>='
|
87
80
|
- !ruby/object:Gem::Version
|
88
81
|
version: '0'
|
89
82
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
90
|
-
none: false
|
91
83
|
requirements:
|
92
|
-
- -
|
84
|
+
- - '>='
|
93
85
|
- !ruby/object:Gem::Version
|
94
86
|
version: '0'
|
95
87
|
requirements: []
|
96
88
|
rubyforge_project:
|
97
|
-
rubygems_version: 1.
|
89
|
+
rubygems_version: 2.1.11
|
98
90
|
signing_key:
|
99
|
-
specification_version:
|
91
|
+
specification_version: 4
|
100
92
|
summary: Quaff
|
101
93
|
test_files: []
|