oversip 1.1.0.beta5 → 1.1.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.
Files changed (71) hide show
  1. data/etc/oversip.conf +16 -4
  2. data/etc/proxies.conf +8 -9
  3. data/etc/server.rb +59 -0
  4. data/ext/sip_parser/sip_parser.c +12066 -11975
  5. data/ext/sip_parser/sip_parser.h +1 -0
  6. data/ext/sip_parser/sip_parser_ruby.c +15 -4
  7. data/ext/utils/haproxy_protocol.c +4 -1
  8. data/ext/websocket_framing_utils/ws_framing_utils_ruby.c +2 -2
  9. data/lib/oversip/config.rb +50 -38
  10. data/lib/oversip/default_server.rb +12 -0
  11. data/lib/oversip/launcher.rb +10 -35
  12. data/lib/oversip/master_process.rb +2 -2
  13. data/lib/oversip/proxies_config.rb +2 -2
  14. data/lib/oversip/sip/client_transaction.rb +1 -7
  15. data/lib/oversip/sip/grammar/uri.rb +23 -1
  16. data/lib/oversip/sip/listeners/{reactor.rb → connection.rb} +16 -2
  17. data/lib/oversip/sip/listeners/ipv4_udp_server.rb +1 -1
  18. data/lib/oversip/sip/listeners/ipv6_udp_server.rb +1 -1
  19. data/lib/oversip/sip/listeners/tcp_client.rb +2 -3
  20. data/lib/oversip/sip/listeners/{tcp_reactor.rb → tcp_connection.rb} +14 -2
  21. data/lib/oversip/sip/listeners/tcp_server.rb +2 -5
  22. data/lib/oversip/sip/listeners/tls_client.rb +15 -12
  23. data/lib/oversip/sip/listeners/tls_server.rb +11 -11
  24. data/lib/oversip/sip/listeners/{tls_tunnel_reactor.rb → tls_tunnel_connection.rb} +20 -20
  25. data/lib/oversip/sip/listeners/tls_tunnel_server.rb +2 -5
  26. data/lib/oversip/sip/listeners/{udp_reactor.rb → udp_connection.rb} +4 -4
  27. data/lib/oversip/sip/listeners.rb +6 -10
  28. data/lib/oversip/sip/message.rb +4 -3
  29. data/lib/oversip/sip/message_processor.rb +17 -17
  30. data/lib/oversip/sip/modules/core.rb +18 -13
  31. data/lib/oversip/sip/modules/user_assertion.rb +7 -53
  32. data/lib/oversip/sip/proxy.rb +3 -3
  33. data/lib/oversip/sip/request.rb +2 -0
  34. data/lib/oversip/sip/rfc3263.rb +3 -3
  35. data/lib/oversip/sip/sip.rb +6 -0
  36. data/lib/oversip/sip/transport_manager.rb +8 -8
  37. data/lib/oversip/tls.rb +18 -22
  38. data/lib/oversip/version.rb +1 -1
  39. data/lib/oversip/websocket/constants.rb +0 -1
  40. data/lib/oversip/websocket/http_request.rb +4 -8
  41. data/lib/oversip/websocket/launcher.rb +83 -139
  42. data/lib/oversip/websocket/listeners/connection.rb +47 -0
  43. data/lib/oversip/websocket/{ws_apps/ipv4_ws_sip_app.rb → listeners/ipv4_ws_server.rb} +3 -3
  44. data/lib/oversip/websocket/{ws_apps/ipv4_wss_sip_app.rb → listeners/ipv4_wss_server.rb} +2 -2
  45. data/lib/oversip/websocket/listeners/ipv4_wss_tunnel_server.rb +21 -0
  46. data/lib/oversip/websocket/{ws_apps/ipv6_ws_sip_app.rb → listeners/ipv6_ws_server.rb} +3 -3
  47. data/lib/oversip/websocket/{ws_apps/ipv6_wss_sip_app.rb → listeners/ipv6_wss_server.rb} +2 -3
  48. data/lib/oversip/websocket/listeners/ipv6_wss_tunnel_server.rb +21 -0
  49. data/lib/oversip/websocket/listeners/{tcp_server.rb → ws_server.rb} +63 -43
  50. data/lib/oversip/websocket/listeners/{tls_server.rb → wss_server.rb} +14 -13
  51. data/lib/oversip/websocket/listeners/{tls_tunnel_server.rb → wss_tunnel_server.rb} +36 -10
  52. data/lib/oversip/websocket/listeners.rb +10 -9
  53. data/lib/oversip/websocket/websocket.rb +13 -0
  54. data/lib/oversip/websocket/ws_framing.rb +35 -97
  55. data/lib/oversip/websocket/ws_sip_app.rb +120 -0
  56. data/lib/oversip.rb +1 -1
  57. data/test/oversip_test_helper.rb +2 -2
  58. data/test/test_http_parser.rb +2 -2
  59. data/test/test_sip_parser.rb +18 -3
  60. data/test/test_uri.rb +44 -0
  61. metadata +39 -42
  62. data/lib/oversip/websocket/listeners/ipv4_tcp_server.rb +0 -15
  63. data/lib/oversip/websocket/listeners/ipv4_tls_server.rb +0 -15
  64. data/lib/oversip/websocket/listeners/ipv4_tls_tunnel_server.rb +0 -15
  65. data/lib/oversip/websocket/listeners/ipv6_tcp_server.rb +0 -15
  66. data/lib/oversip/websocket/listeners/ipv6_tls_server.rb +0 -15
  67. data/lib/oversip/websocket/listeners/ipv6_tls_tunnel_server.rb +0 -15
  68. data/lib/oversip/websocket/ws_app.rb +0 -77
  69. data/lib/oversip/websocket/ws_apps/ws_autobahn_app.rb +0 -23
  70. data/lib/oversip/websocket/ws_apps/ws_sip_app.rb +0 -156
  71. data/lib/oversip/websocket/ws_apps.rb +0 -9
