kike: be more careful when closing the connection
This commit is contained in:
parent
2dd191376f
commit
94d4f060ff
26
kike.c
26
kike.c
@ -311,6 +311,7 @@ struct client
|
|||||||
bool initialized; ///< Has any data been received yet?
|
bool initialized; ///< Has any data been received yet?
|
||||||
bool registered; ///< The user has registered
|
bool registered; ///< The user has registered
|
||||||
bool closing_link; ///< Closing link
|
bool closing_link; ///< Closing link
|
||||||
|
bool half_closed; ///< Closing link: conn. is half-closed
|
||||||
|
|
||||||
bool ssl_rx_want_tx; ///< SSL_read() wants to write
|
bool ssl_rx_want_tx; ///< SSL_read() wants to write
|
||||||
bool ssl_tx_want_rx; ///< SSL_write() wants to read
|
bool ssl_tx_want_rx; ///< SSL_write() wants to read
|
||||||
@ -787,7 +788,9 @@ client_kill (struct client *c, const char *reason)
|
|||||||
struct server_context *ctx = c->ctx;
|
struct server_context *ctx = c->ctx;
|
||||||
|
|
||||||
if (c->ssl)
|
if (c->ssl)
|
||||||
|
// Note that we might have already called this once, but that is fine
|
||||||
(void) SSL_shutdown (c->ssl);
|
(void) SSL_shutdown (c->ssl);
|
||||||
|
|
||||||
xclose (c->socket_fd);
|
xclose (c->socket_fd);
|
||||||
|
|
||||||
c->socket_event.closed = true;
|
c->socket_event.closed = true;
|
||||||
@ -2620,8 +2623,27 @@ on_client_ready (const struct pollfd *pfd, void *user_data)
|
|||||||
client_update_poller (c, pfd);
|
client_update_poller (c, pfd);
|
||||||
|
|
||||||
// The purpose of the `closing_link' state is to transfer the `ERROR'
|
// The purpose of the `closing_link' state is to transfer the `ERROR'
|
||||||
if (c->closing_link && !c->write_buffer.len)
|
if (c->closing_link && !c->half_closed && !c->write_buffer.len)
|
||||||
client_kill (c, NULL);
|
{
|
||||||
|
// To make sure the client has received our ERROR message, we must
|
||||||
|
// first half-close the connection, otherwise it could happen that they
|
||||||
|
// receive a RST from our TCP stack first when we receive further data
|
||||||
|
|
||||||
|
// We only send the "close notify" alert if libssl can write to the
|
||||||
|
// socket at this moment. All the other data has been already written,
|
||||||
|
// though, and the client will receive a TCP half-close as usual, so
|
||||||
|
// it's not that important if the alert actually gets through.
|
||||||
|
if (c->ssl)
|
||||||
|
(void) SSL_shutdown (c->ssl);
|
||||||
|
|
||||||
|
// Either the shutdown succeeds, in which case we set a flag so that
|
||||||
|
// we don't retry this action and wait until we get an EOF, or it fails
|
||||||
|
// and we just kill the client straight away
|
||||||
|
if (!shutdown (c->socket_fd, SHUT_WR))
|
||||||
|
c->half_closed = true;
|
||||||
|
else
|
||||||
|
client_kill (c, NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
Loading…
Reference in New Issue
Block a user