Ejemplo n.º 1
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;
}
Ejemplo n.º 2
0
int64_t s2n_connection_get_delay(struct s2n_connection *conn)
{
    if (!conn->delay) { return 0; }

    uint64_t elapsed;
    GUARD(s2n_timer_elapsed(conn->config, &conn->write_timer, &elapsed));

    if (elapsed > conn->delay) { return 0; }

    return conn->delay - elapsed;
}
Ejemplo n.º 3
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;
}
Ejemplo n.º 4
0
int main(int argc, char **argv)
{
    struct s2n_timer timer;
    uint64_t nanoseconds;

    BEGIN_TEST();

    /* First: Perform some tests using the real clock */
    EXPECT_SUCCESS(s2n_timer_start(&timer));
    EXPECT_SUCCESS(s2n_timer_reset(&timer, &nanoseconds));
    EXPECT_TRUE(nanoseconds < 1000000000);
    EXPECT_SUCCESS(s2n_timer_elapsed(&timer, &nanoseconds));
    EXPECT_TRUE(nanoseconds < 1000000000);
    EXPECT_SUCCESS(sleep(1));
    EXPECT_SUCCESS(s2n_timer_reset(&timer, &nanoseconds));
    EXPECT_TRUE(nanoseconds > 1000000000);
    EXPECT_TRUE(nanoseconds < 2000000000);
    EXPECT_SUCCESS(sleep(1));
    EXPECT_SUCCESS(s2n_timer_elapsed(&timer, &nanoseconds));
    EXPECT_TRUE(nanoseconds > 1000000000);
    EXPECT_TRUE(nanoseconds < 2000000000);

#if !defined(__APPLE__) || !defined(__MACH__)
    /* Next: perform some tests around timespec boundaries */

    /* Pretend that there were 999,999,999 nanoseconds elapsed in the
     * previously measured instant. Keep reseting the timer until
     * the second progresses from that instant, and there are also
     * less than 999,999,999 nanoseconds elapsed.
     *
     * This sets up a situation in which the tv_sec field causes time
     * to move "forwards", and tv_nsec causes it to move backwards.
     * e.g.
     *
     * previous_time = 10
     *
     * timer.time.tv_sec = 11
     * timer.time.tv_nsec = 123456789;
     *
     * delta will be:
     *   (11 - 10) * 1000000000
     * + (123456789 - 999999999)
     *
     * = 123456790 (same as 1 + 123456789)
     */
    time_t previous_time;
    do {
        previous_time = timer.time.tv_sec;
        timer.time.tv_nsec = 999999999;

        EXPECT_SUCCESS(s2n_timer_reset(&timer, &nanoseconds));
    }
    while(previous_time != (timer.time.tv_sec - 1) || timer.time.tv_nsec == 999999999);

    EXPECT_TRUE(nanoseconds < 1000000000);
    EXPECT_TRUE(nanoseconds == 1 + timer.time.tv_nsec);

    /* Now we perform the oppossite test: make sure that the previous value for
     * nsec is smaller than the later one */
    do {
        previous_time = timer.time.tv_sec;
        timer.time.tv_nsec = 0;

        EXPECT_SUCCESS(s2n_timer_reset(&timer, &nanoseconds));
    }
    while(previous_time != (timer.time.tv_sec - 1) || timer.time.tv_nsec == 0);

    EXPECT_TRUE(nanoseconds > 1000000000);
    EXPECT_TRUE(nanoseconds < 2000000000);
    EXPECT_TRUE(nanoseconds == 1000000000 + timer.time.tv_nsec);
#endif

    END_TEST();
}