@@ -1,10 +1,8 @@
1
1
  module OverSIP::WebSocket
2
2
 
3
- class TcpServer < ::EM::Connection
3
+ class WsServer < Connection
4
4
 
5
- include ::OverSIP::Logger
6
-
7
- # Max size (bytes) of the buffered data when receiving message headers
5
+ # Max size (bytes) of the buffered data when receiving HTTP headers
8
6
  # (avoid DoS attacks).
9
7
  HEADERS_MAX_SIZE = 2048
10
8
 
@@ -13,23 +11,25 @@ module OverSIP::WebSocket
13
11
  HDR_SUPPORTED_WEBSOCKET_VERSIONS = [ "X-Supported-WebSocket-Versions: #{WS_VERSIONS.keys.join(", ")}" ]
14
12
 
15
13
 
16
- class << self
17
- attr_accessor :ip_type, :transport
18
- end
14
+ attr_reader :outbound_flow_token
15
+ attr_writer :ws_established, :client_closed
16
+
19
17
 
20
- attr_accessor :ws_protocol, :ws_app_klass
21
- attr_reader :connection_log_id, :remote_ip_type, :remote_ip, :remote_port
22
- attr_reader :cvars # A Hash for storing user provided data.
23
- attr_accessor :ws_locally_closed
18
+ def remote_ip_type
19
+ @remote_ip_type || self.class.ip_type
20
+ end
24
21
 
22
+ def remote_ip
23
+ @remote_ip
24
+ end
25
25
 
26
- def initialize
27
- @http_parser = ::OverSIP::WebSocket::HttpRequestParser.new
28
- @buffer = ::IO::Buffer.new
29
- @state = :init
30
- @cvars = {}
26
+ def remote_port
27
+ @remote_port
31
28
  end
32
29
 
30
+ def transport
31
+ self.class.transport
32
+ end
33
33
 
34
34
  def post_connection
35
35
  begin
@@ -40,9 +40,13 @@ module OverSIP::WebSocket
40
40
  @state = :ignore
41
41
  return
42
42
  end
43
- @connection_log_id = ::SecureRandom.hex(4)
44
43
 
45
- log_system_info "connection opened from " << remote_desc
44
+ @connection_id = ::OverSIP::SIP::TransportManager.add_connection self, self.class, self.class.ip_type, @remote_ip, @remote_port
45
+
46
+ # Create an Outbound (RFC 5626) flow token for this connection.
47
+ @outbound_flow_token = ::OverSIP::SIP::TransportManager.add_outbound_connection self
48
+
49
+ log_system_debug("connection opened from " << remote_desc) if $oversip_debug
46
50
  end
47
51
 
48
52
 
@@ -62,7 +66,16 @@ module OverSIP::WebSocket
62
66
 
