<p>Nickolay V. Shmyrev has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/14453">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">res_http_websocket: Use mask for client messages<br><br>According to websocket protocol specification<br>https://tools.ietf.org/html/rfc6455#section-5.1 websocket clients MUST<br>use masking when sending data. Implement zero mask for interoperability<br>with websocket servers.<br><br>ASTERISK-28914 #close<br>Reported-by: Nickolay Shmyrev <nshmyrev@alphacephei.com><br><br>Change-Id: I9649e294f35489ae852a4bbb309ae32ef2a0689e<br>---<br>M res/res_http_websocket.c<br>1 file changed, 22 insertions(+), 4 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/53/14453/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/res/res_http_websocket.c b/res/res_http_websocket.c</span><br><span>index 63fccdd..4599985 100644</span><br><span>--- a/res/res_http_websocket.c</span><br><span>+++ b/res/res_http_websocket.c</span><br><span>@@ -287,7 +287,8 @@</span><br><span> int AST_OPTIONAL_API_NAME(ast_websocket_close)(struct ast_websocket *session, uint16_t reason)</span><br><span> {</span><br><span> enum ast_websocket_opcode opcode = AST_WEBSOCKET_OPCODE_CLOSE;</span><br><span style="color: hsl(0, 100%, 40%);">- char frame[4] = { 0, }; /* The header is 2 bytes and the reason code takes up another 2 bytes */</span><br><span style="color: hsl(120, 100%, 40%);">+ char frame[8] = { 0, };</span><br><span style="color: hsl(120, 100%, 40%);">+ int header_size, frame_size;</span><br><span> int res;</span><br><span> </span><br><span> if (session->close_sent) {</span><br><span>@@ -297,21 +298,29 @@</span><br><span> frame[0] = opcode | 0x80;</span><br><span> frame[1] = 2; /* The reason code is always 2 bytes */</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ if (session->client) {</span><br><span style="color: hsl(120, 100%, 40%);">+ frame[1] |= 0x80;</span><br><span style="color: hsl(120, 100%, 40%);">+ header_size = 6;</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ header_size = 2;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ frame_size = header_size + 2;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* If no reason has been specified assume 1000 which is normal closure */</span><br><span style="color: hsl(0, 100%, 40%);">- put_unaligned_uint16(&frame[2], htons(reason ? reason : 1000));</span><br><span style="color: hsl(120, 100%, 40%);">+ put_unaligned_uint16(&frame[header_size], htons(reason ? reason : 1000));</span><br><span> </span><br><span> session->closing = 1;</span><br><span> session->close_sent = 1;</span><br><span> </span><br><span> ao2_lock(session);</span><br><span> ast_iostream_set_timeout_inactivity(session->stream, session->timeout);</span><br><span style="color: hsl(0, 100%, 40%);">- res = ast_iostream_write(session->stream, frame, sizeof(frame));</span><br><span style="color: hsl(120, 100%, 40%);">+ res = ast_iostream_write(session->stream, frame, frame_size);</span><br><span> ast_iostream_set_timeout_disable(session->stream);</span><br><span> </span><br><span> /* If an error occurred when trying to close this connection explicitly terminate it now.</span><br><span> * Doing so will cause the thread polling on it to wake up and terminate.</span><br><span> */</span><br><span style="color: hsl(0, 100%, 40%);">- if (res != sizeof(frame)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (res != frame_size) {</span><br><span> ast_iostream_close(session->stream);</span><br><span> session->stream = NULL;</span><br><span> ast_verb(2, "WebSocket connection %s '%s' forcefully closed due to fatal write error\n",</span><br><span>@@ -364,6 +373,10 @@</span><br><span> header_size += 8;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ if (session->client) {</span><br><span style="color: hsl(120, 100%, 40%);">+ header_size += 4;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> frame_size = header_size + payload_size;</span><br><span> </span><br><span> frame = ast_alloca(frame_size + 1);</span><br><span>@@ -372,6 +385,11 @@</span><br><span> frame[0] = opcode | 0x80;</span><br><span> frame[1] = length;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ /* We introduce mask but keep mask zero for now */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (session->client) {</span><br><span style="color: hsl(120, 100%, 40%);">+ frame[1] |= 0x80;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* Use the additional available bytes to store the length */</span><br><span> if (length == 126) {</span><br><span> put_unaligned_uint16(&frame[2], htons(payload_size));</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/14453">change 14453</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/c/asterisk/+/14453"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I9649e294f35489ae852a4bbb309ae32ef2a0689e </div>
<div style="display:none"> Gerrit-Change-Number: 14453 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Nickolay V. Shmyrev <nshmyrev@alphacephei.com> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>