{
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;
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)
}
#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)
if (n < 0 || this->fds[0].revents & (POLLERR | POLLHUP)) {
+ /*
fprintf(stderr, "Listen Socket dead\n");
+ */
goto fatal;
}
if (n == 0) /* poll timeout */
#ifdef LWS_OPENSSL_SUPPORT
this->wsi[this->fds_count]->ssl = NULL;
+ this->ssl_ctx = NULL;
if (this->use_ssl) {
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;
LWS_WRITE_BINARY,
LWS_WRITE_HTTP,
- /* special 04 opcodes */
+ /* special 04+ opcodes */
LWS_WRITE_CLOSE,
LWS_WRITE_PING,
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);
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;
/* 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);
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;
}
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;
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 {
usage:
fprintf(stderr, "Usage: libwebsockets-test-client "
"<server address> [--port=<p>] "
- "[--ssl]\n");
+ "[--ssl] [-k] [-v <ver>]\n");
return 1;
}
"[--protocol=<protocolname>] "
"[--mirror] "
"[--replicate=clients>]"
+ "[--version <version>]"
"\n");
return 1;
}