static void shutdown_ssl(h2o_socket_t *sock, int status) { int ret; if (status != 0) goto Close; if ((ret = SSL_shutdown(sock->ssl->ssl)) == -1) { goto Close; } if (sock->ssl->output.bufs.size != 0) { h2o_socket_read_stop(sock); flush_pending_ssl(sock, ret == 1 ? dispose_socket : shutdown_ssl); } else if (ret == 2 && SSL_get_error(sock->ssl->ssl, ret) == SSL_ERROR_WANT_READ) { h2o_socket_read_start(sock, shutdown_ssl); } else { status = ret == 1; goto Close; } return; Close: dispose_socket(sock, status); }
static void shutdown_ssl(h2o_socket_t *sock, const char *err) { int ret; if (err != NULL) goto Close; if (sock->_cb.write != NULL) { /* note: libuv calls the write callback after the socket is closed by uv_close (with status set to 0 if the write succeeded) */ sock->_cb.write = NULL; goto Close; } if ((ret = SSL_shutdown(sock->ssl->ssl)) == -1) { goto Close; } if (sock->ssl->output.bufs.size != 0) { h2o_socket_read_stop(sock); flush_pending_ssl(sock, ret == 1 ? dispose_socket : shutdown_ssl); } else if (ret == 2 && SSL_get_error(sock->ssl->ssl, ret) == SSL_ERROR_WANT_READ) { h2o_socket_read_start(sock, shutdown_ssl); } else { goto Close; } return; Close: dispose_socket(sock, err); }
void h2o_socket_close(h2o_socket_t *sock) { if (sock->ssl == NULL) { dispose_socket(sock, 0); } else { shutdown_ssl(sock, 0); } }