int s2n_shutdown(struct s2n_connection *conn, int *more) { /* Write any pending I/O */ GUARD(s2n_flush(conn, more)); GUARD(s2n_queue_writer_close_alert(conn)); /* Write the alert message out */ GUARD(s2n_flush(conn, more)); /* Wipe the connection */ GUARD(s2n_connection_wipe(conn)); return 0; }
int s2n_shutdown(struct s2n_connection *conn, s2n_blocked_status * more) { notnull_check(conn); notnull_check(more); /* Treat this call as a no-op if already wiped */ if (conn->send == NULL && conn->recv == NULL) { return 0; } uint64_t elapsed; GUARD(s2n_timer_elapsed(conn->config, &conn->write_timer, &elapsed)); S2N_ERROR_IF(elapsed < conn->delay, S2N_ERR_SHUTDOWN_PAUSED); /* Queue our close notify, once. Use warning level so clients don't give up */ GUARD(s2n_queue_writer_close_alert_warning(conn)); /* Write it */ GUARD(s2n_flush(conn, more)); /* Assume caller isn't interested in pending incoming data */ if (conn->in_status == PLAINTEXT) { GUARD(s2n_stuffer_wipe(&conn->header_in)); GUARD(s2n_stuffer_wipe(&conn->in)); conn->in_status = ENCRYPTED; } /* Fails with S2N_ERR_SHUTDOWN_RECORD_TYPE or S2N_ERR_ALERT on receipt of anything but a close_notify */ GUARD(s2n_recv_close_notify(conn, more)); return 0; }
int s2n_shutdown(struct s2n_connection *conn, s2n_blocked_status *more) { uint64_t elapsed; GUARD(s2n_timer_elapsed(conn->config, &conn->write_timer, &elapsed)); if (elapsed < conn->delay) { S2N_ERROR(S2N_ERR_SHUTDOWN_PAUSED); } /* Write any pending I/O */ GUARD(s2n_flush(conn, more)); GUARD(s2n_queue_writer_close_alert(conn)); /* Write the alert message out */ GUARD(s2n_flush(conn, more)); /* Wipe the connection */ GUARD(s2n_connection_wipe(conn)); return 0; }