quaff 0.2.0 → 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.
- data/lib/call.rb +14 -23
- data/lib/endpoint.rb +57 -25
- data/lib/sip_parser.rb +4 -7
- data/lib/sources.rb +3 -3
- metadata +2 -2
data/lib/call.rb
CHANGED
@@ -31,12 +31,14 @@ class Call
|
|
31
31
|
destination=nil,
|
32
32
|
target_uri=nil)
|
33
33
|
@cxn = cxn
|
34
|
+
@cseq_number = 1
|
34
35
|
change_cid cid
|
35
36
|
@uri = uri
|
36
37
|
@retrans = nil
|
37
38
|
@t1, @t2 = 0.5, 32
|
38
39
|
@last_From = "<#{uri}>"
|
39
40
|
update_branch
|
41
|
+
@last_To = "<#{target_uri}>"
|
40
42
|
setdest(destination, recv_from_this: true) if destination
|
41
43
|
set_callee target_uri if target_uri
|
42
44
|
@routeset = []
|
@@ -65,7 +67,6 @@ class Call
|
|
65
67
|
end
|
66
68
|
|
67
69
|
@sip_destination = "#{uri}"
|
68
|
-
@last_To = "<#{uri}>"
|
69
70
|
end
|
70
71
|
|
71
72
|
def setdest source, options={}
|
@@ -133,25 +134,6 @@ class Call
|
|
133
134
|
return TCPSource.new sock
|
134
135
|
end
|
135
136
|
|
136
|
-
def register username=@username, password=@password, expires="3600"
|
137
|
-
@username, @password = username, password
|
138
|
-
set_callee(@uri)
|
139
|
-
send_request("REGISTER", "", { "Expires" => expires.to_s })
|
140
|
-
response_data = recv_response("401|200")
|
141
|
-
if response_data['message'].status_code == "401"
|
142
|
-
send_request("ACK")
|
143
|
-
auth_hdr = Quaff::Auth.gen_auth_header response_data['message'].header("WWW-Authenticate"), username, password, "REGISTER", @uri
|
144
|
-
update_branch
|
145
|
-
send_request("REGISTER", "", {"Authorization" => auth_hdr, "Expires" => expires.to_s, "CSeq" => "2 REGISTER"})
|
146
|
-
recv_response("200")
|
147
|
-
end
|
148
|
-
return true
|
149
|
-
end
|
150
|
-
|
151
|
-
def unregister
|
152
|
-
register @username, @password, 0
|
153
|
-
end
|
154
|
-
|
155
137
|
private
|
156
138
|
def recv_something
|
157
139
|
data = @cxn.get_new_message @cid
|
@@ -165,14 +147,23 @@ class Call
|
|
165
147
|
data
|
166
148
|
end
|
167
149
|
|
168
|
-
|
150
|
+
def calculate_cseq type, method
|
151
|
+
if (type == :response)
|
152
|
+
@last_CSeq.to_s
|
153
|
+
elsif (method == "ACK")
|
154
|
+
@last_CSeq.to_s
|
155
|
+
else
|
156
|
+
@cseq_number = @cseq_number + 1
|
157
|
+
"#{@cseq_number} #{method}"
|
158
|
+
end
|
159
|
+
end
|
169
160
|
|
170
161
|
def build_message headers, body, type, method=nil, code=nil, phrase=nil
|
171
162
|
defaults = {
|
172
163
|
"From" => @last_From,
|
173
164
|
"To" => @last_To,
|
174
165
|
"Call-ID" => @cid,
|
175
|
-
"CSeq" => (type
|
166
|
+
"CSeq" => calculate_cseq(type, method),
|
176
167
|
"Via" => @last_Via,
|
177
168
|
"Max-Forwards" => "70",
|
178
169
|
"Content-Length" => "0",
|
@@ -194,7 +185,7 @@ class Call
|
|
194
185
|
end
|
195
186
|
|
196
187
|
def send_something(msg, retrans)
|
197
|
-
@cxn.
|
188
|
+
@cxn.send_msg(msg, @src)
|
198
189
|
if retrans and (@transport == "UDP") then
|
199
190
|
@retrans = true
|
200
191
|
Thread.new do
|
data/lib/endpoint.rb
CHANGED
@@ -2,12 +2,17 @@
|
|
2
2
|
require 'socket'
|
3
3
|
require 'thread'
|
4
4
|
require 'timeout'
|
5
|
+
require 'digest/md5'
|
5
6
|
require_relative './sip_parser.rb'
|
6
7
|
require_relative './sources.rb'
|
7
8
|
|
8
9
|
module Quaff
|
9
|
-
class BaseEndpoint
|
10
|
-
attr_accessor :msg_trace
|
10
|
+
class BaseEndpoint
|
11
|
+
attr_accessor :msg_trace, :uri
|
12
|
+
|
13
|
+
def generate_call_id
|
14
|
+
digest = Digest::MD5.hexdigest(rand(60000).to_s)
|
15
|
+
end
|
11
16
|
|
12
17
|
def terminate
|
13
18
|
end
|
@@ -15,17 +20,29 @@ class BaseEndpoint
|
|
15
20
|
def add_sock sock
|
16
21
|
end
|
17
22
|
|
18
|
-
def
|
23
|
+
def incoming_call *args
|
19
24
|
call_id ||= get_new_call_id
|
20
25
|
puts "Call-Id for endpoint on #{@lport} is #{call_id}" if @msg_trace
|
21
26
|
Call.new(self, call_id, *args)
|
22
27
|
end
|
23
28
|
|
24
|
-
def
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
+
def outgoing_call to_uri
|
30
|
+
call_id = generate_call_id
|
31
|
+
puts "Call-Id for endpoint on #{@lport} is #{call_id}" if @msg_trace
|
32
|
+
Call.new(self, call_id, @uri, @outbound_connection, to_uri)
|
33
|
+
end
|
34
|
+
|
35
|
+
def initialize(uri, username, password, local_port, outbound_proxy=nil, outbound_port=5060)
|
36
|
+
@uri = uri
|
37
|
+
@username = username
|
38
|
+
@password = password
|
39
|
+
@lport = local_port
|
40
|
+
initialize_connection @lport
|
41
|
+
if outbound_proxy
|
42
|
+
@outbound_connection = new_connection(outbound_proxy, outbound_port)
|
43
|
+
end
|
44
|
+
initialize_queues
|
45
|
+
start
|
29
46
|
end
|
30
47
|
|
31
48
|
def local_port
|
@@ -36,12 +53,12 @@ class BaseEndpoint
|
|
36
53
|
@messages[cid] ||= Queue.new
|
37
54
|
end
|
38
55
|
|
39
|
-
def get_new_call_id time_limit=
|
56
|
+
def get_new_call_id time_limit=30
|
40
57
|
Timeout::timeout(time_limit) { @call_ids.deq }
|
41
58
|
end
|
42
59
|
|
43
|
-
def get_new_message(cid, time_limit=
|
44
|
-
|
60
|
+
def get_new_message(cid, time_limit=30)
|
61
|
+
Timeout::timeout(time_limit) { @messages[cid].deq }
|
45
62
|
end
|
46
63
|
|
47
64
|
def mark_call_dead(cid)
|
@@ -51,9 +68,27 @@ class BaseEndpoint
|
|
51
68
|
@dead_calls = @dead_calls.keep_if {|k, v| v > now}
|
52
69
|
end
|
53
70
|
|
54
|
-
def
|
71
|
+
def send_msg(data, source)
|
55
72
|
puts "Endpoint on #{@lport} sending #{data} to #{source.inspect}" if @msg_trace
|
56
|
-
source.
|
73
|
+
source.send_msg(@cxn, data)
|
74
|
+
end
|
75
|
+
|
76
|
+
def register expires="3600"
|
77
|
+
call = outgoing_call(@uri)
|
78
|
+
call.send_request("REGISTER", "", { "Expires" => expires.to_s })
|
79
|
+
response_data = call.recv_response("401|200")
|
80
|
+
if response_data['message'].status_code == "401"
|
81
|
+
call.send_request("ACK")
|
82
|
+
auth_hdr = Quaff::Auth.gen_auth_header response_data['message'].header("WWW-Authenticate"), @username, @password, "REGISTER", @uri
|
83
|
+
call.update_branch
|
84
|
+
call.send_request("REGISTER", "", {"Authorization" => auth_hdr, "Expires" => expires.to_s, "CSeq" => "2 REGISTER"})
|
85
|
+
call.recv_response("200")
|
86
|
+
end
|
87
|
+
return true
|
88
|
+
end
|
89
|
+
|
90
|
+
def unregister
|
91
|
+
register 0
|
57
92
|
end
|
58
93
|
|
59
94
|
private
|
@@ -85,9 +120,9 @@ class BaseEndpoint
|
|
85
120
|
end
|
86
121
|
end
|
87
122
|
|
88
|
-
end
|
123
|
+
end
|
89
124
|
|
90
|
-
class TCPSIPEndpoint < BaseEndpoint
|
125
|
+
class TCPSIPEndpoint < BaseEndpoint
|
91
126
|
attr_accessor :sockets
|
92
127
|
|
93
128
|
def initialize_connection(lport)
|
@@ -139,16 +174,15 @@ class TCPSIPEndpoint < BaseEndpoint
|
|
139
174
|
def recv_msg_from_sock(sock)
|
140
175
|
@parser.parse_start
|
141
176
|
msg = nil
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
177
|
+
while msg.nil? and not sock.closed? do
|
178
|
+
line = sock.gets
|
179
|
+
msg = @parser.parse_partial line
|
180
|
+
end
|
146
181
|
queue_msg msg, TCPSourceFromSocket.new(sock)
|
147
182
|
end
|
183
|
+
end
|
148
184
|
|
149
|
-
|
150
|
-
|
151
|
-
class UDPSIPEndpoint < BaseEndpoint
|
185
|
+
class UDPSIPEndpoint < BaseEndpoint
|
152
186
|
|
153
187
|
def transport
|
154
188
|
"UDP"
|
@@ -174,8 +208,6 @@ class UDPSIPEndpoint < BaseEndpoint
|
|
174
208
|
msg = @parser.parse_partial(data)
|
175
209
|
queue_msg msg, UDPSourceFromAddrinfo.new(addrinfo) unless msg.nil?
|
176
210
|
end
|
177
|
-
|
178
|
-
|
179
|
-
end
|
211
|
+
end
|
180
212
|
|
181
213
|
end
|
data/lib/sip_parser.rb
CHANGED
@@ -64,11 +64,6 @@ module Quaff
|
|
64
64
|
if line.start_with? " "
|
65
65
|
@msg.headers[@cur_hdr][-1] += " "
|
66
66
|
@msg.headers[@cur_hdr][-1] += line.lstrip
|
67
|
-
if $1 == "Content-Length"
|
68
|
-
@state = :got_content_length
|
69
|
-
else
|
70
|
-
@state = :middle_of_headers
|
71
|
-
end
|
72
67
|
elsif line.include? ":"
|
73
68
|
parts = line.split ":", 2
|
74
69
|
header_name, header_value = parts[0].rstrip, parts[1].lstrip
|
@@ -79,10 +74,12 @@ module Quaff
|
|
79
74
|
@state = :got_content_length
|
80
75
|
@msg.headers[header_name] = [header_value]
|
81
76
|
else
|
82
|
-
@state
|
77
|
+
if (@state != :got_content_length)
|
78
|
+
@state = :middle_of_headers
|
79
|
+
end
|
83
80
|
end
|
84
81
|
elsif line == ""
|
85
|
-
if @state == :got_content_length and @msg.header("Content-Length").to_i > 0
|
82
|
+
if (@state == :got_content_length) and (@msg.header("Content-Length").to_i > 0)
|
86
83
|
@state = :parsing_body
|
87
84
|
else
|
88
85
|
@state = :done
|
data/lib/sources.rb
CHANGED
@@ -22,7 +22,7 @@ class UDPSource < Source
|
|
22
22
|
@ip, @port = ip, port
|
23
23
|
end
|
24
24
|
|
25
|
-
def
|
25
|
+
def send_msg cxn, data
|
26
26
|
cxn.send(data, 0, @ip, @port)
|
27
27
|
end
|
28
28
|
end
|
@@ -35,14 +35,14 @@ end
|
|
35
35
|
|
36
36
|
|
37
37
|
class TCPSource < Source
|
38
|
-
|
38
|
+
attr_reader :sock
|
39
39
|
|
40
40
|
def initialize ip, port
|
41
41
|
@sock = TCPSocket.new ip, port
|
42
42
|
@port, @ip = port, ip
|
43
43
|
end
|
44
44
|
|
45
|
-
def
|
45
|
+
def send_msg _, data
|
46
46
|
@sock.sendmsg data
|
47
47
|
end
|
48
48
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: quaff
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-12-05 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: facter
|