/* 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"

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

static SECStatus dtls_TransmitMessageFlight(sslSocket *ss);
static void dtls_RetransmitTimerExpiredCb(sslSocket *ss);
static SECStatus dtls_SendSavedWriteData(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

/* List copied from ssl3con.c:cipherSuites */
static const ssl3CipherSuite nonDTLSSuites[] = {
#ifdef NSS_ENABLE_ECC
    TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
    TLS_ECDHE_RSA_WITH_RC4_128_SHA,
#endif  /* NSS_ENABLE_ECC */
    TLS_DHE_DSS_WITH_RC4_128_SHA,
#ifdef NSS_ENABLE_ECC
    TLS_ECDH_RSA_WITH_RC4_128_SHA,
    TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
#endif  /* NSS_ENABLE_ECC */
    SSL_RSA_WITH_RC4_128_MD5,
    SSL_RSA_WITH_RC4_128_SHA,
    TLS_RSA_EXPORT1024_WITH_RC4_56_SHA,
    SSL_RSA_EXPORT_WITH_RC4_40_MD5,
    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)
 */
SSL3ProtocolVersion
dtls_TLSVersionToDTLSVersion(SSL3ProtocolVersion tlsv)
{
    /* Anything other than TLS 1.1 is an error, so return
     * the invalid version ffff. */
    if (tlsv != SSL_LIBRARY_VERSION_TLS_1_1)
	return 0xffff;

    return SSL_LIBRARY_VERSION_DTLS_1_0_WIRE;
}

/* 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;

    /* Return a fictional higher version than we know of */
    return SSL_LIBRARY_VERSION_TLS_1_1 + 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) {
	SECStatus rv = ssl3_CipherPrefSet(ss, *suite, PR_FALSE);

	PORT_Assert(rv == SECSuccess); /* else is coding error */
    }
    return SECSuccess;
}

/* Allocate a DTLSQueuedMessage.
 *
 * Called from dtls_QueueMessage()
 */
