/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/*
 * DTLS Protocol
 */

#include "ssl.h"
#include "sslimpl.h"
#include "sslproto.h"
#include "dtls13con.h"

#ifndef PR_ARRAY_SIZE
#define PR_ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
#endif

static SECStatus dtls_StartRetransmitTimer(sslSocket *ss);
static void dtls_RetransmitTimerExpiredCb(sslSocket *ss);
static SECStatus dtls_SendSavedWriteData(sslSocket *ss);
static void dtls_FinishedTimerCb(sslSocket *ss);
static void dtls_CancelAllTimers(sslSocket *ss);

/* -28 adjusts for the IP/UDP header */
static const PRUint16 COMMON_MTU_VALUES[] = {
    1500 - 28, /* Ethernet MTU */
    1280 - 28, /* IPv6 minimum MTU */
    576 - 28,  /* Common assumption */
    256 - 28   /* We're in serious trouble now */
};

#define DTLS_COOKIE_BYTES 32
/* Maximum DTLS expansion = header + IV + max CBC padding +
 * maximum MAC. */
#define DTLS_MAX_EXPANSION (DTLS_RECORD_HEADER_LENGTH + 16 + 16 + 32)

/* List copied from ssl3con.c:cipherSuites */
static const ssl3CipherSuite nonDTLSSuites[] = {
    TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
    TLS_ECDHE_RSA_WITH_RC4_128_SHA,
    TLS_DHE_DSS_WITH_RC4_128_SHA,
    TLS_ECDH_RSA_WITH_RC4_128_SHA,
    TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
    TLS_RSA_WITH_RC4_128_MD5,
    TLS_RSA_WITH_RC4_128_SHA,
    0 /* End of list marker */
};

/* Map back and forth between TLS and DTLS versions in wire format.
 * Mapping table is:
 *
 * TLS             DTLS
 * 1.1 (0302)      1.0 (feff)
 * 1.2 (0303)      1.2 (fefd)
 * 1.3 (0304)      1.3 (fefc)
 */
SSL3ProtocolVersion
dtls_TLSVersionToDTLSVersion(SSL3ProtocolVersion tlsv)
{
    if (tlsv == SSL_LIBRARY_VERSION_TLS_1_1) {
        return SSL_LIBRARY_VERSION_DTLS_1_0_WIRE;
    }
    if (tlsv == SSL_LIBRARY_VERSION_TLS_1_2) {
        return SSL_LIBRARY_VERSION_DTLS_1_2_WIRE;
    }
    if (tlsv == SSL_LIBRARY_VERSION_TLS_1_3) {
        return SSL_LIBRARY_VERSION_DTLS_1_3_WIRE;
    }

    /* Anything other than TLS 1.1 or 1.2 is an error, so return
     * the invalid version 0xffff. */
    return 0xffff;
}

/* Map known DTLS versions to known TLS versions.
 * - Invalid versions (< 1.0) return a version of 0
 * - Versions > known return a version one higher than we know of
 * to accomodate a theoretically newer version */
SSL3ProtocolVersion
dtls_DTLSVersionToTLSVersion(SSL3ProtocolVersion dtlsv)
{
    if (MSB(dtlsv) == 0xff) {
        return 0;
    }

    if (dtlsv == SSL_LIBRARY_VERSION_DTLS_1_0_WIRE) {
        return SSL_LIBRARY_VERSION_TLS_1_1;
    }
    /* Handle the skipped version of DTLS 1.1 by returning
     * an error. */
    if (dtlsv == ((~0x0101) & 0xffff)) {
        return 0;
    }
    if (dtlsv == SSL_LIBRARY_VERSION_DTLS_1_2_WIRE) {
        return SSL_LIBRARY_VERSION_TLS_1_2;
    }
    if (dtlsv == SSL_LIBRARY_VERSION_DTLS_1_3_WIRE) {
        return SSL_LIBRARY_VERSION_TLS_1_3;
    }

    /* Return a fictional higher version than we know of */
    return SSL_LIBRARY_VERSION_MAX_SUPPORTED + 1;
}

/* On this socket, Disable non-DTLS cipher suites in the argument's list */
SECStatus
ssl3_DisableNonDTLSSuites(sslSocket *ss)
{
    const ssl3CipherSuite *suite;

    for (suite = nonDTLSSuites; *suite; ++suite) {
        PORT_CheckSuccess(ssl3_CipherPrefSet(ss, *suite, PR_FALSE));
    }
    return SECSuccess;
}

/* Allocate a DTLSQueuedMessage.
 *
 * Called from dtls_QueueMessage()
 */
static DTLSQueuedMessage *
dtls_AllocQueuedMessage(ssl3CipherSpec *cwSpec, SSLContentType ct,
                        const unsigned char *data, PRUint32 len)
{
    DTLSQueuedMessage *msg;

    msg = PORT_ZNew(DTLSQueuedMessage);
    if (!msg)
        return NULL;

    msg->data = PORT_Alloc(len);
    if (!msg->data) {
        PORT_Free(msg);
        return NULL;
    }
    PORT_Memcpy(msg->data, data, len);

    msg->len = len;
    msg->cwSpec = cwSpec;
    msg->type = ct;
    /* Safe if we are < 1.3, since the refct is
     * already very high. */
    ssl_CipherSpecAddRef(cwSpec);

    return msg;
}

/*
 * Free a handshake message
 *
 * Called from dtls_FreeHandshakeMessages()
 */
void
dtls_FreeHandshakeMessage(DTLSQueuedMessage *msg)
{
    if (!msg)
        return;

    /* Safe if we are < 1.3, since the refct is
     * already very high. */
    ssl_CipherSpecRelease(msg->cwSpec);
    PORT_ZFree(msg->data, msg->len);
    PORT_Free(msg);
}

/*
 * Free a list of handshake messages
 *
 * Called from:
 *              dtls_HandleHandshake()
 *              ssl3_DestroySSL3Info()
 */
void
dtls_FreeHandshakeMessages(PRCList *list)
{
    PRCList *cur_p;

    while (!PR_CLIST_IS_EMPTY(list)) {
        cur_p = PR_LIST_TAIL(list);
        PR_REMOVE_LINK(cur_p);
        dtls_FreeHandshakeMessage((DTLSQueuedMessage *)cur_p);
    }
}

/* Called by dtls_HandleHandshake() and dtls_MaybeRetransmitHandshake() if a
 * handshake message retransmission is detected. */