63
67
 
64
68
  def unbind cause=nil
69
+ @state = :ignore
70
+
71
+ # Remove the connection.
72
+ self.class.connections.delete @connection_id
73
+
74
+ # Remove the Outbound token flow.
75
+ ::OverSIP::SIP::TransportManager.delete_outbound_connection @outbound_flow_token
76
+
65
77
  @local_closed = true if cause == ::Errno::ETIMEDOUT
78
+ @local_closed = false if @client_closed
66
79
 
67
80
  if $oversip_debug
68
81
  log_msg = "connection from #{remote_desc} "
@@ -71,11 +84,9 @@ module OverSIP::WebSocket
71
84
  log_system_debug log_msg
72
85
  end unless $!
73
86
 
74
- @ws_framing.tcp_closed if @ws_framing
75
-
76
- if @ws_handshake_done
87
+ if @ws_established
77
88
  begin
78
- ::OverSIP::WebSocketEvents.on_disconnection self, !@ws_locally_closed
89
+ ::OverSIP::WebSocketEvents.on_disconnection self, !@local_closed
79
90
  rescue ::Exception => e
80
91
  log_system_error "error calling OverSIP::WebSocketEvents.on_disconnection():"
81
92
  log_system_error e
@@ -90,8 +101,8 @@ module OverSIP::WebSocket
90
101
 
91
102
  while (case @state
92
103
  when :init
104
+ @http_parser = ::OverSIP::WebSocket::HttpRequestParser.new
93
105
  @http_request = ::OverSIP::WebSocket::HttpRequest.new
94
- @http_parser.reset
95
106
  @http_parser_nbytes = 0
96
107
  @bytes_remaining = 0
97
108
  @state = :http_headers
@@ -103,14 +114,13 @@ module OverSIP::WebSocket
103
114
  check_http_request
104
115
 
105
116
  when :ws_connection_callback
106
- check_ws_connection_callback
117
+ ws_connection_callback
107
118
 
108
119
  when :accept_ws_handshake
109
120
  accept_ws_handshake
110
121
 
111
- when :websocket_frames
112
- return false if @buffer.size.zero?
113
-
122
+ when :websocket
123
+ @ws_established = true
114
124
  @ws_framing.receive_data
115
125
  false
116
126
 
@@ -147,10 +157,6 @@ module OverSIP::WebSocket
147
157
  @buffer.read(@http_parser_nbytes)
148
158
 
149
159
  @http_request.connection = self
150
- @http_request.transport = self.class.transport
151
- @http_request.source_ip = @remote_ip
152
- @http_request.source_port = @remote_port
153
- @http_request.source_ip_type = @remote_ip_type ||= self.class.ip_type
154
160
 
155
161
  @state = :check_http_request
156
162
  true
@@ -200,7 +206,7 @@ module OverSIP::WebSocket
200
206
 
201
207
  # Check Sec-WebSocket-Protocol.
202
208
  if @http_request.hdr_sec_websocket_protocol
203
- if @http_request.hdr_sec_websocket_protocol.include? @ws_protocol
209
+ if @http_request.hdr_sec_websocket_protocol.include? WS_SIP_PROTOCOL
204
210
  @websocket_protocol_negotiated = true
205
211
  else
206
212
  log_system_notice "Sec-WebSocket-Protocol does not contain a supported protocol but #{@http_request.hdr_sec_websocket_protocol} => 501"
@@ -214,7 +220,7 @@ module OverSIP::WebSocket
214
220
  end
215
221
 
216
222
 
217
- def check_ws_connection_callback
223
+ def ws_connection_callback
218
224
  begin
219
225
  ::OverSIP::WebSocketEvents.on_connection self, @http_request
220
226
  rescue ::Exception => e
@@ -245,7 +251,7 @@ module OverSIP::WebSocket
245
251
  ]
246
252
 
247
253
  if @websocket_protocol_negotiated
248
- extra_headers << "Sec-WebSocket-Protocol: #{@ws_protocol}"
254
+ extra_headers << "Sec-WebSocket-Protocol: #{WS_SIP_PROTOCOL}"
249
255
  end
250
256
 
251
257
  if @websocket_extensions
@@ -254,12 +260,12 @@ module OverSIP::WebSocket
254
260
 
255
261
  @http_request.reply 101, nil, extra_headers
256
262
 
