1
0
Fork 0
mirror of https://github.com/warmcat/libwebsockets.git synced 2025-03-09 00:00:04 +01:00

introduce-new-05-socket-closure-rules.patch

Signed-off-by: Andy Green <andy.green@linaro.org>
This commit is contained in:
Andy Green 2011-02-10 09:07:05 +00:00
parent 18910c5920
commit 5e1fa17a6c
7 changed files with 76 additions and 25 deletions

View file

@ -20,10 +20,23 @@ libwebsocket_client_close(struct libwebsocket *wsi)
{
int n = wsi->state;
struct libwebsocket_context *clients;
unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + 2 +
LWS_SEND_BUFFER_POST_PADDING];
if (n == WSI_STATE_DEAD_SOCKET)
return;
/*
* signal we are closing, libsocket_write will
* add any necessary version-specific stuff. If the write fails,
* no worries we are closing anyway. If we didn't initiate this
* close, then our state has been changed to
* WSI_STATE_RETURNED_CLOSE_ALREADY and we can skip this
*/
if (n == WSI_STATE_ESTABLISHED)
libwebsocket_write(wsi, &buf[LWS_SEND_BUFFER_PRE_PADDING], 0,
LWS_WRITE_CLOSE);
/* mark the WSI as dead and let the callback know */
wsi->state = WSI_STATE_DEAD_SOCKET;

View file