static SECStatus
dtls_RetransmitDetected(sslSocket *ss)
{
    dtlsTimer *timer = ss->ssl3.hs.rtTimer;
    SECStatus rv = SECSuccess;

    PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
    PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));

    if (timer->cb == dtls_RetransmitTimerExpiredCb) {
        /* Check to see if we retransmitted recently. If so,
         * suppress the triggered retransmit. This avoids
         * retransmit wars after packet loss.
         * This is not in RFC 5346 but it should be.
         */
        if ((PR_IntervalNow() - timer->started) >
            (timer->timeout / 4)) {
            SSL_TRC(30,
                    ("%d: SSL3[%d]: Shortcutting retransmit timer",
                     SSL_GETPID(), ss->fd));

            /* Cancel the timer and call the CB,
             * which re-arms the timer */
            dtls_CancelTimer(ss, ss->ssl3.hs.rtTimer);
            dtls_RetransmitTimerExpiredCb(ss);
        } else {
            SSL_TRC(30,
                    ("%d: SSL3[%d]: Ignoring retransmission: "
                     "last retransmission %dms ago, suppressed for %dms",
                     SSL_GETPID(), ss->fd,
                     PR_IntervalNow() - timer->started,
                     timer->timeout / 4));
        }

    } else if (timer->cb == dtls_FinishedTimerCb) {
        SSL_TRC(30, ("%d: SSL3[%d]: Retransmit detected in holddown",
                     SSL_GETPID(), ss->fd));
        /* Retransmit the messages and re-arm the timer
         * Note that we are not backing off the timer here.
         * The spec isn't clear and my reasoning is that this
         * may be a re-ordered packet rather than slowness,
         * so let's be aggressive. */
        dtls_CancelTimer(ss, ss->ssl3.hs.rtTimer);
        rv = dtls_TransmitMessageFlight(ss);
        if (rv == SECSuccess) {
            rv = dtls_StartHolddownTimer(ss);
        }

    } else {
        PORT_Assert(timer->cb == NULL);
        /* ... and ignore it. */
    }
    return rv;
}

static SECStatus
dtls_HandleHandshakeMessage(sslSocket *ss, PRUint8 *data, PRBool last)
{
    ss->ssl3.hs.recvdHighWater = -1;

    return ssl3_HandleHandshakeMessage(ss, data, ss->ssl3.hs.msg_len,
                                       last);
}

/* Called only from ssl3_HandleRecord, for each (deciphered) DTLS record.
 * origBuf is the decrypted ssl record content and is expected to contain
 * complete handshake records
 * Caller must hold the handshake and RecvBuf locks.
 *
 * Note that this code uses msg_len for two purposes:
 *
 * (1) To pass the length to ssl3_HandleHandshakeMessage()
 * (2) To carry the length of a message currently being reassembled
 *
 * However, unlike ssl3_HandleHandshake(), it is not used to carry
 * the state of reassembly (i.e., whether one is in progress). That
 * is carried in recvdHighWater and recvdFragments.
 */
#define OFFSET_BYTE(o) (o / 8)
#define OFFSET_MASK(o) (1 << (o % 8))

