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 registered; ///< The user has registered
|
||||
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_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;
|
||||
|
||||
if (c->ssl)
|
||||
// Note that we might have already called this once, but that is fine
|
||||
(void) SSL_shutdown (c->ssl);
|
||||
|
||||
xclose (c->socket_fd);
|
||||
|
||||
c->socket_event.closed = true;
|
||||
@ -2620,8 +2623,27 @@ on_client_ready (const struct pollfd *pfd, void *user_data)
|
||||
client_update_poller (c, pfd);
|
||||
|
||||
// The purpose of the `closing_link' state is to transfer the `ERROR'
|
||||
if (c->closing_link && !c->write_buffer.len)
|
||||
client_kill (c, NULL);
|
||||
if (c->closing_link && !c->half_closed && !c->write_buffer.len)
|
||||
{
|
||||
// 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
|
||||
|
Loading…
Reference in New Issue
Block a user