static DTLSQueuedMessage *
dtls_AllocQueuedMessage(PRUint16 epoch, SSL3ContentType type,
			const unsigned char *data, PRUint32 len)
{
    DTLSQueuedMessage *msg = NULL;

    msg = PORT_ZAlloc(sizeof(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->epoch = epoch;
    msg->type = type;

    return msg;
}

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

    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 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, 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;

    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;
            break;
        }

        /* 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_RECORD_TOO_LONG);
	    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;
            break;
        }

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

        /* 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 = (SSL3HandshakeType)type;
            ss->ssl3.hs.msg_len = message_length;

            /* At this point we are advancing our state machine, so
             * we can free our last flight of messages */
            dtls_FreeHandshakeMessages(&ss->ssl3.hs.lastMessageFlight);
	    ss->ssl3.hs.recvdHighWater = -1;
	    dtls_CancelTimer(ss);

	    /* Reset the timer to the initial value if the retry counter
	     * is 0, per Sec. 4.2.4.1 */
	    if (ss->ssl3.hs.rtRetries == 0) {
		ss->ssl3.hs.rtTimeoutMs = INITIAL_DTLS_TIMEOUT_MS;
	    }

            rv = ssl3_HandleHandshakeMessage(ss, buf.buf, ss->ssl3.hs.msg_len);
            if (rv == SECFailure) {
                /* Do not attempt to process rest of messages in this record */
                break;
            }
        } else {
	    if (message_seq < ss->ssl3.hs.recvMessageSeq) {
		/* Case 3: we do an immediate retransmit if we're
		 * in a waiting state*/
		if (ss->ssl3.hs.rtTimerCb == NULL) {
		    /* Ignore */
		} else if (ss->ssl3.hs.rtTimerCb ==
			 dtls_RetransmitTimerExpiredCb) {
		    SSL_TRC(30, ("%d: SSL3[%d]: Retransmit detected",
				 SSL_GETPID(), ss->fd));
		    /* 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 should be
		     */
		    if ((PR_IntervalNow() - ss->ssl3.hs.rtTimerStarted) >
			(ss->ssl3.hs.rtTimeoutMs / 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);
			    dtls_RetransmitTimerExpiredCb(ss);
			    rv = SECSuccess;
			    break;
			} else {
			    SSL_TRC(30,
			    ("%d: SSL3[%d]: We just retransmitted. Ignoring.",
                            SSL_GETPID(), ss->fd));
			    rv = SECSuccess;
			    break;
			}
		} else if (ss->ssl3.hs.rtTimerCb == dtls_FinishedTimerCb) {
		    /* 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);
		    rv = dtls_TransmitMessageFlight(ss);
		    if (rv == SECSuccess) {
			rv = dtls_StartTimer(ss, dtls_FinishedTimerCb);
		    }
		    if (rv != SECSuccess)
			return rv;
		    break;
		}
	    } 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?
		 */
	    } else {
		/* 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)
                        break;
                    /* Make room for the fragment map */
                    rv = sslBuffer_Grow(&ss->ssl3.hs.recvdFragments,
                                        map_length);
                    if (rv != SECSuccess)
                        break;

                    /* 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 = (SSL3HandshakeType)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;
                    break;
                }

                /* Now copy this fragment into the buffer */
                PORT_Assert((fragment_offset + fragment_length) <=
                            ss->ssl3.hs.msg_body.space);
                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 <= ss->ssl3.hs.recvdHighWater) {
		    /* Either this is the adjacent fragment or an overlapping
                     * fragment */
                    ss->ssl3.hs.recvdHighWater = fragment_offset +
                                                 fragment_length;
                } else {
                    for (offset = fragment_offset;
                         offset < fragment_offset + fragment_length;
                         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) {
                    ss->ssl3.hs.recvdHighWater = -1;

                    rv = ssl3_HandleHandshakeMessage(ss,
                                                     ss->ssl3.hs.msg_body.buf,
                                                     ss->ssl3.hs.msg_len);
                    if (rv == SECFailure)
                        break; /* Skip rest of record */

		    /* At this point we are advancing our state machine, so
		     * we can free our last flight of messages */
		    dtls_FreeHandshakeMessages(&ss->ssl3.hs.lastMessageFlight);
		    dtls_CancelTimer(ss);

		    /* If there have been no retries this time, reset the
		     * timer value to the default per Section 4.2.4.1 */
		    if (ss->ssl3.hs.rtRetries == 0) {
			ss->ssl3.hs.rtTimeoutMs = INITIAL_DTLS_TIMEOUT_MS;
		    }
                }
            }
        }

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

    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, SSL3ContentType type,
    const SSL3Opaque *pIn, PRInt32 nIn)
{
    SECStatus rv = SECSuccess;
    DTLSQueuedMessage *msg = NULL;

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

    msg = dtls_AllocQueuedMessage(ss->ssl3.cwSpec->epoch, type, 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, content_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)) {
	    ss->ssl3.hs.rtRetries = 0;
	    rv = dtls_StartTimer(ss, dtls_RetransmitTimerExpiredCb);
	}
    }

    return rv;
}

/* The callback for when the retransmit timer expires
 *
 * Called from:
 *              dtls_CheckTimer()
 *              dtls_HandleHandshake()
 */
static void
dtls_RetransmitTimerExpiredCb(sslSocket *ss)
{
    SECStatus rv = SECFailure;

    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 */
	rv = dtls_RestartTimer(ss, PR_TRUE, dtls_RetransmitTimerExpiredCb);
    }

    if (rv == SECFailure) {
	/* XXX OK for now. In future maybe signal the stack that we couldn't
	 * transmit. For now, let the read handle any real network errors */
    }
}

/* Transmit a flight of handshake messages, stuffing them
 * into as few records as seems reasonable
 *
 * Called from:
 *             dtls_FlushHandshake()
 *             dtls_RetransmitTimerExpiredCb()
 */