SECStatus
dtls_HandleHandshake(sslSocket *ss, DTLSEpoch epoch, sslSequenceNumber seqNum,
                     sslBuffer *origBuf)
{
    /* XXX OK for now.
     * This doesn't work properly with asynchronous certificate validation.
     * because that returns a WOULDBLOCK error. The current DTLS
     * applications do not need asynchronous validation, but in the
     * future we will need to add this.
     */
    sslBuffer buf = *origBuf;
    SECStatus rv = SECSuccess;
    PRBool discarded = PR_FALSE;

    ss->ssl3.hs.endOfFlight = PR_FALSE;

    PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
    PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));

    while (buf.len > 0) {
        PRUint8 type;
        PRUint32 message_length;
        PRUint16 message_seq;
        PRUint32 fragment_offset;
        PRUint32 fragment_length;
        PRUint32 offset;

        if (buf.len < 12) {
            PORT_SetError(SSL_ERROR_RX_MALFORMED_HANDSHAKE);
            rv = SECFailure;
            goto loser;
        }

        /* Parse the header */
        type = buf.buf[0];
        message_length = (buf.buf[1] << 16) | (buf.buf[2] << 8) | buf.buf[3];
        message_seq = (buf.buf[4] << 8) | buf.buf[5];
        fragment_offset = (buf.buf[6] << 16) | (buf.buf[7] << 8) | buf.buf[8];
        fragment_length = (buf.buf[9] << 16) | (buf.buf[10] << 8) | buf.buf[11];

#define MAX_HANDSHAKE_MSG_LEN 0x1ffff /* 128k - 1 */
        if (message_length > MAX_HANDSHAKE_MSG_LEN) {
            (void)ssl3_DecodeError(ss);
            PORT_SetError(SSL_ERROR_RX_MALFORMED_HANDSHAKE);
            return SECFailure;
        }
#undef MAX_HANDSHAKE_MSG_LEN

        buf.buf += 12;
        buf.len -= 12;

        /* This fragment must be complete */
        if (buf.len < fragment_length) {
            PORT_SetError(SSL_ERROR_RX_MALFORMED_HANDSHAKE);
            rv = SECFailure;
            goto loser;
        }

        /* Sanity check the packet contents */
        if ((fragment_length + fragment_offset) > message_length) {
            PORT_SetError(SSL_ERROR_RX_MALFORMED_HANDSHAKE);
            rv = SECFailure;
            goto loser;
        }

        /* If we're a server and we receive what appears to be a retried
         * ClientHello, and we are expecting a ClientHello, move the receive
         * sequence number forward.  This allows for a retried ClientHello if we
         * send a stateless HelloRetryRequest. */
        if (message_seq > ss->ssl3.hs.recvMessageSeq &&
            message_seq == 1 &&
            fragment_offset == 0 &&
            ss->ssl3.hs.ws == wait_client_hello &&
            (SSLHandshakeType)type == ssl_hs_client_hello) {
            SSL_TRC(5, ("%d: DTLS[%d]: Received apparent 2nd ClientHello",
                        SSL_GETPID(), ss->fd));
            ss->ssl3.hs.recvMessageSeq = 1;
        }

        /* There are three ways we could not be ready for this packet.
         *
         * 1. It's a partial next message.
         * 2. It's a partial or complete message beyond the next
         * 3. It's a message we've already seen
         *
         * If it's the complete next message we accept it right away.
         * This is the common case for short messages
         */
        if ((message_seq == ss->ssl3.hs.recvMessageSeq) &&
            (fragment_offset == 0) &&
            (fragment_length == message_length)) {
            /* Complete next message. Process immediately */
            ss->ssl3.hs.msg_type = (SSLHandshakeType)type;
            ss->ssl3.hs.msg_len = message_length;

            rv = dtls_HandleHandshakeMessage(ss, buf.buf,
                                             buf.len == fragment_length);
            if (rv == SECFailure) {
                goto loser;
            }
        } else {
            if (message_seq < ss->ssl3.hs.recvMessageSeq) {
                /* Case 3: we do an immediate retransmit if we're
                 * in a waiting state. */
                rv = dtls_RetransmitDetected(ss);
                goto loser;
            } else if (message_seq > ss->ssl3.hs.recvMessageSeq) {
                /* Case 2
                 *
                 * Ignore this message. This means we don't handle out of
                 * order complete messages that well, but we're still
                 * compliant and this probably does not happen often
                 *
                 * XXX OK for now. Maybe do something smarter at some point?
                 */
                SSL_TRC(10, ("%d: SSL3[%d]: dtls_HandleHandshake, discarding handshake message",
                             SSL_GETPID(), ss->fd));
                discarded = PR_TRUE;
            } else {
                PRInt32 end = fragment_offset + fragment_length;

                /* Case 1
                 *
                 * Buffer the fragment for reassembly
                 */
                /* Make room for the message */
                if (ss->ssl3.hs.recvdHighWater == -1) {
                    PRUint32 map_length = OFFSET_BYTE(message_length) + 1;

                    rv = sslBuffer_Grow(&ss->ssl3.hs.msg_body, message_length);
                    if (rv != SECSuccess)
                        goto loser;
                    /* Make room for the fragment map */
                    rv = sslBuffer_Grow(&ss->ssl3.hs.recvdFragments,
                                        map_length);
                    if (rv != SECSuccess)
                        goto loser;

                    /* Reset the reassembly map */
                    ss->ssl3.hs.recvdHighWater = 0;
                    PORT_Memset(ss->ssl3.hs.recvdFragments.buf, 0,
                                ss->ssl3.hs.recvdFragments.space);
                    ss->ssl3.hs.msg_type = (SSLHandshakeType)type;
                    ss->ssl3.hs.msg_len = message_length;
                }

                /* If we have a message length mismatch, abandon the reassembly
                 * in progress and hope that the next retransmit will give us
                 * something sane
                 */
                if (message_length != ss->ssl3.hs.msg_len) {
                    ss->ssl3.hs.recvdHighWater = -1;
                    PORT_SetError(SSL_ERROR_RX_MALFORMED_HANDSHAKE);
                    rv = SECFailure;
                    goto loser;
                }

                /* Now copy this fragment into the buffer. */
                if (end > ss->ssl3.hs.recvdHighWater) {
                    PORT_Memcpy(ss->ssl3.hs.msg_body.buf + fragment_offset,
                                buf.buf, fragment_length);
                }

                /* This logic is a bit tricky. We have two values for
                 * reassembly state:
                 *
                 * - recvdHighWater contains the highest contiguous number of
                 *   bytes received
                 * - recvdFragments contains a bitmask of packets received
                 *   above recvdHighWater
                 *
                 * This avoids having to fill in the bitmask in the common
                 * case of adjacent fragments received in sequence
                 */
                if (fragment_offset <= (unsigned int)ss->ssl3.hs.recvdHighWater) {
                    /* Either this is the adjacent fragment or an overlapping
                     * fragment */
                    if (end > ss->ssl3.hs.recvdHighWater) {
                        ss->ssl3.hs.recvdHighWater = end;
                    }
                } else {
                    for (offset = fragment_offset; offset < end; offset++) {
                        ss->ssl3.hs.recvdFragments.buf[OFFSET_BYTE(offset)] |=
                            OFFSET_MASK(offset);
                    }
                }

                /* Now figure out the new high water mark if appropriate */
                for (offset = ss->ssl3.hs.recvdHighWater;
                     offset < ss->ssl3.hs.msg_len; offset++) {
                    /* Note that this loop is not efficient, since it counts
                     * bit by bit. If we have a lot of out-of-order packets,
                     * we should optimize this */
                    if (ss->ssl3.hs.recvdFragments.buf[OFFSET_BYTE(offset)] &
                        OFFSET_MASK(offset)) {
                        ss->ssl3.hs.recvdHighWater++;
                    } else {
                        break;
                    }
                }

                /* If we have all the bytes, then we are good to go */
                if (ss->ssl3.hs.recvdHighWater == ss->ssl3.hs.msg_len) {
                    rv = dtls_HandleHandshakeMessage(ss, ss->ssl3.hs.msg_body.buf,
                                                     buf.len == fragment_length);

                    if (rv == SECFailure) {
                        goto loser;
                    }
                }
            }
        }

        buf.buf += fragment_length;
        buf.len -= fragment_length;
    }

    // This should never happen, but belt and suspenders.
    if (rv == SECFailure) {
        PORT_Assert(0);
        goto loser;
    }

    /* If we processed all the fragments in this message, then mark it as remembered.
     * TODO(ekr@rtfm.com): Store out of order messages for DTLS 1.3 so ACKs work
     * better. Bug 1392620.*/
    if (!discarded && tls13_MaybeTls13(ss)) {
        rv = dtls13_RememberFragment(ss, &ss->ssl3.hs.dtlsRcvdHandshake,
                                     0, 0, 0, epoch, seqNum);
    }
    if (rv != SECSuccess) {
        goto loser;
    }

    rv = dtls13_SetupAcks(ss);

loser:
    origBuf->len = 0; /* So ssl3_GatherAppDataRecord will keep looping. */

    /* XXX OK for now. In future handle rv == SECWouldBlock safely in order
     * to deal with asynchronous certificate verification */
    return rv;
}

/* Enqueue a message (either handshake or CCS)
 *
 * Called from:
 *              dtls_StageHandshakeMessage()
 *              ssl3_SendChangeCipherSpecs()
 */
SECStatus
dtls_QueueMessage(sslSocket *ss, SSLContentType ct,
                  const PRUint8 *pIn, PRInt32 nIn)
{
    SECStatus rv = SECSuccess;
    DTLSQueuedMessage *msg = NULL;
    ssl3CipherSpec *spec;

    PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
    PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));

    spec = ss->ssl3.cwSpec;
    msg = dtls_AllocQueuedMessage(spec, ct, pIn, nIn);

    if (!msg) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        rv = SECFailure;
    } else {
        PR_APPEND_LINK(&msg->link, &ss->ssl3.hs.lastMessageFlight);
    }

    return rv;
}

/* Add DTLS handshake message to the pending queue
 * Empty the sendBuf buffer.
 * This function returns SECSuccess or SECFailure, never SECWouldBlock.
 * Always set sendBuf.len to 0, even when returning SECFailure.
 *
 * Called from:
 *              ssl3_AppendHandshakeHeader()
 *              dtls_FlushHandshake()
 */
SECStatus
dtls_StageHandshakeMessage(sslSocket *ss)
{
    SECStatus rv = SECSuccess;

    PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
    PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));

    /* This function is sometimes called when no data is actually to
     * be staged, so just return SECSuccess. */
    if (!ss->sec.ci.sendBuf.buf || !ss->sec.ci.sendBuf.len)
        return rv;

    rv = dtls_QueueMessage(ss, ssl_ct_handshake,
                           ss->sec.ci.sendBuf.buf, ss->sec.ci.sendBuf.len);

    /* Whether we succeeded or failed, toss the old handshake data. */
    ss->sec.ci.sendBuf.len = 0;
    return rv;
}

/* Enqueue the handshake message in sendBuf (if any) and then
 * transmit the resulting flight of handshake messages.
 *
 * Called from:
 *              ssl3_FlushHandshake()
 */
SECStatus
dtls_FlushHandshakeMessages(sslSocket *ss, PRInt32 flags)
{
    SECStatus rv = SECSuccess;

    PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
    PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));

    rv = dtls_StageHandshakeMessage(ss);
    if (rv != SECSuccess)
        return rv;

    if (!(flags & ssl_SEND_FLAG_FORCE_INTO_BUFFER)) {
        rv = dtls_TransmitMessageFlight(ss);
        if (rv != SECSuccess) {
            return rv;
        }

        if (!(flags & ssl_SEND_FLAG_NO_RETRANSMIT)) {
            rv = dtls_StartRetransmitTimer(ss);
        } else {
            PORT_Assert(ss->version < SSL_LIBRARY_VERSION_TLS_1_3);
        }
    }

    return rv;
}

/* The callback for when the retransmit timer expires
 *
 * Called from:
 *              dtls_CheckTimer()
 *              dtls_HandleHandshake()
 */
static void
dtls_RetransmitTimerExpiredCb(sslSocket *ss)
{
    SECStatus rv;
    dtlsTimer *timer = ss->ssl3.hs.rtTimer;
    ss->ssl3.hs.rtRetries++;

    if (!(ss->ssl3.hs.rtRetries % 3)) {
        /* If one of the messages was potentially greater than > MTU,
         * then downgrade. Do this every time we have retransmitted a
         * message twice, per RFC 6347 Sec. 4.1.1 */
        dtls_SetMTU(ss, ss->ssl3.hs.maxMessageSent - 1);
    }

    rv = dtls_TransmitMessageFlight(ss);
    if (rv == SECSuccess) {
        /* Re-arm the timer */
        timer->timeout *= 2;
        if (timer->timeout > DTLS_RETRANSMIT_MAX_MS) {
            timer->timeout = DTLS_RETRANSMIT_MAX_MS;
        }

        timer->started = PR_IntervalNow();
        timer->cb = dtls_RetransmitTimerExpiredCb;

        SSL_TRC(30,
                ("%d: SSL3[%d]: Retransmit #%d, next in %d",
                 SSL_GETPID(), ss->fd,
                 ss->ssl3.hs.rtRetries, timer->timeout));
    }
    /* else: OK for now. In future maybe signal the stack that we couldn't
     * transmit. For now, let the read handle any real network errors */
}

#define DTLS_HS_HDR_LEN 12
#define DTLS_MIN_FRAGMENT (DTLS_HS_HDR_LEN + 1 + DTLS_MAX_EXPANSION)

/* Encrypt and encode a handshake message fragment.  Flush the data out to the
 * network if there is insufficient space for any fragment. */
static SECStatus
dtls_SendFragment(sslSocket *ss, DTLSQueuedMessage *msg, PRUint8 *data,
                  unsigned int len)
{
    PRInt32 sent;
    SECStatus rv;

    PRINT_BUF(40, (ss, "dtls_SendFragment", data, len));
    sent = ssl3_SendRecord(ss, msg->cwSpec, msg->type, data, len,
                           ssl_SEND_FLAG_FORCE_INTO_BUFFER);
    if (sent != len) {
        if (sent != -1) {
            PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        }
        return SECFailure;
    }

    /* If another fragment won't fit, flush. */
    if (ss->ssl3.mtu < ss->pendingBuf.len + DTLS_MIN_FRAGMENT) {
        SSL_TRC(20, ("%d: DTLS[%d]: dtls_SendFragment: flush",
                     SSL_GETPID(), ss->fd));
        rv = dtls_SendSavedWriteData(ss);
        if (rv != SECSuccess) {
            return SECFailure;
        }
    }
    return SECSuccess;
}

/* Fragment a handshake message into multiple records and send them. */
static SECStatus
dtls_FragmentHandshake(sslSocket *ss, DTLSQueuedMessage *msg)
{
    PRBool fragmentWritten = PR_FALSE;
    PRUint16 msgSeq;
    PRUint8 *fragment;
    PRUint32 fragmentOffset = 0;
    PRUint32 fragmentLen;
    const PRUint8 *content = msg->data + DTLS_HS_HDR_LEN;
    PRUint32 contentLen = msg->len - DTLS_HS_HDR_LEN;
    SECStatus rv;

    /* The headers consume 12 bytes so the smallest possible message (i.e., an
     * empty one) is 12 bytes. */
    PORT_Assert(msg->len >= DTLS_HS_HDR_LEN);

    /* DTLS only supports fragmenting handshaking messages. */
    PORT_Assert(msg->type == ssl_ct_handshake);

    msgSeq = (msg->data[4] << 8) | msg->data[5];

    /* do {} while() so that empty messages are sent at least once. */
    do {
        PRUint8 buf[DTLS_MAX_MTU]; /* >= than largest plausible MTU */
        PRBool hasUnackedRange;
        PRUint32 end;

        hasUnackedRange = dtls_NextUnackedRange(ss, msgSeq,
                                                fragmentOffset, contentLen,
                                                &fragmentOffset, &end);
        if (!hasUnackedRange) {
            SSL_TRC(20, ("%d: SSL3[%d]: FragmentHandshake %d: all acknowledged",
                         SSL_GETPID(), ss->fd, msgSeq));
            break;
        }

        SSL_TRC(20, ("%d: SSL3[%d]: FragmentHandshake %d: unacked=%u-%u",
                     SSL_GETPID(), ss->fd, msgSeq, fragmentOffset, end));

        /* Cut down to the data we have available. */
        PORT_Assert(fragmentOffset <= contentLen);
        PORT_Assert(fragmentOffset <= end);
        PORT_Assert(end <= contentLen);
        fragmentLen = PR_MIN(end, contentLen) - fragmentOffset;

        /* Limit further by the record size limit.  Account for the header. */
        fragmentLen = PR_MIN(fragmentLen,
                             msg->cwSpec->recordSizeLimit - DTLS_HS_HDR_LEN);

        /* Reduce to the space remaining in the MTU. */
        fragmentLen = PR_MIN(fragmentLen,
                             ss->ssl3.mtu -           /* MTU estimate. */
                                 ss->pendingBuf.len - /* Less any unsent records. */
                                 DTLS_MAX_EXPANSION - /* Allow for expansion. */
                                 DTLS_HS_HDR_LEN);    /* And the handshake header. */
        PORT_Assert(fragmentLen > 0 || fragmentOffset == 0);

        /* Make totally sure that we will fit in the buffer. This should be
         * impossible; DTLS_MAX_MTU should always be more than ss->ssl3.mtu. */
        if (fragmentLen >= (DTLS_MAX_MTU - DTLS_HS_HDR_LEN)) {
            PORT_Assert(0);
            PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
            return SECFailure;
        }

        if (fragmentLen == contentLen) {
            fragment = msg->data;
        } else {
            sslBuffer tmp = SSL_BUFFER_FIXED(buf, sizeof(buf));

            /* Construct an appropriate-sized fragment */
            /* Type, length, sequence */
            rv = sslBuffer_Append(&tmp, msg->data, 6);
            if (rv != SECSuccess) {
                return SECFailure;
            }
            /* Offset. */
            rv = sslBuffer_AppendNumber(&tmp, fragmentOffset, 3);
            if (rv != SECSuccess) {
                return SECFailure;
            }
            /* Length. */
            rv = sslBuffer_AppendNumber(&tmp, fragmentLen, 3);
            if (rv != SECSuccess) {
                return SECFailure;
            }
            /* Data. */
            rv = sslBuffer_Append(&tmp, content + fragmentOffset, fragmentLen);
            if (rv != SECSuccess) {
                return SECFailure;
            }

            fragment = SSL_BUFFER_BASE(&tmp);
        }

        /* Record that we are sending first, because encrypting
         * increments the sequence number. */
        rv = dtls13_RememberFragment(ss, &ss->ssl3.hs.dtlsSentHandshake,
                                     msgSeq, fragmentOffset, fragmentLen,
                                     msg->cwSpec->epoch,
                                     msg->cwSpec->nextSeqNum);
        if (rv != SECSuccess) {
            return SECFailure;
        }

        rv = dtls_SendFragment(ss, msg, fragment,
                               fragmentLen + DTLS_HS_HDR_LEN);
        if (rv != SECSuccess) {
            return SECFailure;
        }

        fragmentWritten = PR_TRUE;
        fragmentOffset += fragmentLen;
    } while (fragmentOffset < contentLen);

    if (!fragmentWritten) {
        /* Nothing was written if we got here, so the whole message must have
         * been acknowledged.  Discard it. */
        SSL_TRC(10, ("%d: SSL3[%d]: FragmentHandshake %d: removed",
                     SSL_GETPID(), ss->fd, msgSeq));
        PR_REMOVE_LINK(&msg->link);
        dtls_FreeHandshakeMessage(msg);
    }

    return SECSuccess;
}

/* Transmit a flight of handshake messages, stuffing them
 * into as few records as seems reasonable.
 *
 * TODO: Space separate UDP packets out a little.
 *
 * Called from:
 *             dtls_FlushHandshake()
 *             dtls_RetransmitTimerExpiredCb()
 */
SECStatus
dtls_TransmitMessageFlight(sslSocket *ss)
{
    SECStatus rv = SECSuccess;
    PRCList *msg_p;

    SSL_TRC(10, ("%d: SSL3[%d]: dtls_TransmitMessageFlight",
                 SSL_GETPID(), ss->fd));

    ssl_GetXmitBufLock(ss);
    ssl_GetSpecReadLock(ss);

    /* DTLS does not buffer its handshake messages in ss->pendingBuf, but rather
     * in the lastMessageFlight structure. This is just a sanity check that some
     * programming error hasn't inadvertantly stuffed something in
     * ss->pendingBuf.  This function uses ss->pendingBuf temporarily and it
     * needs to be empty to start.
     */
    PORT_Assert(!ss->pendingBuf.len);

    for (msg_p = PR_LIST_HEAD(&ss->ssl3.hs.lastMessageFlight);
         msg_p != &ss->ssl3.hs.lastMessageFlight;) {
        DTLSQueuedMessage *msg = (DTLSQueuedMessage *)msg_p;

        /* Move the pointer forward so that the functions below are free to
         * remove messages from the list. */
        msg_p = PR_NEXT_LINK(msg_p);

        /* Note: This function fragments messages so that each record is close
         * to full.  This produces fewer records, but it means that messages can
         * be quite fragmented.  Adding an extra flush here would push new
         * messages into new records and reduce fragmentation. */

        if (msg->type == ssl_ct_handshake) {
            rv = dtls_FragmentHandshake(ss, msg);
        } else {
            PORT_Assert(!tls13_MaybeTls13(ss));
            rv = dtls_SendFragment(ss, msg, msg->data, msg->len);
        }
        if (rv != SECSuccess) {
            break;
        }
    }

    /* Finally, flush any data that wasn't flushed already. */
    if (rv == SECSuccess) {
        rv = dtls_SendSavedWriteData(ss);
    }

    /* Give up the locks */
    ssl_ReleaseSpecReadLock(ss);
    ssl_ReleaseXmitBufLock(ss);

    return rv;
}

/* Flush the data in the pendingBuf and update the max message sent
 * so we can adjust the MTU estimate if we need to.
 * Wrapper for ssl_SendSavedWriteData.
 *
 * Called from dtls_TransmitMessageFlight()
 */
static SECStatus
dtls_SendSavedWriteData(sslSocket *ss)
{
    PRInt32 sent;

    sent = ssl_SendSavedWriteData(ss);
    if (sent < 0)
        return SECFailure;

    /* We should always have complete writes b/c datagram sockets
     * don't really block */
    if (ss->pendingBuf.len > 0) {
        ssl_MapLowLevelError(SSL_ERROR_SOCKET_WRITE_FAILURE);
        return SECFailure;
    }

    /* Update the largest message sent so we can adjust the MTU
     * estimate if necessary */
    if (sent > ss->ssl3.hs.maxMessageSent)
        ss->ssl3.hs.maxMessageSent = sent;

    return SECSuccess;
}

