Skip to content
Snippets Groups Projects
Commit 40d5abc2 authored by Andy Green's avatar Andy Green
Browse files

close reply must use writable control reply path

parent bb90f9b7
Branches
Tags
No related merge requests found
...@@ -572,7 +572,6 @@ LWS_VISIBLE int lws_frame_is_binary(struct libwebsocket *wsi) ...@@ -572,7 +572,6 @@ LWS_VISIBLE int lws_frame_is_binary(struct libwebsocket *wsi)
int int
libwebsocket_rx_sm(struct libwebsocket *wsi, unsigned char c) libwebsocket_rx_sm(struct libwebsocket *wsi, unsigned char c)
{ {
int n;
struct lws_tokens eff_buf; struct lws_tokens eff_buf;
int ret = 0; int ret = 0;
...@@ -870,18 +869,15 @@ spill: ...@@ -870,18 +869,15 @@ spill:
lwsl_parser("seen client close ack\n"); lwsl_parser("seen client close ack\n");
return -1; return -1;
} }
if (wsi->state == WSI_STATE_RETURNED_CLOSE_ALREADY)
/* if he sends us 2 CLOSE, kill him */
return -1;
lwsl_parser("server sees client close packet\n"); lwsl_parser("server sees client close packet\n");
/* parrot the close packet payload back */
n = libwebsocket_write(wsi, (unsigned char *)
&wsi->u.ws.rx_user_buffer[
LWS_SEND_BUFFER_PRE_PADDING],
wsi->u.ws.rx_user_buffer_head,
LWS_WRITE_CLOSE);
if (n < 0)
lwsl_info("write of close ack failed %d\n", n);
wsi->state = WSI_STATE_RETURNED_CLOSE_ALREADY; wsi->state = WSI_STATE_RETURNED_CLOSE_ALREADY;
/* close the connection */ /* deal with the close packet contents as a PONG */
return -1; wsi->u.ws.payload_is_close = 1;
goto process_as_ping;
case LWS_WS_OPCODE_07__PING: case LWS_WS_OPCODE_07__PING:
lwsl_info("received %d byte ping, sending pong\n", lwsl_info("received %d byte ping, sending pong\n",
...@@ -895,7 +891,7 @@ spill: ...@@ -895,7 +891,7 @@ spill:
lwsl_parser("DROP PING since one pending\n"); lwsl_parser("DROP PING since one pending\n");
goto ping_drop; goto ping_drop;
} }
process_as_ping:
/* control packets can only be < 128 bytes long */ /* control packets can only be < 128 bytes long */
if (wsi->u.ws.rx_user_buffer_head > 128 - 4) { if (wsi->u.ws.rx_user_buffer_head > 128 - 4) {
lwsl_parser("DROP PING payload too large\n"); lwsl_parser("DROP PING payload too large\n");
......
...@@ -791,6 +791,7 @@ struct _lws_websocket_related { ...@@ -791,6 +791,7 @@ struct _lws_websocket_related {
unsigned int this_frame_masked:1; unsigned int this_frame_masked:1;
unsigned int inside_frame:1; /* next write will be more of frame */ unsigned int inside_frame:1; /* next write will be more of frame */
unsigned int clean_buffer:1; /* buffer not rewritten by extension */ unsigned int clean_buffer:1; /* buffer not rewritten by extension */
unsigned int payload_is_close:1; /* process as PONG, but it is close */
unsigned char *ping_payload_buf; /* non-NULL if malloc'd */ unsigned char *ping_payload_buf; /* non-NULL if malloc'd */
unsigned int ping_payload_alloc; /* length malloc'd */ unsigned int ping_payload_alloc; /* length malloc'd */
......
...@@ -101,9 +101,14 @@ lws_handle_POLLOUT_event(struct libwebsocket_context *context, ...@@ -101,9 +101,14 @@ lws_handle_POLLOUT_event(struct libwebsocket_context *context,
LWS_WRITE_PONG); LWS_WRITE_PONG);
if (n < 0) if (n < 0)
return -1; return -1;
/* well he is sent, mark him done */ /* well he is sent, mark him done */
wsi->u.ws.ping_pending_flag = 0; wsi->u.ws.ping_pending_flag = 0;
/* leave POLLOUT active either way */ if (wsi->u.ws.payload_is_close)
/* oh... a close frame was it... then we are done */
return -1;
/* otherwise for PING, leave POLLOUT active either way */
return 0; return 0;
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment