mirror of
https://github.com/warmcat/libwebsockets.git
synced 2025-03-09 00:00:04 +01:00
require close reason argument on close and free session
Signed-off-by: Andy Green <andy@warmcat.com>
This commit is contained in:
parent
06de513612
commit
687b0188bc
5 changed files with 129 additions and 90 deletions
|
@ -611,7 +611,8 @@ libwebsocket_read(struct libwebsocket_context *this, struct libwebsocket *wsi,
|
|||
return 0;
|
||||
|
||||
bail:
|
||||
libwebsocket_close_and_free_session(this, wsi);
|
||||
libwebsocket_close_and_free_session(this, wsi,
|
||||
LWS_CLOSE_STATUS_NOSTATUS);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -131,7 +131,7 @@ interface_to_sa(const char* ifname, struct sockaddr_in *addr, size_t addrlen)
|
|||
|
||||
void
|
||||
libwebsocket_close_and_free_session(struct libwebsocket_context *this,
|
||||
struct libwebsocket *wsi)
|
||||
struct libwebsocket *wsi, enum lws_close_status reason)
|
||||
{
|
||||
int n;
|
||||
int old_state;
|
||||
|
@ -169,6 +169,8 @@ libwebsocket_close_and_free_session(struct libwebsocket_context *this,
|
|||
this->protocols[0].callback(this, wsi,
|
||||
LWS_CALLBACK_DEL_POLL_FD, (void *)(long)wsi->sock, NULL, 0);
|
||||
|
||||
wsi->close_reason = reason;
|
||||
|
||||
/*
|
||||
* signal we are closing, libsocket_write will
|
||||
* add any necessary version-specific stuff. If the write fails,
|
||||
|
@ -244,7 +246,7 @@ libwebsockets_hangup_on_client(struct libwebsocket_context *this, int fd)
|
|||
this->fds_count--;
|
||||
}
|
||||
|
||||
libwebsocket_close_and_free_session(this, wsi);
|
||||
libwebsocket_close_and_free_session(this, wsi, 0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -375,7 +377,8 @@ libwebsocket_service_fd(struct libwebsocket_context *this,
|
|||
*/
|
||||
|
||||
if (tv.tv_sec > wsi->pending_timeout_limit)
|
||||
libwebsocket_close_and_free_session(this, wsi);
|
||||
libwebsocket_close_and_free_session(this, wsi,
|
||||
LWS_CLOSE_STATUS_NOSTATUS);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -590,7 +593,8 @@ libwebsocket_service_fd(struct libwebsocket_context *this,
|
|||
debug("Session Socket %p (fd=%d) dead\n",
|
||||
(void *)wsi, pollfd->fd);
|
||||
|
||||
libwebsocket_close_and_free_session(this, wsi);
|
||||
libwebsocket_close_and_free_session(this, wsi,
|
||||
LWS_CLOSE_STATUS_NORMAL);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -676,20 +680,23 @@ libwebsocket_service_fd(struct libwebsocket_context *this,
|
|||
fprintf(stderr, "Proxy connection %p (fd=%d) dead\n",
|
||||
(void *)wsi, pollfd->fd);
|
||||
|
||||
libwebsocket_close_and_free_session(this, wsi);
|
||||
libwebsocket_close_and_free_session(this, wsi,
|
||||
LWS_CLOSE_STATUS_NOSTATUS);
|
||||
return 1;
|
||||
}
|
||||
|
||||
n = recv(wsi->sock, pkt, sizeof pkt, 0);
|
||||
if (n < 0) {
|
||||
libwebsocket_close_and_free_session(this, wsi);
|
||||
libwebsocket_close_and_free_session(this, wsi,
|
||||
LWS_CLOSE_STATUS_NOSTATUS);
|
||||
fprintf(stderr, "ERROR reading from proxy socket\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
pkt[13] = '\0';
|
||||
if (strcmp(pkt, "HTTP/1.0 200 ") != 0) {
|
||||
libwebsocket_close_and_free_session(this, wsi);
|
||||
libwebsocket_close_and_free_session(this, wsi,
|
||||
LWS_CLOSE_STATUS_NOSTATUS);
|
||||
fprintf(stderr, "ERROR from proxy: %s\n", pkt);
|
||||
return 1;
|
||||
}
|
||||
|
@ -714,21 +721,23 @@ libwebsocket_service_fd(struct libwebsocket_context *this,
|
|||
|
||||
if (SSL_connect(wsi->ssl) <= 0) {
|
||||
fprintf(stderr, "SSL connect error %s\n",
|
||||
ERR_error_string(ERR_get_error(), ssl_err_buf));
|
||||
libwebsocket_close_and_free_session(this, wsi);
|
||||
ERR_error_string(ERR_get_error(),
|
||||
ssl_err_buf));
|
||||
libwebsocket_close_and_free_session(this, wsi,
|
||||
LWS_CLOSE_STATUS_NOSTATUS);
|
||||
return 1;
|
||||
}
|
||||
|
||||
n = SSL_get_verify_result(wsi->ssl);
|
||||
if (n != X509_V_OK) {
|
||||
if (n != X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT ||
|
||||
wsi->use_ssl != 2) {
|
||||
if (n != X509_V_OK) && (
|
||||
n != X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT ||
|
||||
wsi->use_ssl != 2)) {
|
||||
|
||||
fprintf(stderr, "server's cert didn't "
|
||||
"look good %d\n", n);
|
||||
libwebsocket_close_and_free_session(this, wsi);
|
||||
return 1;
|
||||
}
|
||||
fprintf(stderr, "server's cert didn't "
|
||||
"look good %d\n", n);
|
||||
libwebsocket_close_and_free_session(this, wsi,
|
||||
LWS_CLOSE_STATUS_NOSTATUS);
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
wsi->ssl = NULL;
|
||||
|
@ -753,7 +762,8 @@ libwebsocket_service_fd(struct libwebsocket_context *this,
|
|||
free(wsi->c_origin);
|
||||
if (wsi->c_protocol)
|
||||
free(wsi->c_protocol);
|
||||
libwebsocket_close_and_free_session(this, wsi);
|
||||
libwebsocket_close_and_free_session(this, wsi,
|
||||
LWS_CLOSE_STATUS_NOSTATUS);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -819,7 +829,8 @@ libwebsocket_service_fd(struct libwebsocket_context *this,
|
|||
|
||||
if (n < 0) {
|
||||
fprintf(stderr, "ERROR writing to client socket\n");
|
||||
libwebsocket_close_and_free_session(this, wsi);
|
||||
libwebsocket_close_and_free_session(this, wsi,
|
||||
LWS_CLOSE_STATUS_NOSTATUS);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -890,7 +901,7 @@ libwebsocket_service_fd(struct libwebsocket_context *this,
|
|||
(!wsi->utf8_token[WSI_TOKEN_PROTOCOL].token_len &&
|
||||
wsi->c_protocol != NULL)) {
|
||||
fprintf(stderr, "libwebsocket_client_handshake "
|
||||
"missing required header(s)\n");
|
||||
"missing required header(s)\n");
|
||||
pkt[len] = '\0';
|
||||
fprintf(stderr, "%s", pkt);
|
||||
goto bail3;
|
||||
|
@ -1061,7 +1072,8 @@ bail3:
|
|||
free(wsi->c_protocol);
|
||||
|
||||
bail2:
|
||||
libwebsocket_close_and_free_session(this, wsi);
|
||||
libwebsocket_close_and_free_session(this, wsi,
|
||||
LWS_CLOSE_STATUS_NOSTATUS);
|
||||
return 1;
|
||||
|
||||
|
||||
|
@ -1075,7 +1087,8 @@ bail2:
|
|||
fprintf(stderr, "Session Socket %p (fd=%d) dead\n",
|
||||
(void *)wsi, pollfd->fd);
|
||||
|
||||
libwebsocket_close_and_free_session(this, wsi);
|
||||
libwebsocket_close_and_free_session(this, wsi,
|
||||
LWS_CLOSE_STATUS_NOSTATUS);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -1113,7 +1126,8 @@ bail2:
|
|||
break;
|
||||
}
|
||||
if (!n) {
|
||||
libwebsocket_close_and_free_session(this, wsi);
|
||||
libwebsocket_close_and_free_session(this, wsi,
|
||||
LWS_CLOSE_STATUS_NOSTATUS);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -1150,7 +1164,8 @@ libwebsocket_context_destroy(struct libwebsocket_context *this)
|
|||
for (n = 0; n < FD_HASHTABLE_MODULUS; n++)
|
||||
for (m = 0; m < this->fd_hashtable[n].length; m++) {
|
||||
wsi = this->fd_hashtable[n].wsi[m];
|
||||
libwebsocket_close_and_free_session(this, wsi);
|
||||
libwebsocket_close_and_free_session(this, wsi,
|
||||
LWS_CLOSE_STATUS_GOINGAWAY);
|
||||
}
|
||||
|
||||
close(this->fd_random);
|
||||
|
|
|
@ -123,6 +123,45 @@ enum lws_token_indexes {
|
|||
WSI_PARSING_COMPLETE
|
||||
};
|
||||
|
||||
/*
|
||||
* From 06 sped
|
||||
1000
|
||||
|
||||
1000 indicates a normal closure, meaning whatever purpose the
|
||||
connection was established for has been fulfilled.
|
||||
|
||||
1001
|
||||
|
||||
1001 indicates that an endpoint is "going away", such as a server
|
||||
going down, or a browser having navigated away from a page.
|
||||
|
||||
1002
|
||||
|
||||
1002 indicates that an endpoint is terminating the connection due
|
||||
to a protocol error.
|
||||
|
||||
1003
|
||||
|
||||
1003 indicates that an endpoint is terminating the connection
|
||||
because it has received a type of data it cannot accept (e.g. an
|
||||
endpoint that understands only text data may send this if it
|
||||
receives a binary message.)
|
||||
|
||||
1004
|
||||
|
||||
1004 indicates that an endpoint is terminating the connection
|
||||
because it has received a message that is too large.
|
||||
*/
|
||||
|
||||
enum lws_close_status {
|
||||
LWS_CLOSE_STATUS_NOSTATUS = 0,
|
||||
LWS_CLOSE_STATUS_NORMAL = 1000,
|
||||
LWS_CLOSE_STATUS_GOINGAWAY = 1001,
|
||||
LWS_CLOSE_STATUS_PROTOCOL_ERR = 1002,
|
||||
LWS_CLOSE_STATUS_UNACCEPTABLE_OPCODE = 1003,
|
||||
LWS_CLOSE_STATUS_PAYLOAD_TOO_LARGE = 1004,
|
||||
};
|
||||
|
||||
struct libwebsocket;
|
||||
struct libwebsocket_context;
|
||||
|
||||
|
@ -367,7 +406,11 @@ libwebsocket_service_fd(struct libwebsocket_context *context,
|
|||
* use the whole buffer without taking care of the above.
|
||||
*/
|
||||
|
||||
/* this is the frame nonce plus two header plus 8 length */
|
||||
/*
|
||||
* this is the frame nonce plus two header plus 8 length
|
||||
* 2 byte prepend on close will already fit because control frames cannot use
|
||||
* the big length style
|
||||
*/
|
||||
|
||||
#define LWS_SEND_BUFFER_PRE_PADDING (4 + 10)
|
||||
#define LWS_SEND_BUFFER_POST_PADDING 1
|
||||
|
@ -430,6 +473,6 @@ libwebsockets_hangup_on_client(struct libwebsocket_context *context, int fd);
|
|||
|
||||
extern void
|
||||
libwebsocket_close_and_free_session(struct libwebsocket_context *context,
|
||||
struct libwebsocket *wsi);
|
||||
struct libwebsocket *wsi, enum lws_close_status);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1139,8 +1139,11 @@ int libwebsocket_write(struct libwebsocket *wsi, unsigned char *buf,
|
|||
* in both client and server directions
|
||||
*/
|
||||
|
||||
if (wsi->ietf_spec_revision >= 5) {
|
||||
|
||||
switch (wsi->ietf_spec_revision) {
|
||||
case 0:
|
||||
case 4:
|
||||
break;
|
||||
case 5:
|
||||
/* we can do this because we demand post-buf */
|
||||
|
||||
if (len < 1)
|
||||
|
@ -1162,6 +1165,19 @@ int libwebsocket_write(struct libwebsocket *wsi, unsigned char *buf,
|
|||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
* 06 has a 2-byte status code in network order
|
||||
* we can do this because we demand post-buf
|
||||
*/
|
||||
|
||||
if (wsi->close_reason) {
|
||||
buf[pre - 2] = wsi->close_reason >> 8;
|
||||
buf[pre - 1] = wsi->close_reason;
|
||||
pre += 2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case LWS_WRITE_PING:
|
||||
|
@ -1181,35 +1197,35 @@ int libwebsocket_write(struct libwebsocket *wsi, unsigned char *buf,
|
|||
n |= 1 << 7;
|
||||
|
||||
if (len < 126) {
|
||||
buf[-2] = n;
|
||||
buf[-1] = len;
|
||||
pre = 2;
|
||||
buf[pre - 2] = n;
|
||||
buf[pre - 1] = len;
|
||||
pre += 2;
|
||||
} else {
|
||||
if (len < 65536) {
|
||||
buf[-4] = n;
|
||||
buf[-3] = 126;
|
||||
buf[-2] = len >> 8;
|
||||
buf[-1] = len;
|
||||
pre = 4;
|
||||
buf[pre - 4] = n;
|
||||
buf[pre - 3] = 126;
|
||||
buf[pre - 2] = len >> 8;
|
||||
buf[pre - 1] = len;
|
||||
pre += 4;
|
||||
} else {
|
||||
buf[-10] = n;
|
||||
buf[-9] = 127;
|
||||
buf[pre - 10] = n;
|
||||
buf[pre - 9] = 127;
|
||||
#if defined __LP64__
|
||||
buf[-8] = (len >> 56) & 0x7f;
|
||||
buf[-7] = len >> 48;
|
||||
buf[-6] = len >> 40;
|
||||
buf[-5] = len >> 32;
|
||||
buf[pre - 8] = (len >> 56) & 0x7f;
|
||||
buf[pre - 7] = len >> 48;
|
||||
buf[pre - 6] = len >> 40;
|
||||
buf[pre - 5] = len >> 32;
|
||||
#else
|
||||
buf[-8] = 0;
|
||||
buf[-7] = 0;
|
||||
buf[-6] = 0;
|
||||
buf[-5] = 0;
|
||||
buf[pre - 8] = 0;
|
||||
buf[pre - 7] = 0;
|
||||
buf[pre - 6] = 0;
|
||||
buf[pre - 5] = 0;
|
||||
#endif
|
||||
buf[-4] = len >> 24;
|
||||
buf[-3] = len >> 16;
|
||||
buf[-2] = len >> 8;
|
||||
buf[-1] = len;
|
||||
pre = 10;
|
||||
buf[pre - 4] = len >> 24;
|
||||
buf[pre - 3] = len >> 16;
|
||||
buf[pre - 2] = len >> 8;
|
||||
buf[pre - 1] = len;
|
||||
pre += 10;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -93,44 +93,6 @@ static inline void debug(const char *format, ...)
|
|||
#define MAX_WEBSOCKET_04_KEY_LEN 128
|
||||
#define SYSTEM_RANDOM_FILEPATH "/dev/urandom"
|
||||
|
||||
/*
|
||||
* From 06 sped
|
||||
1000
|
||||
|
||||
1000 indicates a normal closure, meaning whatever purpose the
|
||||
connection was established for has been fulfilled.
|
||||
|
||||
1001
|
||||
|
||||
1001 indicates that an endpoint is "going away", such as a server
|
||||
going down, or a browser having navigated away from a page.
|
||||
|
||||
1002
|
||||
|
||||
1002 indicates that an endpoint is terminating the connection due
|
||||
to a protocol error.
|
||||
|
||||
1003
|
||||
|
||||
1003 indicates that an endpoint is terminating the connection
|
||||
because it has received a type of data it cannot accept (e.g. an
|
||||
endpoint that understands only text data may send this if it
|
||||
receives a binary message.)
|
||||
|
||||
1004
|
||||
|
||||
1004 indicates that an endpoint is terminating the connection
|
||||
because it has received a message that is too large.
|
||||
*/
|
||||
|
||||
enum lws_close_status {
|
||||
LWS_CLOSE_STATUS_NORMAL = 1000,
|
||||
LWS_CLOSE_STATUS_GOINGAWAY = 1001,
|
||||
LWS_CLOSE_STATUS_PROTOCOL_ERR = 1002,
|
||||
LWS_CLOSE_STATUS_UNACCEPTABLE_OPCODE = 1003,
|
||||
LWS_CLOSE_STATUS_PAYLOAD_TOO_LARGE = 1004,
|
||||
};
|
||||
|
||||
enum lws_websocket_opcodes_04 {
|
||||
LWS_WS_OPCODE_04__CONTINUATION = 0,
|
||||
LWS_WS_OPCODE_04__CLOSE = 1,
|
||||
|
@ -278,6 +240,8 @@ struct libwebsocket {
|
|||
unsigned char (*xor_mask)(struct libwebsocket *, unsigned char);
|
||||
char all_zero_nonce;
|
||||
|
||||
enum lws_close_status close_reason;
|
||||
|
||||
/* client support */
|
||||
char initial_handshake_hash_base64[30];
|
||||
enum connection_mode mode;
|
||||
|
|
Loading…
Add table
Reference in a new issue