void
dtls_InitTimers(sslSocket *ss)
{
    unsigned int i;
    dtlsTimer **timers[PR_ARRAY_SIZE(ss->ssl3.hs.timers)] = {
        &ss->ssl3.hs.rtTimer,
        &ss->ssl3.hs.ackTimer,
        &ss->ssl3.hs.hdTimer
    };
    static const char *timerLabels[] = {
        "retransmit", "ack", "holddown"
    };

    PORT_Assert(PR_ARRAY_SIZE(timers) == PR_ARRAY_SIZE(timerLabels));
    for (i = 0; i < PR_ARRAY_SIZE(ss->ssl3.hs.timers); ++i) {
        *timers[i] = &ss->ssl3.hs.timers[i];
        ss->ssl3.hs.timers[i].label = timerLabels[i];
    }
}

SECStatus
dtls_StartTimer(sslSocket *ss, dtlsTimer *timer, PRUint32 time, DTLSTimerCb cb)
{
    PORT_Assert(timer->cb == NULL);

    SSL_TRC(10, ("%d: SSL3[%d]: %s dtls_StartTimer %s timeout=%d",
                 SSL_GETPID(), ss->fd, SSL_ROLE(ss), timer->label, time));

    timer->started = PR_IntervalNow();
    timer->timeout = time;
    timer->cb = cb;
    return SECSuccess;
}

SECStatus
dtls_RestartTimer(sslSocket *ss, dtlsTimer *timer)
{
    timer->started = PR_IntervalNow();
    return SECSuccess;
}

PRBool
dtls_TimerActive(sslSocket *ss, dtlsTimer *timer)
{
    return timer->cb != NULL;
}
/* Start a timer for retransmission. */
static SECStatus
dtls_StartRetransmitTimer(sslSocket *ss)
{
    ss->ssl3.hs.rtRetries = 0;
    return dtls_StartTimer(ss, ss->ssl3.hs.rtTimer,
                           DTLS_RETRANSMIT_INITIAL_MS,
                           dtls_RetransmitTimerExpiredCb);
}

/* Start a timer for holding an old cipher spec. */
SECStatus
dtls_StartHolddownTimer(sslSocket *ss)
{
    ss->ssl3.hs.rtRetries = 0;
    return dtls_StartTimer(ss, ss->ssl3.hs.rtTimer,
                           DTLS_RETRANSMIT_FINISHED_MS,
                           dtls_FinishedTimerCb);
}

/* Cancel a pending timer
 *
 * Called from:
 *              dtls_HandleHandshake()
 *              dtls_CheckTimer()
 */
void
dtls_CancelTimer(sslSocket *ss, dtlsTimer *timer)
{
    SSL_TRC(30, ("%d: SSL3[%d]: %s dtls_CancelTimer %s",
                 SSL_GETPID(), ss->fd, SSL_ROLE(ss),
                 timer->label));

    PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));

    timer->cb = NULL;
}

static void
dtls_CancelAllTimers(sslSocket *ss)
{
    unsigned int i;

    for (i = 0; i < PR_ARRAY_SIZE(ss->ssl3.hs.timers); ++i) {
        dtls_CancelTimer(ss, &ss->ssl3.hs.timers[i]);
    }
}

/* Check the pending timer and fire the callback if it expired
 *
 * Called from ssl3_GatherCompleteHandshake()
 */
void
dtls_CheckTimer(sslSocket *ss)
{
    unsigned int i;
    SSL_TRC(30, ("%d: SSL3[%d]: dtls_CheckTimer (%s)",
                 SSL_GETPID(), ss->fd, ss->sec.isServer ? "server" : "client"));

    ssl_GetSSL3HandshakeLock(ss);

    for (i = 0; i < PR_ARRAY_SIZE(ss->ssl3.hs.timers); ++i) {
        dtlsTimer *timer = &ss->ssl3.hs.timers[i];
        if (!timer->cb) {
            continue;
        }

        if ((PR_IntervalNow() - timer->started) >=
            PR_MillisecondsToInterval(timer->timeout)) {
            /* Timer has expired */
            DTLSTimerCb cb = timer->cb;

            SSL_TRC(10, ("%d: SSL3[%d]: %s firing timer %s",
                         SSL_GETPID(), ss->fd, SSL_ROLE(ss),
                         timer->label));

            /* Cancel the timer so that we can call the CB safely */
            dtls_CancelTimer(ss, timer);

            /* Now call the CB */
            cb(ss);
        }
    }
    ssl_ReleaseSSL3HandshakeLock(ss);
}

/* The callback to fire when the holddown timer for the Finished
 * message expires and we can delete it
 *
 * Called from dtls_CheckTimer()
 */
static void
dtls_FinishedTimerCb(sslSocket *ss)
{
    dtls_FreeHandshakeMessages(&ss->ssl3.hs.lastMessageFlight);
}

/* Cancel the Finished hold-down timer and destroy the
 * pending cipher spec. Note that this means that
 * successive rehandshakes will fail if the Finished is
 * lost.
 *
 * XXX OK for now. Figure out how to handle the combination
 * of Finished lost and rehandshake
 */
void
dtls_RehandshakeCleanup(sslSocket *ss)
{
    /* Skip this if we are handling a second ClientHello. */
    if (ss->ssl3.hs.helloRetry) {
        return;
    }
    PORT_Assert((ss->version < SSL_LIBRARY_VERSION_TLS_1_3));
    dtls_CancelAllTimers(ss);
    dtls_FreeHandshakeMessages(&ss->ssl3.hs.lastMessageFlight);
    ss->ssl3.hs.sendMessageSeq = 0;
    ss->ssl3.hs.recvMessageSeq = 0;
}

/* Set the MTU to the next step less than or equal to the
 * advertised value. Also used to downgrade the MTU by
 * doing dtls_SetMTU(ss, biggest packet set).
 *
 * Passing 0 means set this to the largest MTU known
 * (effectively resetting the PMTU backoff value).
 *
 * Called by:
 *            ssl3_InitState()
 *            dtls_RetransmitTimerExpiredCb()
 */
void
dtls_SetMTU(sslSocket *ss, PRUint16 advertised)
{
    int i;

    if (advertised == 0) {
        ss->ssl3.mtu = COMMON_MTU_VALUES[0];
        SSL_TRC(30, ("Resetting MTU to %d", ss->ssl3.mtu));
        return;
    }

    for (i = 0; i < PR_ARRAY_SIZE(COMMON_MTU_VALUES); i++) {
        if (COMMON_MTU_VALUES[i] <= advertised) {
            ss->ssl3.mtu = COMMON_MTU_VALUES[i];
            SSL_TRC(30, ("Resetting MTU to %d", ss->ssl3.mtu));
            return;
        }
    }

    /* Fallback */
    ss->ssl3.mtu = COMMON_MTU_VALUES[PR_ARRAY_SIZE(COMMON_MTU_VALUES) - 1];
    SSL_TRC(30, ("Resetting MTU to %d", ss->ssl3.mtu));
}