257
- # Set the WS framming layer and WS application layer.
258
- @ws_framing = ::OverSIP::WebSocket::WsFraming.new(self, @buffer)
259
- @ws_framing.ws_app = @ws_app_klass.new(self, @ws_framing)
263
+ # Set the WS framing layer and WS application layer.
264
+ @ws_framing = ::OverSIP::WebSocket::WsFraming.new self, @buffer
265
+ ws_sip_app = ::OverSIP::WebSocket::WsSipApp.new self, @ws_framing
266
+ @ws_framing.ws_app = ws_sip_app
260
267
 
261
- @ws_handshake_done = true
262
- @state = :websocket_frames
268
+ @state = :websocket
263
269
  true
264
270
  end
265
271
 
@@ -271,12 +277,26 @@ module OverSIP::WebSocket
271
277
  end
272
278
 
273
279
 
274
- def ignore_incoming_data
275
- @state = :ignore # The WS application needs to set the connection in :ignore state
276
- # after sending a close frame to the client.
280
+ # Parameters ip and port are just included because they are needed in UDP, so the API remains equal.
281
+ def send_sip_msg msg, ip=nil, port=nil
282
+ if self.error?
283
+ log_system_notice "SIP message could not be sent, connection is closed"
284
+ return false
285
+ end
286
+
287
+ # If the SIP message is fully valid UTF-8 send a WS text frame.
288
+ if msg.force_encoding(::Encoding::UTF_8).valid_encoding?
289
+ @ws_framing.send_text_frame msg
290
+
291
+ # If not, send a WS binary frame.
292
+ else
293
+ @ws_framing.send_binary_frame msg
294
+ end
295
+
296
+ true
277
297
  end
278
298
 
279
- end # class TcpServer
299
+ end
280
300
 
281
301
  end
282
302
 
@@ -1,8 +1,8 @@
1
1
  module OverSIP::WebSocket
2
2
 
3
- class TlsServer < TcpServer
3
+ class WssServer < WsServer
4
4
 
5
- TLS_HANDSHAKE_MAX_TIME = 8
5
+ TLS_HANDSHAKE_MAX_TIME = 4
6
6
 
7
7
 
8
8
  def post_init
@@ -44,25 +44,26 @@ module OverSIP::WebSocket
44
44
  def ssl_handshake_completed
45
45
  log_system_info "TLS connection established from " << remote_desc
46
46
 
47
- # TODO: What to do it falidation fails? always do validation?
48
-
49
- validated, cert, tls_error, tls_error_string = ::OverSIP::TLS.validate @client_pems.pop, @client_pems
50
- if validated
51
- log_system_info "client provides a valid TLS certificate"
52
- else
53
- log_system_notice "client's TLS certificate validation failed (TLS error: #{tls_error.inspect}, description: #{tls_error_string.inspect})"
54
- end
55
-
56
- # @connected in TlsServer means "TLS connection" rather than
47
+ # @connected in WssServer means "TLS connection" rather than
57
48
  # just "TCP connection".
58
49
  @connected = true
59
50
  @timer_tls_handshake.cancel if @timer_tls_handshake
51
+
52
+ if ::OverSIP::WebSocket.callback_on_client_tls_handshake
53
+ begin
54
+ ::OverSIP::WebSocketEvents.on_client_tls_handshake self, @client_pems
55
+ rescue ::Exception => e
56
+ log_system_error "error calling OverSIP::WebSocketEvents.on_client_tls_handshake():"
57
+ log_system_error e
58
+ close_connection
59
+ end
60
+ end
60
61
  end
61
62
 
62
63
 
63
64
  def unbind cause=nil
64
- @timer_tls_handshake.cancel if @timer_tls_handshake
65
65
  super
66
+ @timer_tls_handshake.cancel if @timer_tls_handshake
66
67
  end
67
68
 
68
69
  end
@@ -1,16 +1,10 @@
1
1
  module OverSIP::WebSocket
2
2
 
3
- class TlsTunnelServer < TcpServer
4
-
5
- def initialize
6
- @http_parser = ::OverSIP::WebSocket::HttpRequestParser.new
7
- @buffer = ::IO::Buffer.new
8
- @state = :init
9
- end
10
-
3
+ class WssTunnelServer < WsServer
11
4
 
12
5
  def post_connection
13
6
  begin