static SECStatus
dtls_TransmitMessageFlight(sslSocket *ss)
{
    SECStatus rv = SECSuccess;
    PRCList *msg_p;
    PRUint16 room_left = ss->ssl3.mtu;
    PRInt32 sent;

    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
     */
    PORT_Assert(!ss->pendingBuf.len);
    for (msg_p = PR_LIST_HEAD(&ss->ssl3.hs.lastMessageFlight);
	 msg_p != &ss->ssl3.hs.lastMessageFlight;
	 msg_p = PR_NEXT_LINK(msg_p)) {
        DTLSQueuedMessage *msg = (DTLSQueuedMessage *)msg_p;

        /* The logic here is:
         *
	 * 1. If this is a message that will not fit into the remaining
	 *    space, then flush.
	 * 2. If the message will now fit into the remaining space,
         *    encrypt, buffer, and loop.
         * 3. If the message will not fit, then fragment.
         *
	 * At the end of the function, flush.
         */
        if ((msg->len + SSL3_BUFFER_FUDGE) > room_left) {
	    /* The message will not fit into the remaining space, so flush */
	    rv = dtls_SendSavedWriteData(ss);
	    if (rv != SECSuccess)
		break;

            room_left = ss->ssl3.mtu;
	}

        if ((msg->len + SSL3_BUFFER_FUDGE) <= room_left) {
            /* The message will fit, so encrypt and then continue with the
	     * next packet */
            sent = ssl3_SendRecord(ss, msg->epoch, msg->type,
				   msg->data, msg->len,
				   ssl_SEND_FLAG_FORCE_INTO_BUFFER |
				   ssl_SEND_FLAG_USE_EPOCH);
            if (sent != msg->len) {
		rv = SECFailure;
		if (sent != -1) {
		    PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
		}
                break;
	    }

            room_left = ss->ssl3.mtu - ss->pendingBuf.len;
        } else {
            /* The message will not fit, so fragment.
             *
	     * XXX OK for now. Arrange to coalesce the last fragment
	     * of this message with the next message if possible.
	     * That would be more efficient.
	     */
            PRUint32 fragment_offset = 0;
            unsigned char fragment[DTLS_MAX_MTU]; /* >= than largest
                                                   * plausible MTU */

	    /* Assert that we have already flushed */
	    PORT_Assert(room_left == ss->ssl3.mtu);

            /* Case 3: We now need to fragment this message
             * DTLS only supports fragmenting handshaking messages */
            PORT_Assert(msg->type == content_handshake);

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

            while ((fragment_offset + 12) < msg->len) {
                PRUint32 fragment_len;
                const unsigned char *content = msg->data + 12;
                PRUint32 content_len = msg->len - 12;

		/* The reason we use 8 here is that that's the length of
		 * the new DTLS data that we add to the header */
                fragment_len = PR_MIN(room_left - (SSL3_BUFFER_FUDGE + 8),
                                      content_len - fragment_offset);
		PORT_Assert(fragment_len < DTLS_MAX_MTU - 12);
		/* Make totally sure that we are within the buffer.
		 * Note that the only way that fragment len could get
		 * adjusted here is if
                 *
		 * (a) we are in release mode so the PORT_Assert is compiled out
		 * (b) either the MTU table is inconsistent with DTLS_MAX_MTU
		 * or ss->ssl3.mtu has become corrupt.
		 */
		fragment_len = PR_MIN(fragment_len, DTLS_MAX_MTU - 12);

                /* Construct an appropriate-sized fragment */
                /* Type, length, sequence */
                PORT_Memcpy(fragment, msg->data, 6);

                /* Offset */
                fragment[6] = (fragment_offset >> 16) & 0xff;
                fragment[7] = (fragment_offset >> 8) & 0xff;
                fragment[8] = (fragment_offset) & 0xff;

                /* Fragment length */
                fragment[9] = (fragment_len >> 16) & 0xff;
                fragment[10] = (fragment_len >> 8) & 0xff;
                fragment[11] = (fragment_len) & 0xff;

                PORT_Memcpy(fragment + 12, content + fragment_offset,
                            fragment_len);

                /*
		 *  Send the record. We do this in two stages
		 * 1. Encrypt
		 */
                sent = ssl3_SendRecord(ss, msg->epoch, msg->type,
                                       fragment, fragment_len + 12,
                                       ssl_SEND_FLAG_FORCE_INTO_BUFFER |
				       ssl_SEND_FLAG_USE_EPOCH);
                if (sent != (fragment_len + 12)) {
		    rv = SECFailure;
		    if (sent != -1) {
			PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
		    }
		    break;
		}
		
		/* 2. Flush */
		rv = dtls_SendSavedWriteData(ss);
		if (rv != SECSuccess)
		    break;

                fragment_offset += fragment_len;
            }
        }
    }

    /* Finally, we need to flush */
    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;
}

