Class: Quaff::BaseEndpoint

Inherits:
Object
  • Object
show all
Defined in:
lib/endpoint.rb

Direct Known Subclasses

TCPSIPEndpoint, UDPSIPEndpoint

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(uri, username, password, local_port, outbound_proxy = nil, outbound_port = 5060) ⇒ BaseEndpoint

Constructs a new endpoint Params:

uri

The SIP URI of this endpoint

username

The authentication username of this endpoint

password

The authentication password of this endpoint

local_port

The port this endpoint should bind to. Use

‘:anyport’ to bind to an ephemeral port.

outbound_proxy

The outbound proxy where all requests should

be directed. Optional, but it only makes sense to omit it when Quaff is emulating a server rather than a client.

outbound_port

The port of the outbound proxy



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/endpoint.rb', line 102

def initialize(uri, username, password, local_port, outbound_proxy=nil, outbound_port=5060)
  @msg_log = Array.new
  @uri = uri
  @resolver = Resolv::DNS.new
  @username = username
  @password = password
  @local_host = Utils::local_ip
  @local_port = local_port
  initialize_connection
  if outbound_proxy
    @outbound_connection = new_connection(outbound_proxy, outbound_port)
  end
  @hashes = []
  @contact_params = {}
  @contact_uri_params = {"transport" => transport, "ob" => true}
  @terminated = false
  @local_hostname = Utils::local_ip
  initialize_queues
  start
end

Instance Attribute Details

#instance_idObject

Returns the value of attribute instance_id.



15
16
17
# File 'lib/endpoint.rb', line 15

def instance_id
  @instance_id
end

#local_hostnameObject

Returns the value of attribute local_hostname.



14
15
16
# File 'lib/endpoint.rb', line 14

def local_hostname
  @local_hostname
end

#local_portObject (readonly)

Returns the value of attribute local_port.



15
16
17
# File 'lib/endpoint.rb', line 15

def local_port
  @local_port
end

#msg_logObject (readonly)

Returns the value of attribute msg_log.



15
16
17
# File 'lib/endpoint.rb', line 15

def msg_log
  @msg_log
end

#msg_traceObject

Returns the value of attribute msg_trace.



14
15
16
# File 'lib/endpoint.rb', line 14

def msg_trace
  @msg_trace
end

#sdp_portObject

Returns the value of attribute sdp_port.



14
15
16
# File 'lib/endpoint.rb', line 14

def sdp_port
  @sdp_port
end

#sdp_socketObject

Returns the value of attribute sdp_socket.



14
15
16
# File 'lib/endpoint.rb', line 14

def sdp_socket
  @sdp_socket
end

#uriObject

Returns the value of attribute uri.



14
15
16
# File 'lib/endpoint.rb', line 14

def uri
  @uri
end

Instance Method Details

#add_contact_param(name, value) ⇒ Object



39
40
41
# File 'lib/endpoint.rb', line 39

def add_contact_param name, value
  @contact_params[name] = value
end

#add_contact_uri_param(name, value) ⇒ Object



43
44
45
# File 'lib/endpoint.rb', line 43

def add_contact_uri_param name, value
  @contact_uri_params[name] = value
end

#add_sock(sock) ⇒ Object

Adds a socket connection to another UA - designed to be overriden by per-transport subclasses



36
37
# File 'lib/endpoint.rb', line 36

def add_sock sock
end

#contact_headerObject



123
124
125
126
127
# File 'lib/endpoint.rb', line 123

def contact_header
  param_str = Utils.paramhash_to_str(@contact_params)
  uri_param_str = Utils.paramhash_to_str(@contact_uri_params)
  "<sip:quaff@#{@local_hostname}:#{@local_port}#{uri_param_str}>#{param_str}"
end

#create_aka_client(uri, username, key, op, outbound_proxy, outbound_port = 5060) ⇒ Object

Not yet ready for use



88
89
# File 'lib/endpoint.rb', line 88

def create_aka_client(uri, username, key, op, outbound_proxy, outbound_port=5060) # :nodoc:
end

#create_client(uri, username, password, outbound_proxy, outbound_port = 5060) ⇒ Object

Not yet ready for use



80
81
# File 'lib/endpoint.rb', line 80

def create_client(uri, username, password, outbound_proxy, outbound_port=5060) # :nodoc:
end

#create_server(uri, local_port = 5060, outbound_proxy = nil, outbound_port = 5060) ⇒ Object

Not yet ready for use



84
85
# File 'lib/endpoint.rb', line 84

def create_server(uri, local_port=5060, outbound_proxy=nil, outbound_port=5060) # :nodoc:
end

#get_new_message(cid, time_limit = 30) ⇒ Object

Only designed for use by the Call class. Retrieves a new message on a particular call. If no new message has been received, blocks for up to time_limit seconds waiting for one. If nothing arrives, raises a TimeoutError.



178
179
180
# File 'lib/endpoint.rb', line 178

def get_new_message(cid, time_limit=30) # :nodoc:
  Timeout::timeout(time_limit) { @messages[cid].deq }
end

#incoming_callObject

Retrieves the next unhandled call for this endpoint and returns a Call object representing it



61
62
63
64
65
66
67
68
69
70
# File 'lib/endpoint.rb', line 61

def incoming_call
  begin
    call_id = get_new_call_id
  rescue Timeout::Error
    raise "#{ @uri } timed out waiting for new incoming call"
  end

  puts "Call-Id for endpoint on #{@local_port} is #{call_id}" if @msg_trace
  Call.new(self, call_id, @instance_id, @uri)
end

#mark_call_dead(cid) ⇒ Object

Flags that a particular call has ended, and any more messages using it shold be ignored.



186
187
188
189
190
191
# File 'lib/endpoint.rb', line 186

def mark_call_dead(cid)
    @messages.delete cid
    now = Time.now
    @dead_calls[cid] = now + 30
    @dead_calls = @dead_calls.keep_if {|k, v| v > now}
end

#outgoing_call(to_uri) ⇒ Object

Creates a Call object representing a new outbound call



73
74
75
76
77
# File 'lib/endpoint.rb', line 73

def outgoing_call to_uri
  call_id = generate_call_id
  puts "Call-Id for endpoint on #{@local_port} is #{call_id}" if @msg_trace
  Call.new(self, call_id, @instance_id, @uri, @outbound_connection, to_uri)
end

#register(expires = "3600", aka = false) ⇒ Object

Utility method - handles a REGISTER/200 or REGISTER/401/REGISTER/200 flow to authenticate the subscriber. Currently only supports SIP Digest authentication. Re-REGISTERs are not handled; if you need long-running endpoints you should create a thread to re-REGISTER them yourself.

Returns the Message representing the 200 OK, or throws an exception on failure to authenticate successfully.



149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/endpoint.rb', line 149

def register expires="3600", aka=false
  @reg_call ||= outgoing_call(@uri)
  auth_hdr = Quaff::Auth.gen_empty_auth_header @username
  @reg_call.update_branch
  @reg_call.send_request("REGISTER", "", {"Authorization" =>  auth_hdr, "Expires" => expires.to_s})
  response_data = @reg_call.recv_response("401|200")
  if response_data.status_code == "401"
    if aka
      rand = Quaff::Auth.extract_rand response_data.header("WWW-Authenticate")
      password = @kernel.f3 rand
    else
      password = @password
    end
    auth_hdr = Quaff::Auth.gen_auth_header response_data.header("WWW-Authenticate"), @username, @password, "REGISTER", @uri
    @reg_call.update_branch
    @reg_call.send_request("REGISTER", "", {"Authorization" =>  auth_hdr, "Expires" => expires.to_s})
    response_data = @reg_call.recv_response("200")
  end
  return response_data # always the 200 OK
end

#remove_contact_param(name) ⇒ Object



47
48
49
# File 'lib/endpoint.rb', line 47

def remove_contact_param name
  @contact_params.delete name
end

#remove_contact_uri_param(name) ⇒ Object



51
52
53
# File 'lib/endpoint.rb', line 51

def remove_contact_uri_param name
  @contact_uri_params.delete name
end

#send_msg(data, source) ⇒ Object

:nodoc:



129
130
131
132
133
# File 'lib/endpoint.rb', line 129

def send_msg(data, source) # :nodoc:
  @msg_log.push "Endpoint on #{@local_port} sending:\n\n#{data.strip}\n\nto #{source.inspect}"
  puts "Endpoint on #{@local_port} sending #{data} to #{source.inspect}" if @msg_trace
    source.send_msg(@cxn, data)
end

#set_aka_credentials(key, op) ⇒ Object

Not yet ready for use



136
137
138
139
# File 'lib/endpoint.rb', line 136

def set_aka_credentials key, op # :nodoc:
  @kernel = Milenage.Kernel key
  @kernel.op = op
end

#setup_sdpObject

Creates an SDP socket bound to an ephemeral port



18
19
20
21
22
# File 'lib/endpoint.rb', line 18

def setup_sdp
  @sdp_socket = UDPSocket.new
  @sdp_socket.bind('0.0.0.0', 0)
  @sdp_port = @sdp_socket.addr[1]
end

#terminateObject



24
25
26
27
# File 'lib/endpoint.rb', line 24

def terminate
  @terminated = true
  terminate_specific
end

#terminate_specificObject

Cleans up the endpoint - designed to be overriden by per-transport subclasses



31
32
# File 'lib/endpoint.rb', line 31

def terminate_specific
end

#unregisterObject



170
171
172
# File 'lib/endpoint.rb', line 170

def unregister
  register 0
end