quaff 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|