Class: OverSIP::WebSocket::WsSipApp

Inherits:
WsApp
  • Object
show all
Includes:
SIP::MessageProcessor
Defined in:
lib/oversip/sip/modules/user_assertion.rb,
lib/oversip/websocket/ws_apps/ws_sip_app.rb

Constant Summary

Constants included from SIP::MessageProcessor

SIP::MessageProcessor::MSG_TYPE

Constants included from Logger

Logger::SYSLOG_POSIXMQ_MAPPING

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from WsApp

class_init, #close_connection, #message_done, #receive_payload_data

Methods included from Logger

close, #fatal, fg_system_msg2str, init_logger_mq, load_methods, #log_id, syslog_system_msg2str, syslog_user_msg2str

Constructor Details

#initialize(*args) ⇒ WsSipApp

Returns a new instance of WsSipApp.



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/oversip/websocket/ws_apps/ws_sip_app.rb', line 25

def initialize *args
  super
  # WebSocket is message boundary so we just need a SIP parser instance.
  @@parser ||= ::OverSIP::SIP::MessageParser.new
  @parser = @@parser

  # If the request comes from the TLS proxy then take it into account.
  if @connection.class == ::OverSIP::WebSocket::IPv4TlsTunnelServer
    @connection_id = ::OverSIP::SIP::TransportManager.add_connection self, ::OverSIP::WebSocket::IPv4WssSipApp, :ipv4,
                                                                     @connection.remote_ip, @connection.remote_port
  elsif @connection.class == ::OverSIP::WebSocket::IPv6TlsTunnelServer
    @connection_id = ::OverSIP::SIP::TransportManager.add_connection self, ::OverSIP::WebSocket::IPv6WssSipApp, :ipv6,
                                                                     @connection.remote_ip, @connection.remote_port
  else
    @connection_id = ::OverSIP::SIP::TransportManager.add_connection self, self.class, self.class.ip_type,
                                                                     @connection.remote_ip, @connection.remote_port
  end

  # Create an Outbound (RFC 5626) flow token for this connection.
  @outbound_flow_token = ::OverSIP::SIP::TransportManager.add_outbound_connection self
end

Class Attribute Details

.connectionsObject

Returns the value of attribute connections.



8
9
10
# File 'lib/oversip/websocket/ws_apps/ws_sip_app.rb', line 8

def connections
  @connections
end

.invite_client_transactionsObject

Returns the value of attribute invite_client_transactions.



8
9
10
# File 'lib/oversip/websocket/ws_apps/ws_sip_app.rb', line 8

def invite_client_transactions
  @invite_client_transactions
end

.invite_server_transactionsObject

Returns the value of attribute invite_server_transactions.



8
9
10
# File 'lib/oversip/websocket/ws_apps/ws_sip_app.rb', line 8

def invite_server_transactions
  @invite_server_transactions
end

.ipObject

Returns the value of attribute ip.



8
9
10
# File 'lib/oversip/websocket/ws_apps/ws_sip_app.rb', line 8

def ip
  @ip
end

.ip_typeObject

Returns the value of attribute ip_type.



8
9
10
# File 'lib/oversip/websocket/ws_apps/ws_sip_app.rb', line 8

def ip_type
  @ip_type
end

.non_invite_client_transactionsObject

Returns the value of attribute non_invite_client_transactions.



8
9
10
# File 'lib/oversip/websocket/ws_apps/ws_sip_app.rb', line 8

def non_invite_client_transactions
  @non_invite_client_transactions
end

.non_invite_server_transactionsObject

Returns the value of attribute non_invite_server_transactions.



8
9
10
# File 'lib/oversip/websocket/ws_apps/ws_sip_app.rb', line 8

def non_invite_server_transactions
  @non_invite_server_transactions
end

.outbound_path_fragmentObject

Returns the value of attribute outbound_path_fragment.



8
9
10
# File 'lib/oversip/websocket/ws_apps/ws_sip_app.rb', line 8

def outbound_path_fragment
  @outbound_path_fragment
end

.outbound_record_route_fragmentObject

Returns the value of attribute outbound_record_route_fragment.



8
9
10
# File 'lib/oversip/websocket/ws_apps/ws_sip_app.rb', line 8

def outbound_record_route_fragment
  @outbound_record_route_fragment
end

.portObject

Returns the value of attribute port.



8
9
10
# File 'lib/oversip/websocket/ws_apps/ws_sip_app.rb', line 8

def port
  @port
end

.record_routeObject

Returns the value of attribute record_route.



8
9
10
# File 'lib/oversip/websocket/ws_apps/ws_sip_app.rb', line 8

def record_route
  @record_route
end

.transportObject

Returns the value of attribute transport.



8
9
10
# File 'lib/oversip/websocket/ws_apps/ws_sip_app.rb', line 8