/* Called from ssl3_HandleHandshakeMessage() when it has deciphered a
 * DTLS hello_verify_request
 * Caller must hold Handshake and RecvBuf locks.
 */
SECStatus
dtls_HandleHelloVerifyRequest(sslSocket *ss, PRUint8 *b, PRUint32 length)
{
    int errCode = SSL_ERROR_RX_MALFORMED_HELLO_VERIFY_REQUEST;
    SECStatus rv;
    SSL3ProtocolVersion temp;
    SSL3AlertDescription desc = illegal_parameter;

    SSL_TRC(3, ("%d: SSL3[%d]: handle hello_verify_request handshake",
                SSL_GETPID(), ss->fd));
    PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
    PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));

    if (ss->ssl3.hs.ws != wait_server_hello) {
        errCode = SSL_ERROR_RX_UNEXPECTED_HELLO_VERIFY_REQUEST;
        desc = unexpected_message;
        goto alert_loser;
    }

    dtls_ReceivedFirstMessageInFlight(ss);

    /* The version.
     *
     * RFC 4347 required that you verify that the server versions
     * match (Section 4.2.1) in the HelloVerifyRequest and the
     * ServerHello.
     *
     * RFC 6347 suggests (SHOULD) that servers always use 1.0 in
     * HelloVerifyRequest and allows the versions not to match,
     * especially when 1.2 is being negotiated.
     *
     * Therefore we do not do anything to enforce a match, just
     * read and check that this value is sane.
     */
    rv = ssl_ClientReadVersion(ss, &b, &length, &temp);
    if (rv != SECSuccess) {
        goto loser; /* alert has been sent */
    }

    /* Read the cookie.
     * IMPORTANT: The value of ss->ssl3.hs.cookie is only valid while the
     * HelloVerifyRequest message remains valid. */
    rv = ssl3_ConsumeHandshakeVariable(ss, &ss->ssl3.hs.cookie, 1, &b, &length);
    if (rv != SECSuccess) {
        goto loser; /* alert has been sent */
    }
    if (ss->ssl3.hs.cookie.len > DTLS_COOKIE_BYTES) {
        desc = decode_error;
        goto alert_loser; /* malformed. */
    }

    ssl_GetXmitBufLock(ss); /*******************************/

    /* Now re-send the client hello */
    rv = ssl3_SendClientHello(ss, client_hello_retransmit);

    ssl_ReleaseXmitBufLock(ss); /*******************************/

    if (rv == SECSuccess)
        return rv;

alert_loser:
    (void)SSL3_SendAlert(ss, alert_fatal, desc);

loser:
    ssl_MapLowLevelError(errCode);
    return SECFailure;
}

/* Initialize the DTLS anti-replay window
 *
 * Called from:
 *              ssl3_SetupPendingCipherSpec()
 *              ssl3_InitCipherSpec()
 */
void
dtls_InitRecvdRecords(DTLSRecvdRecords *records)
{
    PORT_Memset(records->data, 0, sizeof(records->data));
    records->left = 0;
    records->right = DTLS_RECVD_RECORDS_WINDOW - 1;
}

/*
 * Has this DTLS record been received? Return values are:
 * -1 -- out of range to the left
 *  0 -- not received yet
 *  1 -- replay
 *
 *  Called from: ssl3_HandleRecord()
 */
int
dtls_RecordGetRecvd(const DTLSRecvdRecords *records, sslSequenceNumber seq)
{
    PRUint64 offset;

    /* Out of range to the left */
    if (seq < records->left) {
        return -1;
    }

    /* Out of range to the right; since we advance the window on
     * receipt, that means that this packet has not been received
     * yet */
    if (seq > records->right)
        return 0;

    offset = seq % DTLS_RECVD_RECORDS_WINDOW;

    return !!(records->data[offset / 8] & (1 << (offset % 8)));
}

/* Update the DTLS anti-replay window
 *
 * Called from ssl3_HandleRecord()
 */
void
dtls_RecordSetRecvd(DTLSRecvdRecords *records, sslSequenceNumber seq)
{
    PRUint64 offset;

    if (seq < records->left)
        return;

    if (seq > records->right) {
        sslSequenceNumber new_left;
        sslSequenceNumber new_right;
        sslSequenceNumber right;

        /* Slide to the right; this is the tricky part
         *
         * 1. new_top is set to have room for seq, on the
         *    next byte boundary by setting the right 8
         *    bits of seq
         * 2. new_left is set to compensate.
         * 3. Zero all bits between top and new_top. Since
         *    this is a ring, this zeroes everything as-yet
         *    unseen. Because we always operate on byte
         *    boundaries, we can zero one byte at a time
         */
        new_right = seq | 0x07;
        new_left = (new_right - DTLS_RECVD_RECORDS_WINDOW) + 1;

        if (new_right > records->right + DTLS_RECVD_RECORDS_WINDOW) {
            PORT_Memset(records->data, 0, sizeof(records->data));
        } else {
            for (right = records->right + 8; right <= new_right; right += 8) {
                offset = right % DTLS_RECVD_RECORDS_WINDOW;
                records->data[offset / 8] = 0;
            }
        }

        records->right = new_right;
        records->left = new_left;
    }

    offset = seq % DTLS_RECVD_RECORDS_WINDOW;

    records->data[offset / 8] |= (1 << (offset % 8));
}

SECStatus
DTLS_GetHandshakeTimeout(PRFileDesc *socket, PRIntervalTime *timeout)
{
    sslSocket *ss = NULL;
    PRBool found = PR_FALSE;
    PRIntervalTime now = PR_IntervalNow();
    PRIntervalTime to;
    unsigned int i;

    *timeout = PR_INTERVAL_NO_TIMEOUT;

    ss = ssl_FindSocket(socket);

    if (!ss) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    if (!IS_DTLS(ss)) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    for (i = 0; i < PR_ARRAY_SIZE(ss->ssl3.hs.timers); ++i) {
        PRIntervalTime elapsed;
        PRIntervalTime desired;
        dtlsTimer *timer = &ss->ssl3.hs.timers[i];

        if (!timer->cb) {
            continue;
        }
        found = PR_TRUE;

        elapsed = now - timer->started;
        desired = PR_MillisecondsToInterval(timer->timeout);
        if (elapsed > desired) {
            /* Timer expired */
            *timeout = PR_INTERVAL_NO_WAIT;
            return SECSuccess;
        } else {
            to = desired - elapsed;
        }

        if (*timeout > to) {
            *timeout = to;
        }
    }

    if (!found) {
        PORT_SetError(SSL_ERROR_NO_TIMERS_FOUND);
        return SECFailure;
    }

    return SECSuccess;
}