7
+ # Temporal @remote_ip and @remote_port until the HAProxy protocol line is parsed.
14
8
  @remote_port, @remote_ip = ::Socket.unpack_sockaddr_in(get_peername)
15
9
  rescue => e
16
10
  log_system_error "error obtaining remote IP/port (#{e.class}: #{e.message}), closing connection"
@@ -18,9 +12,40 @@ module OverSIP::WebSocket
18
12
  @state = :ignore
19
13
  return
20
14
  end
21
- @connection_log_id = ::SecureRandom.hex(4)
22
15
 
23
- log_system_info "connection from the TLS tunnel " << remote_desc
16
+ # Create an Outbound (RFC 5626) flow token for this connection.
17
+ @outbound_flow_token = ::OverSIP::SIP::TransportManager.add_outbound_connection self
18
+
19
+ log_system_debug ("connection from the TLS tunnel " << remote_desc) if $oversip_debug
20
+ end
21
+
22
+
23
+ def unbind cause=nil
24
+ @state = :ignore
25
+
26
+ # Remove the connection.
27
+ self.class.connections.delete @connection_id if @connection_id
28
+
29
+ # Remove the Outbound token flow.
30
+ ::OverSIP::SIP::TransportManager.delete_outbound_connection @outbound_flow_token
31
+
32
+ @local_closed = true if cause == ::Errno::ETIMEDOUT
33
+
34
+ if $oversip_debug
35
+ log_msg = "connection from the TLS tunnel #{remote_desc} "
36
+ log_msg << ( @local_closed ? "locally closed" : "remotely closed" )
37
+ log_msg << " (cause: #{cause.inspect})" if cause
38
+ log_system_debug log_msg
39
+ end unless $!
40
+
41
+ if @state == :websocket
42
+ begin
43
+ ::OverSIP::WebSocketEvents.on_disconnection self, !@local_closed
44
+ rescue ::Exception => e
45
+ log_system_error "error calling OverSIP::WebSocketEvents.on_disconnection():"
46
+ log_system_error e
47
+ end
48
+ end unless $!
24
49
  end
25
50
 
26
51
 
@@ -30,6 +55,7 @@ module OverSIP::WebSocket
30
55
 
