/* -*- 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 (0304)
 */
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 else 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)
{
    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);
            rv = SECFailure;
            goto loser;
        }
#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;
            ss->ssl3.hs.helloRetry = PR_TRUE;
        }

        /* 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 != SECSuccess) {
        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. */
    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.
 * 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
}

PRBool
dtls_IsDtls13Ciphertext(SSL3ProtocolVersion version, PRUint8 firstOctet)
{
    // Allow no version in case we haven't negotiated one yet.
    return (version == 0 || version >= SSL_LIBRARY_VERSION_TLS_1_3) &&
           (firstOctet & 0xe0) == 0x20;
}

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 (dtls_IsDtls13Ciphertext(crSpec->version, hdr[0])) {
        /* TODO(ekr@rtfm.com: do something with the two-bit epoch. */
        /* Use crSpec->epoch, or crSpec->epoch - 1 if the last bit differs. */
        return crSpec->epoch - ((hdr[0] ^ crSpec->epoch) & 0x3);
    }

    /* 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] & 0x08) {
        cap = spec->nextSeqNum + (1ULL << 15);
        partial = (((sslSequenceNumber)hdr[1]) << 8) |
                  (sslSequenceNumber)hdr[2];
        mask = (1ULL << 16) - 1;
    } else {
        cap = spec->nextSeqNum + (1ULL << 7);
        partial = (sslSequenceNumber)hdr[1];
        mask = (1ULL << 8) - 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);
}