PRBool
dtls_IsLongHeader(SSL3ProtocolVersion version, PRUint8 firstOctet)
{
#ifndef UNSAFE_FUZZER_MODE
    return version < SSL_LIBRARY_VERSION_TLS_1_3 ||
           firstOctet == ssl_ct_handshake ||
           firstOctet == ssl_ct_ack ||
           firstOctet == ssl_ct_alert;
#else
    return PR_TRUE;
#endif
}

DTLSEpoch
dtls_ReadEpoch(const ssl3CipherSpec *crSpec, const PRUint8 *hdr)
{
    DTLSEpoch epoch;
    DTLSEpoch maxEpoch;
    DTLSEpoch partial;

    if (dtls_IsLongHeader(crSpec->version, hdr[0])) {
        return ((DTLSEpoch)hdr[3] << 8) | hdr[4];
    }

    /* A lot of how we recover the epoch here will depend on how we plan to
     * manage KeyUpdate.  In the case that we decide to install a new read spec
     * as a KeyUpdate is handled, crSpec will always be the highest epoch we can
     * possibly receive.  That makes this easier to manage. */
    if ((hdr[0] & 0xe0) == 0x20) {
        /* Use crSpec->epoch, or crSpec->epoch - 1 if the last bit differs. */
        if (((hdr[0] >> 4) & 1) == (crSpec->epoch & 1)) {
            return crSpec->epoch;
        }
        return crSpec->epoch - 1;
    }

    /* dtls_GatherData should ensure that this works. */
    PORT_Assert(hdr[0] == ssl_ct_application_data);

    /* This uses the same method as is used to recover the sequence number in
     * dtls_ReadSequenceNumber, except that the maximum value is set to the
     * current epoch. */
    partial = hdr[1] >> 6;
    maxEpoch = PR_MAX(crSpec->epoch, 3);
    epoch = (maxEpoch & 0xfffc) | partial;
    if (partial > (maxEpoch & 0x03)) {
        epoch -= 4;
    }
    return epoch;
}

static sslSequenceNumber
dtls_ReadSequenceNumber(const ssl3CipherSpec *spec, const PRUint8 *hdr)
{
    sslSequenceNumber cap;
    sslSequenceNumber partial;
    sslSequenceNumber seqNum;
    sslSequenceNumber mask;

    if (dtls_IsLongHeader(spec->version, hdr[0])) {
        static const unsigned int seqNumOffset = 5; /* type, version, epoch */
        static const unsigned int seqNumLength = 6;
        sslReader r = SSL_READER(hdr + seqNumOffset, seqNumLength);
        (void)sslRead_ReadNumber(&r, seqNumLength, &seqNum);
        return seqNum;
    }

    /* Only the least significant bits of the sequence number is available here.
     * This recovers the value based on the next expected sequence number.
     *
     * This works by determining the maximum possible sequence number, which is
     * half the range of possible values above the expected next value (the
     * expected next value is in |spec->seqNum|).  Then, the last part of the
     * sequence number is replaced.  If that causes the value to exceed the
     * maximum, subtract an entire range.
     */
    if ((hdr[0] & 0xe0) == 0x20) {
        /* A 12-bit sequence number. */
        cap = spec->nextSeqNum + (1ULL << 11);
        partial = (((sslSequenceNumber)hdr[0] & 0xf) << 8) |
                  (sslSequenceNumber)hdr[1];
        mask = (1ULL << 12) - 1;
    } else {
        /* A 30-bit sequence number. */
        cap = spec->nextSeqNum + (1ULL << 29);
        partial = (((sslSequenceNumber)hdr[1] & 0x3f) << 24) |
                  ((sslSequenceNumber)hdr[2] << 16) |
                  ((sslSequenceNumber)hdr[3] << 8) |
                  (sslSequenceNumber)hdr[4];
        mask = (1ULL << 30) - 1;
    }
    seqNum = (cap & ~mask) | partial;
    /* The second check prevents the value from underflowing if we get a large
     * gap at the start of a connection, where this subtraction would cause the
     * sequence number to wrap to near UINT64_MAX. */
    if ((partial > (cap & mask)) && (seqNum > mask)) {
        seqNum -= mask + 1;
    }
    return seqNum;
}

/*
 * DTLS relevance checks:
 * Note that this code currently ignores all out-of-epoch packets,
 * which means we lose some in the case of rehandshake +
 * loss/reordering. Since DTLS is explicitly unreliable, this
 * seems like a good tradeoff for implementation effort and is
 * consistent with the guidance of RFC 6347 Sections 4.1 and 4.2.4.1.
 *
 * If the packet is not relevant, this function returns PR_FALSE.  If the packet
 * is relevant, this function returns PR_TRUE and sets |*seqNumOut| to the
 * packet sequence number (removing the epoch).
 */
PRBool
dtls_IsRelevant(sslSocket *ss, const ssl3CipherSpec *spec,
                const SSL3Ciphertext *cText,
                sslSequenceNumber *seqNumOut)
{
    sslSequenceNumber seqNum = dtls_ReadSequenceNumber(spec, cText->hdr);
    if (dtls_RecordGetRecvd(&spec->recvdRecords, seqNum) != 0) {
        SSL_TRC(10, ("%d: SSL3[%d]: dtls_IsRelevant, rejecting "
                     "potentially replayed packet",
                     SSL_GETPID(), ss->fd));
        return PR_FALSE;
    }

    *seqNumOut = seqNum;
    return PR_TRUE;
}

void
dtls_ReceivedFirstMessageInFlight(sslSocket *ss)
{
    if (!IS_DTLS(ss))
        return;

    /* At this point we are advancing our state machine, so we can free our last
     * flight of messages. */
    if (ss->ssl3.hs.ws != idle_handshake ||
        ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) {
        /* We need to keep our last flight around in DTLS 1.2 and below,
         * so we can retransmit it in response to other people's
         * retransmits. */
        dtls_FreeHandshakeMessages(&ss->ssl3.hs.lastMessageFlight);

        /* Reset the timer to the initial value if the retry counter
         * is 0, per RFC 6347, Sec. 4.2.4.1 */
        dtls_CancelTimer(ss, ss->ssl3.hs.rtTimer);
        if (ss->ssl3.hs.rtRetries == 0) {
            ss->ssl3.hs.rtTimer->timeout = DTLS_RETRANSMIT_INITIAL_MS;
        }
    }

    /* Empty the ACK queue (TLS 1.3 only). */
    ssl_ClearPRCList(&ss->ssl3.hs.dtlsRcvdHandshake, NULL);
}