31
56
  while (case @state
32
57
  when :init
58
+ @http_parser = ::OverSIP::WebSocket::HttpRequestParser.new
33
59
  @http_request = ::OverSIP::WebSocket::HttpRequest.new
34
60
  @http_parser.reset
35
61
  @http_parser_nbytes = 0
@@ -1,12 +1,13 @@
1
1
  # OverSIP files
2
2
 
3
- require "oversip/websocket/listeners/tcp_server"
4
- require "oversip/websocket/listeners/tls_server"
5
- require "oversip/websocket/listeners/tls_tunnel_server"
3
+ require "oversip/websocket/listeners/connection"
4
+ require "oversip/websocket/listeners/ws_server"
5
+ require "oversip/websocket/listeners/wss_server"
6
+ require "oversip/websocket/listeners/wss_tunnel_server"
6
7
 
7
- require "oversip/websocket/listeners/ipv4_tcp_server"
8
- require "oversip/websocket/listeners/ipv6_tcp_server"
9
- require "oversip/websocket/listeners/ipv4_tls_server"
10
- require "oversip/websocket/listeners/ipv6_tls_server"
11
- require "oversip/websocket/listeners/ipv4_tls_tunnel_server"
12
- require "oversip/websocket/listeners/ipv6_tls_tunnel_server"
8
+ require "oversip/websocket/listeners/ipv4_ws_server"
9
+ require "oversip/websocket/listeners/ipv6_ws_server"
10
+ require "oversip/websocket/listeners/ipv4_wss_server"
11
+ require "oversip/websocket/listeners/ipv6_wss_server"
12
+ require "oversip/websocket/listeners/ipv4_wss_tunnel_server"
13
+ require "oversip/websocket/listeners/ipv6_wss_tunnel_server"
@@ -0,0 +1,13 @@
1
+ module OverSIP::WebSocket
2
+
3
+ def self.module_init
4
+ conf = ::OverSIP.configuration
5
+
6
+ @callback_on_client_tls_handshake = conf[:websocket][:callback_on_client_tls_handshake]
7
+ end
8
+
9
+ def self.callback_on_client_tls_handshake
10
+ @callback_on_client_tls_handshake
11
+ end
12
+
13
+ end
@@ -20,16 +20,17 @@ module OverSIP::WebSocket
20
20
  KEEPALIVE_PING_FRAME = keepalive_ping_frame
21
21
 
22
22
 
23
- attr_writer :ws_app
24
-
25
-
26
23
  def self.class_init
27
24
  @@max_frame_size = ::OverSIP.configuration[:websocket][:max_ws_frame_size]
28
25
  end
29
26
 
30
27
 
28
+ attr_writer :ws_app
29
+
30
+
31
+ LOG_ID = "WsFraming"
31
32
  def log_id
32
- @log_id ||= "WsFramming #{@connection.connection_log_id}"
33
+ LOG_ID
33
34
  end
34
35
 
35
36
 
@@ -43,7 +44,7 @@ module OverSIP::WebSocket
43
44
 
44
45
  def do_keep_alive interval
45
46
  @keep_alive_timer = ::EM::PeriodicTimer.new(interval) do
46
- log_system_debug "sending keep-alive ping frame: payload_length=10" if $oversip_debug
47
+ log_system_debug "sending keep-alive ping frame" if $oversip_debug
47
48
  @connection.send_data KEEPALIVE_PING_FRAME
48
49
  end
49
50
  end
@@ -67,21 +68,21 @@ module OverSIP::WebSocket
67
68
 
68
69
  if @rsv1 or @rsv2 or @rsv3
69
70
  log_system_notice "frame has RSV bits set, clossing the connection"
70
- send_close_frame 1002, "RSV bit set not supported"
71
+ @connection.close 1002, "RSV bit set not supported"
71
72
  return false
72
73
  end
73
74
 
74
75
  # opcode are bits 4-7.
75
76
  @opcode = byte1 & 0b00001111
76
77
  unless (@sym_opcode = OPCODE[@opcode])
77
- send_close_frame 1002, "unknown opcode=#{@opcode}"
78
+ @connection.close 1002, "unknown opcode=#{@opcode}"
78
79
  return false
79
80
  end
80
81
 
81
82
  # MASK is bit 8.
82
83
  @mask = (byte2 & 0b10000000) == 0b10000000
83
84
  unless @mask
84
- send_close_frame 1002, "MASK bit not set"
85
+ @connection.close 1002, "MASK bit not set"
85
86
  return false
86
87
  end
87
88
 
@@ -124,7 +125,7 @@ module OverSIP::WebSocket
124
125
 
125
126
  if @buffer.read(4).unpack('N').first != 0
126
127
  log_system_notice "frame size bigger than 4 GB, rejected"
127
- send_close_frame 1008
128
+ @connection.close 1008
128
129
  return false
129
130
  end
130
131
 
@@ -148,13 +149,13 @@ module OverSIP::WebSocket
148
149
  # less and MUST NOT be fragmented.
149
150
  if control_frame? and @payload_length > 125
150
151
  log_system_notice "received invalid control frame (payload_length > 125), sending close frame"
151
- send_close_frame 1002
152
+ @connection.close 1002
152
153
  return false
153
154
  end
154
155
 
155
156
  if control_frame? and not @fin
156
157
  log_system_notice "received invalid control frame (FIN=0), sending close frame"
157
- send_close_frame 1002, "forbidden FIN=0 in control frame"
158
+ @connection.close 1002, "forbidden FIN=0 in control frame"
158
159
  return false
159
160
  end
160
161
 
@@ -162,7 +163,7 @@ module OverSIP::WebSocket
162
163
  # arrived with FIN=0.
163
164
  if continuation_frame? and not @msg_sym_opcode
164
165
  log_system_notice "invalid continuation frame received (no previous unfinished message), sending close frame"
165
- send_close_frame 1002, "invalid continuation frame received"
166
+ @connection.close 1002, "invalid continuation frame received"
166
167
  return false
167
168
  end
168
169
 
@@ -170,13 +171,13 @@ module OverSIP::WebSocket
170
171
  # a new frame with opcode=text/binary.
171
172
  if @msg_sym_opcode and text_or_binary_frame?
172
173
  log_system_notice "invalid text/binary frame received (expecting a continuation frame), sending close frame"
173
- send_close_frame 1002, "expected a continuation frame"
174
+ @connection.close 1002, "expected a continuation frame"
174
175
  return false
175
176
  end
176
177
 
177
178
  # Check max frame size.
178
179
  if @payload_length > @@max_frame_size
179
- send_close_frame 1009, "frame too big"
180
+ @connection.close 1009, "frame too big"
180
181
  return false
181
182
  end
182
183
 
@@ -214,17 +215,22 @@ module OverSIP::WebSocket
214
215
  if @payload
215
216
  if (valid_utf8 = @utf8_validator.validate(@payload)) == false
216
217
  log_system_notice "received single text frame contains invalid UTF-8, closing the connection"
217
- send_close_frame 1007, "single text frame contains invalid UTF-8"
218
+ @connection.close 1007, "single text frame contains invalid UTF-8"
218
219
  return false
219
220
  end
220
221
 
221
222
  if @fin and not valid_utf8
222
223
  log_system_notice "received single text frame contains incomplete UTF-8, closing the connection"
223
- send_close_frame 1007, "single text frame contains incomplete UTF-8"
224
+ @connection.close 1007, "single text frame contains incomplete UTF-8"
224
225
  return false
225
226
  end
226
227
 
227
- return false unless @ws_app.receive_payload_data @payload
228
+ # If @ws_app.receive_payload_data returns false it means that total
229
+ # message size is too big.
230
+ unless @ws_app.receive_payload_data @payload
231
+ @connection.close 1009, "message too big"
232
+ return false
233
+ end
228
234
  end
229
235
 
230
236
  # If message is finished tell it to the WS application.
@@ -241,7 +247,12 @@ module OverSIP::WebSocket
241
247
  @msg_sym_opcode = @sym_opcode
242
248
 
243
249
  if @payload
244
- return false unless @ws_app.receive_payload_data @payload
250
+ # If @ws_app.receive_payload_data returns false it means that total
251
+ # message size is too big.
252
+ unless @ws_app.receive_payload_data @payload
253
+ @connection.close 1009, "message too big"
254
+ return false
255
+ end
245
256
  end
246
257
 
247
258
  # If message is finished tell it to the WS application.
@@ -257,13 +268,13 @@ module OverSIP::WebSocket
257
268
  if @msg_sym_opcode == :text
258
269
  if (valid_utf8 = @utf8_validator.validate(@payload)) == false
259
270
  log_system_notice "received continuation text frame contains invalid UTF-8, closing the connection"
260
- send_close_frame 1007, "continuation text frame contains invalid UTF-8"
271
+ @connection.close 1007, "continuation text frame contains invalid UTF-8"
261
272
  return false
262
273
  end
263
274
 
264
275
  if @fin and not valid_utf8
265
276
  log_system_notice "received continuation final text frame contains incomplete UTF-8, closing the connection"
266
- send_close_frame 1007, "continuation final text frame contains incomplete UTF-8"
277
+ @connection.close 1007, "continuation final text frame contains incomplete UTF-8"
267
278
  return false
268
279
  end
269
280
  end
@@ -293,7 +304,7 @@ module OverSIP::WebSocket
293
304
  # So it must be true for the close frame reason.
294
305
  unless @utf8_validator.validate(reason)
295
306
  log_system_notice "received close frame with invalid UTF-8 data in the reason: status=#{status.inspect}"
296
- send_close_frame 1007, "close frame reason contains incomplete UTF-8"
307
+ @connection.close 1007, "close frame reason contains incomplete UTF-8"
297
308
  return false
298
309
  end
299
310
  end
@@ -316,7 +327,8 @@ module OverSIP::WebSocket
316
327
  log_system_debug "received close frame: status=#{status.inspect}, reason=#{reason.inspect}" if $oversip_debug
317
328
  end
318
329
 
319
- send_close_frame nil, nil, true
330
+ @connection.client_closed = true
331
+ @connection.close nil, nil
320
332
  return false
321
333
 
322
334
  when :ping
@@ -329,13 +341,6 @@ module OverSIP::WebSocket
329
341
  end
330
342
 
331
343
  true
332
-
333
- when :ws_closed
334
- false
335
-
336
- when :tcp_closed
337
- false
338
-
339
344
  end)
340
345
  end # while
341
346
 
@@ -359,14 +364,6 @@ module OverSIP::WebSocket
359
364
 
360
365
  # NOTE: A WS message is always set in a single WS frame.
361
366
  def send_text_frame message
362
- case @state
363
- when :ws_closed
364
- log_system_debug "cannot send text frame, WebSocket session is closed" if $oversip_debug
365
- return false
366
- when :tcp_closed
367
- log_system_debug "cannot send text frame, TCP session is closed" if $oversip_debug
368
- return false
369
- end
370
367
  log_system_debug "sending text frame: payload_length=#{message.bytesize}" if $oversip_debug
371
368
 
372
369
  frame = "".encode ::Encoding::BINARY
@@ -401,14 +398,6 @@ module OverSIP::WebSocket
401
398
 
402
399
 
403
400
  def send_binary_frame message
404
- case @state
405
- when :ws_closed
406
- log_system_debug "cannot send binary frame, WebSocket session is closed" if $oversip_debug
407
- return false
408
- when :tcp_closed
409
- log_system_debug "cannot send binary frame, TCP session is closed" if $oversip_debug
410
- return false
411
- end
412
401
  log_system_debug "sending binary frame: payload_length=#{message.bytesize}" if $oversip_debug
413
402
 
414
403
  frame = "".encode ::Encoding::BINARY
