[Asterisk-code-review] res http websocket: respond to CLOSE opcode (asterisk[15])

Jeremy Lainé asteriskteam at digium.com
Tue Jan 8 01:41:56 CST 2019


Jeremy Lainé has uploaded this change for review. ( https://gerrit.asterisk.org/10861


Change subject: res_http_websocket: respond to CLOSE opcode
......................................................................

res_http_websocket: respond to CLOSE opcode

This ensures that Asterisk responds properly to frames received from a
client with opcode 8 (CLOSE) by:

- responding with its own CLOSE frame, echoing back the status code
- closing the connection

Handling of the CLOSE opcode is moved up with the rest of the opcodes so
that unmasking gets applied. The payload is no longer returned to the
caller, but neither ARI nor the chan_sip nor pjsip made use of the
payload, which is a good thing since it was masked.

ASTERISK-28231 #close

Change-Id: Icb1b60205fc77ee970ddc91d1f545671781344cf
---
M res/res_http_websocket.c
1 file changed, 17 insertions(+), 23 deletions(-)



  git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/61/10861/1

diff --git a/res/res_http_websocket.c b/res/res_http_websocket.c
index e7ce830..4ca5d0a 100644
--- a/res/res_http_websocket.c
+++ b/res/res_http_websocket.c
@@ -584,7 +584,7 @@
 	*opcode = buf[0] & 0xf;
 	*payload_len = buf[1] & 0x7f;
 	if (*opcode == AST_WEBSOCKET_OPCODE_TEXT || *opcode == AST_WEBSOCKET_OPCODE_BINARY || *opcode == AST_WEBSOCKET_OPCODE_CONTINUATION ||
-	    *opcode == AST_WEBSOCKET_OPCODE_PING || *opcode == AST_WEBSOCKET_OPCODE_PONG) {
+	    *opcode == AST_WEBSOCKET_OPCODE_PING || *opcode == AST_WEBSOCKET_OPCODE_PONG  || *opcode == AST_WEBSOCKET_OPCODE_CLOSE) {
 		fin = (buf[0] >> 7) & 1;
 		mask_present = (buf[1] >> 7) & 1;
 
@@ -643,6 +643,22 @@
 			return 0;
 		}
 
+		/* Reply to CLOSE opcode with our own CLOSE and echo back the code */
+		if (*opcode == AST_WEBSOCKET_OPCODE_CLOSE) {
+			uint16_t code = 0;
+			if (*payload_len >= 2) {
+				code = ntohs(get_unaligned_uint16(*payload));
+			}
+			*payload_len = 0;
+			ast_websocket_close(session, code);
+
+			if (session->stream) {
+				ast_iostream_close(session->stream);
+				session->stream = NULL;
+			}
+			return 0;
+		}
+
 		if (*payload_len) {
 			if (!(new_payload = ast_realloc(session->payload, (session->payload_len + *payload_len)))) {
 				ast_log(LOG_WARNING, "Failed allocation: %p, %zu, %"PRIu64"\n",
@@ -682,28 +698,6 @@
 			*payload = session->payload;
 			session->payload_len = 0;
 		}
-	} else if (*opcode == AST_WEBSOCKET_OPCODE_CLOSE) {
-		session->closing = 1;
-
-		/* Make the payload available so the user can look at the reason code if they so desire */
-		if (!*payload_len) {
-			return 0;
-		}
-
-		if (!(new_payload = ast_realloc(session->payload, *payload_len))) {
-			ast_log(LOG_WARNING, "Failed allocation: %p, %"PRIu64"\n",
-					session->payload, *payload_len);
-			*payload_len = 0;
-			return -1;
-		}
-
-		session->payload = new_payload;
-		if (ws_safe_read(session, &buf[frame_size], *payload_len, opcode)) {
-			return -1;
-		}
-		memcpy(session->payload, &buf[frame_size], *payload_len);
-		*payload = session->payload;
-		frame_size += *payload_len;
 	} else {
 		ast_log(LOG_WARNING, "WebSocket unknown opcode %u\n", *opcode);
 		/* We received an opcode that we don't understand, the RFC states that 1003 is for a type of data that can't be accepted... opcodes

-- 
To view, visit https://gerrit.asterisk.org/10861
To unsubscribe, or for help writing mail filters, visit https://gerrit.asterisk.org/settings

Gerrit-Project: asterisk
Gerrit-Branch: 15
Gerrit-MessageType: newchange
Gerrit-Change-Id: Icb1b60205fc77ee970ddc91d1f545671781344cf
Gerrit-Change-Number: 10861
Gerrit-PatchSet: 1
Gerrit-Owner: Jeremy Lainé <jeremy.laine at m4x.org>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-code-review/attachments/20190108/3150dc56/attachment.html>


More information about the asterisk-code-review mailing list