/* Compress, MAC, encrypt a DTLS record. Allows specification of
 * the epoch using epoch value. If use_epoch is PR_TRUE then
 * we use the provided epoch. If use_epoch is PR_FALSE then
 * whatever the current value is in effect is used.
 *
 * Called from ssl3_SendRecord()
 */
SECStatus
dtls_CompressMACEncryptRecord(sslSocket *        ss,
                              DTLSEpoch          epoch,
			      PRBool             use_epoch,
                              SSL3ContentType    type,
		              const SSL3Opaque * pIn,
		              PRUint32           contentLen,
			      sslBuffer        * wrBuf)
{
    SECStatus rv = SECFailure;
    ssl3CipherSpec *          cwSpec;

    ssl_GetSpecReadLock(ss);	/********************************/

    /* The reason for this switch-hitting code is that we might have
     * a flight of records spanning an epoch boundary, e.g.,
     *
     * ClientKeyExchange (epoch = 0)
     * ChangeCipherSpec (epoch = 0)
     * Finished (epoch = 1)
     *
     * Thus, each record needs a different cipher spec. The information
     * about which epoch to use is carried with the record.
     */
    if (use_epoch) {
	if (ss->ssl3.cwSpec->epoch == epoch)
	    cwSpec = ss->ssl3.cwSpec;
	else if (ss->ssl3.pwSpec->epoch == epoch)
	    cwSpec = ss->ssl3.pwSpec;
	else
	    cwSpec = NULL;
    } else {
	cwSpec = ss->ssl3.cwSpec;
    }

    if (cwSpec) {
        rv = ssl3_CompressMACEncryptRecord(cwSpec, ss->sec.isServer, PR_TRUE,
					   PR_FALSE, type, pIn, contentLen,
					   wrBuf);
    } else {
        PR_NOT_REACHED("Couldn't find a cipher spec matching epoch");
	PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
    }
    ssl_ReleaseSpecReadLock(ss); /************************************/

    return rv;
}

/* Start a timer
 *
 * Called from:
 *             dtls_HandleHandshake()
 *             dtls_FlushHAndshake()
 *             dtls_RestartTimer()
 */
SECStatus
dtls_StartTimer(sslSocket *ss, DTLSTimerCb cb)
{
    PORT_Assert(ss->ssl3.hs.rtTimerCb == NULL);

    ss->ssl3.hs.rtTimerStarted = PR_IntervalNow();
    ss->ssl3.hs.rtTimerCb = cb;

    return SECSuccess;
}

/* Restart a timer with optional backoff
 *
 * Called from dtls_RetransmitTimerExpiredCb()
 */
SECStatus
dtls_RestartTimer(sslSocket *ss, PRBool backoff, DTLSTimerCb cb)
{
    if (backoff) {
	ss->ssl3.hs.rtTimeoutMs *= 2;
	if (ss->ssl3.hs.rtTimeoutMs > MAX_DTLS_TIMEOUT_MS)
	    ss->ssl3.hs.rtTimeoutMs = MAX_DTLS_TIMEOUT_MS;
    }

    return dtls_StartTimer(ss, cb);
}