@@ -443,14 +432,6 @@ module OverSIP::WebSocket
443
432
 
444
433
 
445
434
  def send_ping_frame data=nil
446
- case @state
447
- when :ws_closed
448
- log_system_debug "cannot send ping frame, WebSocket session is closed" if $oversip_debug
449
- return false
450
- when :tcp_closed
451
- log_system_debug "cannot send ping frame, TCP session is closed" if $oversip_debug
452
- return false
453
- end
454
435
  if data
455
436
  log_system_debug "sending ping frame: payload_length=#{data.bytesize}" if $oversip_debug
456
437
  else
@@ -483,14 +464,6 @@ module OverSIP::WebSocket
483
464
 
484
465
 
485
466
  def send_pong_frame data=nil
486
- case @state
487
- when :ws_closed
488
- log_system_debug "cannot send pong frame, WebSocket session is closed" if $oversip_debug
489
- return false
490
- when :tcp_closed
491
- log_system_debug "cannot send pong frame, TCP session is closed" if $oversip_debug
492
- return false
493
- end
494
467
  if data
495
468
  log_system_debug "sending pong frame: payload_length=#{data.bytesize}" if $oversip_debug
496
469
  else
@@ -525,22 +498,12 @@ module OverSIP::WebSocket
525
498
  def send_close_frame status=nil, reason=nil, in_reply_to_close=nil
526
499
  @keep_alive_timer.cancel if @keep_alive_timer
527
500
 
528
- case @state
529
- when :ws_closed
530
- log_system_debug "cannot send close frame, WebSocket session is closed" if $oversip_debug
531
- return false
532
- when :tcp_closed
533
- log_system_debug "cannot send close frame, TCP session is closed" if $oversip_debug
534
- return false
535
- end
536
-
537
501
  unless in_reply_to_close
538
502
  log_system_debug "sending close frame: status=#{status.inspect}, reason=#{reason.inspect}" if $oversip_debug
539
503
  else
540
504
  log_system_debug "sending reply close frame: status=#{status.inspect}, reason=#{reason.inspect}" if $oversip_debug
541
505
  end
542
506
 
543
- @state = :ws_closed
544
507
  @buffer.clear
545
508
 
546
509
  frame = "".encode ::Encoding::BINARY
@@ -569,35 +532,10 @@ module OverSIP::WebSocket
569
532
  end
570
533
  end
571
534
 
572
- @connection.ignore_incoming_data
573
535
  @connection.send_data frame
574
-
575
- # NOTE: Don't do it since it "seems" that the connection has been closed
576
- # by the client.
577
- #unless in_reply_to_close
578
- # Let's some time for the client to send us a close frame (it will
579
- # be ignored anyway) before closing the TCP connection.
580
- # NOTE: Don't do it since it "seems" that the connection has been closed
581
- # by the client.
582
- #::EM.add_timer(0.2) do
583
- #@connection.close_connection_after_writing
584
- #end
585
- #else
586
- #@connection.close_connection_after_writing
587
- #end
588
-
589
- @connection.close_connection_after_writing
590
536
  true
591
537
  end
592
538
 
593
-
594
- def tcp_closed
595
- @keep_alive_timer.cancel if @keep_alive_timer
596
- @state = :tcp_closed
597
- # Tell it to the WS application.
598
- @ws_app.tcp_closed rescue nil
599
- end
600
-
601
- end # class WsFraming
539
+ end
602
540
 
603
541
  end