@ -25,12 +25,29 @@ void
libwebsocket_close_and_free_session(struct libwebsocket *wsi)
{
int n;
unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + 2 +
LWS_SEND_BUFFER_POST_PADDING];
if ((unsigned long)wsi < LWS_MAX_PROTOCOLS)
return;
n = wsi->state;
if (n == WSI_STATE_DEAD_SOCKET)
return;
/*
* signal we are closing, libsocket_write will
* add any necessary version-specific stuff. If the write fails,
* no worries we are closing anyway. If we didn't initiate this
* close, then our state has been changed to
* WSI_STATE_RETURNED_CLOSE_ALREADY and we can skip this
*/
if (n == WSI_STATE_ESTABLISHED)
libwebsocket_write(wsi, &buf[LWS_SEND_BUFFER_PRE_PADDING], 0,
LWS_WRITE_CLOSE);
wsi->state = WSI_STATE_DEAD_SOCKET;
if (wsi->protocol->callback && n == WSI_STATE_ESTABLISHED)
@ -233,8 +250,10 @@ libwebsocket_context_destroy(struct libwebsocket_context *this)
}
#ifdef LWS_OPENSSL_SUPPORT
if (this->ssl_ctx)
if (this && this->ssl_ctx)
SSL_CTX_free(this->ssl_ctx);
if (this && this->ssl_client_ctx)
SSL_CTX_free(this->ssl_client_ctx);
#endif
if (this)
@ -300,7 +319,9 @@ libwebsocket_service(struct libwebsocket_context *this, int timeout_ms)
if (n < 0 || this->fds[0].revents & (POLLERR | POLLHUP)) {
/*
fprintf(stderr, "Listen Socket dead\n");
*/
goto fatal;
}
if (n == 0) /* poll timeout */
@ -352,6 +373,7 @@ libwebsocket_service(struct libwebsocket_context *this, int timeout_ms)
#ifdef LWS_OPENSSL_SUPPORT
this->wsi[this->fds_count]->ssl = NULL;
this->ssl_ctx = NULL;
if (this->use_ssl) {
@ -451,22 +473,6 @@ fill_in_fds:
fatal:
fprintf(stderr, "service hits fatal\n");
/* close listening skt and per-protocol broadcast sockets */
for (client = 0; client < this->fds_count; client++)
close(this->fds[0].fd);
#ifdef LWS_OPENSSL_SUPPORT
if (this->ssl_ctx)
SSL_CTX_free(this->ssl_ctx);
#endif
if (this)
free(this);
this = NULL;
/* inform caller we are dead */
return 1;

View file

@ -46,7 +46,7 @@ enum libwebsocket_write_protocol {
LWS_WRITE_BINARY,
LWS_WRITE_HTTP,
/* special 04 opcodes */
/* special 04+ opcodes */
LWS_WRITE_CLOSE,
LWS_WRITE_PING,

View file

@ -583,11 +583,12 @@ spill:
n = libwebsocket_write(wsi, (unsigned char *)
&wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING],
wsi->rx_user_buffer_head, LWS_WRITE_CLOSE);
wsi->state = WSI_STATE_RETURNED_CLOSE_ALREADY;
/* close the connection */
return -1;
case LWS_WS_OPCODE_04__PING:
/* parrot the ping packet payload back as a pong*/
/* parrot the ping packet payload back as a pong */
n = libwebsocket_write(wsi, (unsigned char *)
&wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING],
wsi->rx_user_buffer_head, LWS_WRITE_PONG);
@ -902,6 +903,7 @@ spill:
n = libwebsocket_write(wsi, (unsigned char *)
&wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING],
wsi->rx_user_buffer_head, LWS_WRITE_CLOSE);
wsi->state = WSI_STATE_RETURNED_CLOSE_ALREADY;
/* close the connection */
return -1;
@ -980,9 +982,9 @@ libwebsocket_0405_frame_mask_generate(struct libwebsocket *wsi)
/* fetch the per-frame nonce */
fd = open(SYSTEM_RANDOM_FILEPATH, O_RDONLY);
if (fd < 1) {
fprintf(stderr, "Unable to open random device %s\n",
SYSTEM_RANDOM_FILEPATH);
if (fd < 0) {
fprintf(stderr, "Unable to open random device %s %d\n",
SYSTEM_RANDOM_FILEPATH, fd);
return 1;
}
n = read(fd, wsi->frame_masking_nonce_04, 4);
@ -1051,7 +1053,7 @@ int libwebsocket_write(struct libwebsocket *wsi, unsigned char *buf,
int post = 0;
unsigned int shift = 7;
if (len == 0) {
if (len == 0 && protocol != LWS_WRITE_CLOSE) {
fprintf(stderr, "zero length libwebsocket_write attempt\n");
return 0;
}
@ -1109,6 +1111,34 @@ int libwebsocket_write(struct libwebsocket *wsi, unsigned char *buf,
break;
case LWS_WRITE_CLOSE:
n = LWS_WS_OPCODE_04__CLOSE;
/*
* v5 mandates the first byte of close packet
* in both client and server directions
*/
if (wsi->ietf_spec_revision >= 5) {
/* we can do this because we demand post-buf */
if (len < 1)
len = 1;
switch (wsi->mode) {
case LWS_CONNMODE_WS_SERVING:
/*
fprintf(stderr, "LWS_WRITE_CLOSE S\n");
*/
buf[0] = 'S';
break;
case LWS_CONNMODE_WS_CLIENT:
/*
fprintf(stderr, "LWS_WRITE_CLOSE C\n");
*/
buf[0] = 'C';
break;
}
}
break;
case LWS_WRITE_PING:
n = LWS_WS_OPCODE_04__PING;

View file

@ -95,7 +95,8 @@ enum lws_connection_states {
WSI_STATE_HTTP_HEADERS,
WSI_STATE_DEAD_SOCKET,
WSI_STATE_ESTABLISHED,
WSI_STATE_CLIENT_UNCONNECTED
WSI_STATE_CLIENT_UNCONNECTED,
WSI_STATE_RETURNED_CLOSE_ALREADY
};
enum lws_token_indexes {

View file

@ -264,6 +264,6 @@ int main(int argc, char **argv)
usage:
fprintf(stderr, "Usage: libwebsockets-test-client "
"<server address> [--port=<p>] "
"[--ssl]\n");
"[--ssl] [-k] [-v <ver>]\n");
return 1;
}

View file

@ -514,6 +514,7 @@ usage:
"[--protocol=<protocolname>] "
"[--mirror] "
"[--replicate=clients>]"
"[--version <version>]"
"\n");
return 1;
}