/* Cancel a pending timer
 *
 * Called from:
 *              dtls_HandleHandshake()
 *              dtls_CheckTimer()
 */
void
dtls_CancelTimer(sslSocket *ss)
{
    PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));

    ss->ssl3.hs.rtTimerCb = NULL;
}

/* Check the pending timer and fire the callback if it expired
 *
 * Called from ssl3_GatherCompleteHandshake()
 */
void
dtls_CheckTimer(sslSocket *ss)
{
    if (!ss->ssl3.hs.rtTimerCb)
	return;

    if ((PR_IntervalNow() - ss->ssl3.hs.rtTimerStarted) >
	PR_MillisecondsToInterval(ss->ssl3.hs.rtTimeoutMs)) {
	/* Timer has expired */
	DTLSTimerCb cb = ss->ssl3.hs.rtTimerCb;
	
	/* Cancel the timer so that we can call the CB safely */
	dtls_CancelTimer(ss);

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

/* The callback to fire when the holddown timer for the Finished
 * message expires and we can delete it
 *
 * Called from dtls_CheckTimer()
 */
void
dtls_FinishedTimerCb(sslSocket *ss)
{
    ssl3_DestroyCipherSpec(ss->ssl3.pwSpec, PR_FALSE);
}

/* 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)
{
    dtls_CancelTimer(ss);
    ssl3_DestroyCipherSpec(ss->ssl3.pwSpec, PR_FALSE);
    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, SSL3Opaque *b, PRUint32 length)
{
    int                 errCode	= SSL_ERROR_RX_MALFORMED_HELLO_VERIFY_REQUEST;
    SECStatus           rv;
    PRInt32             temp;
    SECItem             cookie = {siBuffer, NULL, 0};
    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;
    }

    /* The version */
    temp = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length);
    if (temp < 0) {
    	goto loser; 	/* alert has been sent */
    }

    if (temp != SSL_LIBRARY_VERSION_DTLS_1_0_WIRE) {
	/* Note: this will need adjustment for DTLS 1.2 per Section 4.2.1 */
	goto alert_loser;
    }

    /* The cookie */
    rv = ssl3_ConsumeHandshakeVariable(ss, &cookie, 1, &b, &length);
    if (rv != SECSuccess) {
    	goto loser; 	/* alert has been sent */
    }
    if (cookie.len > DTLS_COOKIE_BYTES) {
	desc = decode_error;
	goto alert_loser;	/* malformed. */
    }

    PORT_Memcpy(ss->ssl3.hs.cookie, cookie.data, cookie.len);
    ss->ssl3.hs.cookieLen = cookie.len;


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

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

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

    if (rv == SECSuccess)
	return rv;

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

loser:
    errCode = 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: dtls_HandleRecord()
 */
int
dtls_RecordGetRecvd(DTLSRecvdRecords *records, PRUint64 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, PRUint64 seq)
{
    PRUint64 offset;

    if (seq < records->left)
	return;

    if (seq > records->right) {
	PRUint64 new_left;
	PRUint64 new_right;
	PRUint64 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;

	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;
    PRIntervalTime elapsed;
    PRIntervalTime desired;

    ss = ssl_FindSocket(socket);

    if (!ss)
        return SECFailure;

    if (!IS_DTLS(ss))
        return SECFailure;

    if (!ss->ssl3.hs.rtTimerCb)
        return SECFailure;

    elapsed = PR_IntervalNow() - ss->ssl3.hs.rtTimerStarted;
    desired = PR_MillisecondsToInterval(ss->ssl3.hs.rtTimeoutMs);
    if (elapsed > desired) {
        /* Timer expired */
        *timeout = PR_INTERVAL_NO_WAIT;
    } else {
        *timeout = desired - elapsed;
    }

    return SECSuccess;
}