def transport
  @transport
end

.via_coreObject

Returns the value of attribute via_core.



8
9
10
# File 'lib/oversip/websocket/ws_apps/ws_sip_app.rb', line 8

def via_core
  @via_core
end

Instance Attribute Details

#asserted_userObject

Returns the value of attribute asserted_user.



121
122
123
# File 'lib/oversip/sip/modules/user_assertion.rb', line 121

def asserted_user
  @asserted_user
end

#outbound_flow_tokenObject (readonly)

Returns the value of attribute outbound_flow_token.



22
23
24
# File 'lib/oversip/websocket/ws_apps/ws_sip_app.rb', line 22

def outbound_flow_token
  @outbound_flow_token
end

Class Method Details

.reliable_transport_listener?Boolean

Returns:

  • (Boolean)


16
17
18
# File 'lib/oversip/websocket/ws_apps/ws_sip_app.rb', line 16

def reliable_transport_listener?
  @is_reliable_transport_listener
end

Instance Method Details

#process_binary_message(ws_message) ⇒ Object



53
54
55
# File 'lib/oversip/websocket/ws_apps/ws_sip_app.rb', line 53

def process_binary_message ws_message
  process_sip_message ws_message
end

#process_sip_message(ws_message) ⇒ Object



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/oversip/websocket/ws_apps/ws_sip_app.rb', line 58

def process_sip_message ws_message
  # Just a single SIP message allowed per WS message.
  @parser.reset

  # Better to encode it as BINARY (to later extract the body).
  ws_message.force_encoding ::Encoding::BINARY

  unless parser_nbytes = @parser.execute(ws_message, 0)
    if wrong_message = @parser.parsed
      log_system_warn "SIP parsing error for #{MSG_TYPE[wrong_message.class]}: \"#{@parser.error}\""
    else
      log_system_warn "SIP parsing error: \"#{@parser.error}\""
    end
    close_connection 4000, "SIP message parsing error"
    return
  end

  unless @parser.finished?
    log_system_warn "SIP parsing error: message not completed"

    close_connection 4001, "SIP message incomplete"
    return
  end

  # At this point we've got a SIP::Request, SIP::Response or :outbound_keepalive symbol.
  @msg = @parser.parsed

  # Received data is a SIP Outbound keealive (double CRLF). Reply with single CRLF.
  if @msg == :outbound_keepalive
    log_system_debug "Outbound keepalive received, replying single CRLF"  if $oversip_debug
    @ws_framing.send_text_frame(CRLF)
    return
  end

  @parser.post_parsing

  @msg.connection = self
  @msg.transport = self.class.transport
  @msg.source_ip = @connection.remote_ip
  @msg.source_port = @connection.remote_port
  @msg.source_ip_type = @connection.remote_ip_type

  return  unless valid_message?
  add_via_received_rport  if @msg.request?
  return  unless check_via_branch

  # Get the body.
  if parser_nbytes != ws_message.bytesize
    @msg.body = ws_message[parser_nbytes..-1]

    if @msg.content_length and @msg.content_length != @msg.body.bytesize
      log_system_warn "SIP message body size (#{@msg.body.bytesize}) does not match Content-Length (#{@msg.content_length.inspect}), ignoring message"
      close_connection 4002, "SIP message body size does not match Content-Length"
      return
    end
  end

  if @msg.request?
    process_request
  else
    process_response
  end

end

#process_text_message(ws_message) ⇒ Object



48
49
50
# File 'lib/oversip/websocket/ws_apps/ws_sip_app.rb', line 48

def process_text_message ws_message
  process_sip_message ws_message
end

#send_sip_msg(msg, ip = nil, port = nil) ⇒ Object

Parameters ip and port are just included because they are needed in UDP, so the API remains equal.



134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/oversip/websocket/ws_apps/ws_sip_app.rb', line 134

def send_sip_msg msg, ip=nil, port=nil
  # If the SIP message is fully valid UTF-8 send a WS text frame.
  if msg.force_encoding(::Encoding::UTF_8).valid_encoding?
    unless @ws_framing.send_text_frame(msg)
      log_system_notice "SIP message could not be sent, WebSocket connection is closed"
      return false
    end

  # If not, send a WS binary frame.
  else
    unless @ws_framing.send_binary_frame(msg)
      log_system_notice "SIP message could not be sent, WebSocket connection is closed"
      return false
    end
  end

  true
end

#tcp_closedObject



124
125
126
127
128
129
130
# File 'lib/oversip/websocket/ws_apps/ws_sip_app.rb', line 124

def tcp_closed
  # Remove the connection.
  self.class.connections.delete @connection_id

  # Remove the Outbound token flow.
  ::OverSIP::SIP::TransportManager.delete_outbound_connection @outbound_flow_token
end