Skip to content
Snippets Groups Projects
Commit 599cad94 authored by Alex Hultman's avatar Alex Hultman Committed by Andy Green
Browse files

Optimize payload exhaustion

https://github.com/warmcat/libwebsockets/pull/462

AG refactor and do loop unrolling
parent e32c0ba2
No related branches found
No related tags found
No related merge requests found
...@@ -1455,3 +1455,63 @@ lws_remaining_packet_payload(struct lws *wsi) ...@@ -1455,3 +1455,63 @@ lws_remaining_packet_payload(struct lws *wsi)
{ {
return wsi->u.ws.rx_packet_length; return wsi->u.ws.rx_packet_length;
} }
/* Once we reach LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED, we know how much
* to expect in that state and can deal with it in bulk more efficiently.
*/
void
lws_payload_until_length_exhausted(struct lws *wsi, unsigned char **buf,
size_t *len)
{
unsigned char *buffer = *buf, mask[4];
int buffer_size, avail, n;
char *rx_ubuf;
if (wsi->protocol->rx_buffer_size)
buffer_size = wsi->protocol->rx_buffer_size;
else
buffer_size = LWS_MAX_SOCKET_IO_BUF;
avail = buffer_size - wsi->u.ws.rx_ubuf_head;
/* do not consume more than we should */
if (avail > wsi->u.ws.rx_packet_length)
avail = wsi->u.ws.rx_packet_length;
/* do not consume more than what is in the buffer */
if (avail > *len)
avail = *len;
/* we want to leave 1 byte for the parser to handle properly */
if (avail <= 1)
return;
avail--;
rx_ubuf = wsi->u.ws.rx_ubuf + LWS_PRE + wsi->u.ws.rx_ubuf_head;
if (wsi->u.ws.all_zero_nonce)
memcpy(rx_ubuf, buffer, avail);
else {
for (n = 0; n < 4; n++)
mask[n] = wsi->u.ws.mask[(wsi->u.ws.mask_idx + n) & 3];
/* deal with 4-byte chunks using unwrapped loop */
n = avail >> 2;
while (n--) {
*(rx_ubuf++) = *(buffer++) ^ mask[0];
*(rx_ubuf++) = *(buffer++) ^ mask[1];
*(rx_ubuf++) = *(buffer++) ^ mask[2];
*(rx_ubuf++) = *(buffer++) ^ mask[3];
}
/* and the remaining bytes bytewise */
for (n = 0; n < (avail & 3); n++)
*(rx_ubuf++) = *(buffer++) ^ mask[n];
wsi->u.ws.mask_idx = (wsi->u.ws.mask_idx + avail) & 3;
}
(*buf) += avail;
wsi->u.ws.rx_ubuf_head += avail;
wsi->u.ws.rx_packet_length -= avail;
*len -= avail;
}
...@@ -1289,6 +1289,9 @@ lws_client_interpret_server_handshake(struct lws *wsi); ...@@ -1289,6 +1289,9 @@ lws_client_interpret_server_handshake(struct lws *wsi);
LWS_EXTERN int LWS_WARN_UNUSED_RESULT LWS_EXTERN int LWS_WARN_UNUSED_RESULT
lws_rx_sm(struct lws *wsi, unsigned char c); lws_rx_sm(struct lws *wsi, unsigned char c);
LWS_EXTERN void
lws_payload_until_length_exhausted(struct lws *wsi, unsigned char **buf, size_t *len);
LWS_EXTERN int LWS_WARN_UNUSED_RESULT LWS_EXTERN int LWS_WARN_UNUSED_RESULT
lws_issue_raw_ext_access(struct lws *wsi, unsigned char *buf, size_t len); lws_issue_raw_ext_access(struct lws *wsi, unsigned char *buf, size_t len);
......
...@@ -1235,6 +1235,11 @@ lws_interpret_incoming_packet(struct lws *wsi, unsigned char **buf, size_t len) ...@@ -1235,6 +1235,11 @@ lws_interpret_incoming_packet(struct lws *wsi, unsigned char **buf, size_t len)
if (wsi->rxflow_buffer) if (wsi->rxflow_buffer)
wsi->rxflow_pos++; wsi->rxflow_pos++;
/* consume payload bytes efficiently */
if (wsi->lws_rx_parse_state ==
LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED)
lws_payload_until_length_exhausted(wsi, buf, &len);
/* process the byte */ /* process the byte */
m = lws_rx_sm(wsi, *(*buf)++); m = lws_rx_sm(wsi, *(*buf)++);
if (m < 0) if (m < 0)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment