/* ssl/d1_pkt.c */
/* 
 * DTLS implementation written by Nagendra Modadugu
 * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.  
 */
/* ====================================================================
 * Copyright (c) 1998-2005 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    openssl-core@openssl.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 * 
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 * 
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from 
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 * 
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * 
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */

#include <stdio.h>
#include <errno.h>
#define USE_SOCKETS
#include "ssl_locl.h"
#include <openssl/evp.h>
#include <openssl/buffer.h>
#include <openssl/pqueue.h>
#include <openssl/rand.h>

/* mod 128 saturating subtract of two 64-bit values in big-endian order */
static int satsub64be(const unsigned char *v1,const unsigned char *v2)
{	int ret,sat,brw,i;

	if (sizeof(long) == 8) do
	{	const union { long one; char little; } is_endian = {1};
		long l;

		if (is_endian.little)			break;
		/* not reached on little-endians */
		/* following test is redundant, because input is
		 * always aligned, but I take no chances... */
		if (((size_t)v1|(size_t)v2)&0x7)	break;

		l  = *((long *)v1);
		l -= *((long *)v2);
		if (l>128)		return 128;
		else if (l<-128)	return -128;
		else			return (int)l;
	} while (0);

	ret = (int)v1[7]-(int)v2[7];
	sat = 0;
	brw = ret>>8;	/* brw is either 0 or -1 */
	if (ret & 0x80)
	{	for (i=6;i>=0;i--)
		{	brw += (int)v1[i]-(int)v2[i];
			sat |= ~brw;
			brw >>= 8;
		}
	}
	else
	{	for (i=6;i>=0;i--)
		{	brw += (int)v1[i]-(int)v2[i];
			sat |= brw;
			brw >>= 8;
		}
	}
	brw <<= 8;	/* brw is either 0 or -256 */

	if (sat&0xff)	return brw | 0x80;
	else		return brw + (ret&0xFF);
}

static int have_handshake_fragment(SSL *s, int type, unsigned char *buf, 
	int len, int peek);
static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap);
static void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap);
static DTLS1_BITMAP *dtls1_get_bitmap(SSL *s, SSL3_RECORD *rr, 
    unsigned int *is_next_epoch);
#if 0
static int dtls1_record_needs_buffering(SSL *s, SSL3_RECORD *rr,
	unsigned short *priority, unsigned long *offset);
#endif
static int dtls1_buffer_record(SSL *s, record_pqueue *q,
	unsigned char *priority);
static int dtls1_process_record(SSL *s);
static void dtls1_clear_timeouts(SSL *s);

/* copy buffered record into SSL structure */
static int
dtls1_copy_record(SSL *s, pitem *item)
    {
    DTLS1_RECORD_DATA *rdata;

    rdata = (DTLS1_RECORD_DATA *)item->data;
    
    if (s->s3->rbuf.buf != NULL)
        OPENSSL_free(s->s3->rbuf.buf);
    
    s->packet = rdata->packet;
    s->packet_length = rdata->packet_length;
    memcpy(&(s->s3->rbuf), &(rdata->rbuf), sizeof(SSL3_BUFFER));
    memcpy(&(s->s3->rrec), &(rdata->rrec), sizeof(SSL3_RECORD));
	
	/* Set proper sequence number for mac calculation */
	memcpy(&(s->s3->read_sequence[2]), &(rdata->packet[5]), 6);
    
    return(1);
    }


static int
dtls1_buffer_record(SSL *s, record_pqueue *queue, unsigned char *priority)
	{
	DTLS1_RECORD_DATA *rdata;
	pitem *item;

	/* Limit the size of the queue to prevent DOS attacks */
	if (pqueue_size(queue->q) >= 100)
		return 0;
		
	rdata = OPENSSL_malloc(sizeof(DTLS1_RECORD_DATA));
	item = pitem_new(priority, rdata);
	if (rdata == NULL || item == NULL)
		{
		if (rdata != NULL) OPENSSL_free(rdata);
		if (item != NULL) pitem_free(item);
		
		SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR);
		return(0);
		}
	
	rdata->packet = s->packet;
	rdata->packet_length = s->packet_length;
	memcpy(&(rdata->rbuf), &(s->s3->rbuf), sizeof(SSL3_BUFFER));
	memcpy(&(rdata->rrec), &(s->s3->rrec), sizeof(SSL3_RECORD));

	item->data = rdata;

	/* insert should not fail, since duplicates are dropped */
	if (pqueue_insert(queue->q, item) == NULL)
		{
		OPENSSL_free(rdata);
		pitem_free(item);
		return(0);
		}

	s->packet = NULL;
	s->packet_length = 0;
	memset(&(s->s3->rbuf), 0, sizeof(SSL3_BUFFER));
	memset(&(s->s3->rrec), 0, sizeof(SSL3_RECORD));
	
	if (!ssl3_setup_buffers(s))
		{
		SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR);
		OPENSSL_free(rdata);
		pitem_free(item);
		return(0);
		}
	
	return(1);
	}


static int
dtls1_retrieve_buffered_record(SSL *s, record_pqueue *queue)
    {
    pitem *item;

    item = pqueue_pop(queue->q);
    if (item)
        {
        dtls1_copy_record(s, item);

        OPENSSL_free(item->data);
		pitem_free(item);

        return(1);
        }

    return(0);
    }


/* retrieve a buffered record that belongs to the new epoch, i.e., not processed 
 * yet */
#define dtls1_get_unprocessed_record(s) \
                   dtls1_retrieve_buffered_record((s), \
                   &((s)->d1->unprocessed_rcds))

/* retrieve a buffered record that belongs to the current epoch, ie, processed */
#define dtls1_get_processed_record(s) \
                   dtls1_retrieve_buffered_record((s), \
                   &((s)->d1->processed_rcds))

static int
dtls1_process_buffered_records(SSL *s)
    {
    pitem *item;
    
    item = pqueue_peek(s->d1->unprocessed_rcds.q);
    if (item)
        {
        DTLS1_RECORD_DATA *rdata;
        rdata = (DTLS1_RECORD_DATA *)item->data;
        
        /* Check if epoch is current. */
        if (s->d1->unprocessed_rcds.epoch != s->d1->r_epoch)
            return(1);  /* Nothing to do. */
        
        /* Process all the records. */
        while (pqueue_peek(s->d1->unprocessed_rcds.q))
            {
            dtls1_get_unprocessed_record(s);
            if ( ! dtls1_process_record(s))
                return(0);
            dtls1_buffer_record(s, &(s->d1->processed_rcds), 
                s->s3->rrec.seq_num);
            }
        }

    /* sync epoch numbers once all the unprocessed records 
     * have been processed */
    s->d1->processed_rcds.epoch = s->d1->r_epoch;
    s->d1->unprocessed_rcds.epoch = s->d1->r_epoch + 1;

    return(1);
    }


#if 0

static int
dtls1_get_buffered_record(SSL *s)
	{
	pitem *item;
	PQ_64BIT priority = 
		(((PQ_64BIT)s->d1->handshake_read_seq) << 32) | 
		((PQ_64BIT)s->d1->r_msg_hdr.frag_off);
	
	if ( ! SSL_in_init(s))  /* if we're not (re)negotiating, 
							   nothing buffered */
		return 0;


	item = pqueue_peek(s->d1->rcvd_records);
	if (item && item->priority == priority)
		{
		/* Check if we've received the record of interest.  It must be
		 * a handshake record, since data records as passed up without
		 * buffering */
		DTLS1_RECORD_DATA *rdata;
		item = pqueue_pop(s->d1->rcvd_records);
		rdata = (DTLS1_RECORD_DATA *)item->data;
		
		if (s->s3->rbuf.buf != NULL)
			OPENSSL_free(s->s3->rbuf.buf);
		
		s->packet = rdata->packet;
		s->packet_length = rdata->packet_length;
		memcpy(&(s->s3->rbuf), &(rdata->rbuf), sizeof(SSL3_BUFFER));
		memcpy(&(s->s3->rrec), &(rdata->rrec), sizeof(SSL3_RECORD));
		
		OPENSSL_free(item->data);
		pitem_free(item);
		
		/* s->d1->next_expected_seq_num++; */
		return(1);
		}
	
	return 0;
	}

#endif

static int
dtls1_process_record(SSL *s)
{
	int i,al;
	int clear=0;
	int enc_err;
	SSL_SESSION *sess;
	SSL3_RECORD *rr;
	unsigned int mac_size;
	unsigned char md[EVP_MAX_MD_SIZE];


	rr= &(s->s3->rrec);
	sess = s->session;

	/* At this point, s->packet_length == SSL3_RT_HEADER_LNGTH + rr->length,
	 * and we have that many bytes in s->packet
	 */
	rr->input= &(s->packet[DTLS1_RT_HEADER_LENGTH]);

	/* ok, we can now read from 's->packet' data into 'rr'
	 * rr->input points at rr->length bytes, which
	 * need to be copied into rr->data by either
	 * the decryption or by the decompression
	 * When the data is 'copied' into the rr->data buffer,
	 * rr->input will be pointed at the new buffer */ 

	/* We now have - encrypted [ MAC [ compressed [ plain ] ] ]
	 * rr->length bytes of encrypted compressed stuff. */

	/* check is not needed I believe */
	if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH)
		{
		al=SSL_AD_RECORD_OVERFLOW;
		SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_ENCRYPTED_LENGTH_TOO_LONG);
		goto f_err;
		}

	/* decrypt in place in 'rr->input' */
	rr->data=rr->input;

	enc_err = s->method->ssl3_enc->enc(s,0);
	if (enc_err <= 0)
		{
		if (enc_err == 0)
			/* SSLerr() and ssl3_send_alert() have been called */
			goto err;

		/* otherwise enc_err == -1 */
		goto err;
		}

#ifdef TLS_DEBUG
printf("dec %d\n",rr->length);
{ unsigned int z; for (z=0; z<rr->length; z++) printf("%02X%c",rr->data[z],((z+1)%16)?' ':'\n'); }
printf("\n");
#endif

	/* r->length is now the compressed data plus mac */
	if (	(sess == NULL) ||
		(s->enc_read_ctx == NULL) ||
		(s->read_hash == NULL))
		clear=1;

	if (!clear)
		{
		/* !clear => s->read_hash != NULL => mac_size != -1 */
		int t;
		t=EVP_MD_CTX_size(s->read_hash);
		OPENSSL_assert(t >= 0);
		mac_size=t;

		if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+mac_size)
			{
#if 0 /* OK only for stream ciphers (then rr->length is visible from ciphertext anyway) */
			al=SSL_AD_RECORD_OVERFLOW;
			SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_PRE_MAC_LENGTH_TOO_LONG);
			goto f_err;
#else
			goto err;
#endif			
			}
		/* check the MAC for rr->input (it's in mac_size bytes at the tail) */
		if (rr->length < mac_size)
			{
#if 0 /* OK only for stream ciphers */
			al=SSL_AD_DECODE_ERROR;
			SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_LENGTH_TOO_SHORT);
			goto f_err;
#else
			goto err;
#endif
			}
		rr->length-=mac_size;
		i=s->method->ssl3_enc->mac(s,md,0);
		if (i < 0 || memcmp(md,&(rr->data[rr->length]),mac_size) != 0)
			{
			goto err;
			}
		}

	/* r->length is now just compressed */
	if (s->expand != NULL)
		{
		if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH)
			{
			al=SSL_AD_RECORD_OVERFLOW;
			SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_COMPRESSED_LENGTH_TOO_LONG);
			goto f_err;
			}
		if (!ssl3_do_uncompress(s))
			{
			al=SSL_AD_DECOMPRESSION_FAILURE;
			SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_BAD_DECOMPRESSION);
			goto f_err;
			}
		}

	if (rr->length > SSL3_RT_MAX_PLAIN_LENGTH)
		{
		al=SSL_AD_RECORD_OVERFLOW;
		SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_DATA_LENGTH_TOO_LONG);
		goto f_err;
		}

	rr->off=0;
	/* So at this point the following is true
	 * ssl->s3->rrec.type 	is the type of record
	 * ssl->s3->rrec.length	== number of bytes in record
	 * ssl->s3->rrec.off	== offset to first valid byte
	 * ssl->s3->rrec.data	== where to take bytes from, increment
	 *			   after use :-).
	 */

	/* we have pulled in a full packet so zero things */
	s->packet_length=0;
	dtls1_record_bitmap_update(s, &(s->d1->bitmap));/* Mark receipt of record. */
	return(1);

f_err:
	ssl3_send_alert(s,SSL3_AL_FATAL,al);
err:
	return(0);
}


/* Call this to get a new input record.
 * It will return <= 0 if more data is needed, normally due to an error
 * or non-blocking IO.
 * When it finishes, one packet has been decoded and can be found in
 * ssl->s3->rrec.type    - is the type of record
 * ssl->s3->rrec.data, 	 - data
 * ssl->s3->rrec.length, - number of bytes
 */
/* used only by dtls1_read_bytes */
int dtls1_get_record(SSL *s)
	{
	int ssl_major,ssl_minor;
	int i,n;
	SSL3_RECORD *rr;
	SSL_SESSION *sess;
	unsigned char *p = NULL;
	unsigned short version;
	DTLS1_BITMAP *bitmap;
	unsigned int is_next_epoch;

	rr= &(s->s3->rrec);
	sess=s->session;

	/* The epoch may have changed.  If so, process all the
	 * pending records.  This is a non-blocking operation. */
	dtls1_process_buffered_records(s);

	/* if we're renegotiating, then there may be buffered records */
	if (dtls1_get_processed_record(s))
		return 1;

	/* get something from the wire */
again:
	/* check if we have the header */
	if (	(s->rstate != SSL_ST_READ_BODY) ||
		(s->packet_length < DTLS1_RT_HEADER_LENGTH)) 
		{
		n=ssl3_read_n(s, DTLS1_RT_HEADER_LENGTH, s->s3->rbuf.len, 0);
		/* read timeout is handled by dtls1_read_bytes */
		if (n <= 0) return(n); /* error or non-blocking */

		/* this packet contained a partial record, dump it */
		if (s->packet_length != DTLS1_RT_HEADER_LENGTH)
			{
			s->packet_length = 0;
			goto again;
			}

		s->rstate=SSL_ST_READ_BODY;

		p=s->packet;

		/* Pull apart the header into the DTLS1_RECORD */
		rr->type= *(p++);
		ssl_major= *(p++);
		ssl_minor= *(p++);
		version=(ssl_major<<8)|ssl_minor;

		/* sequence number is 64 bits, with top 2 bytes = epoch */ 
		n2s(p,rr->epoch);

		memcpy(&(s->s3->read_sequence[2]), p, 6);
		p+=6;

		n2s(p,rr->length);

		/* Lets check version */
		if (!s->first_packet)
			{
			if (version != s->version)
				{
				/* unexpected version, silently discard */
				rr->length = 0;
				s->packet_length = 0;
				goto again;
				}
			}

		if ((version & 0xff00) != (s->version & 0xff00))
			{
			/* wrong version, silently discard record */
			rr->length = 0;
			s->packet_length = 0;
			goto again;
			}

		if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH)
			{
			/* record too long, silently discard it */
			rr->length = 0;
			s->packet_length = 0;
			goto again;
			}

		/* If we receive a valid record larger than the current buffer size,
		 * allocate some memory for it.
		 */
		if (rr->length > s->s3->rbuf.len - DTLS1_RT_HEADER_LENGTH)
			{
			unsigned char *pp;
			unsigned int newlen = rr->length + DTLS1_RT_HEADER_LENGTH;
			if ((pp=OPENSSL_realloc(s->s3->rbuf.buf, newlen))==NULL)
				{
				SSLerr(SSL_F_DTLS1_GET_RECORD,ERR_R_MALLOC_FAILURE);
				return(-1);
				}
			p = pp + (p - s->s3->rbuf.buf);
			s->s3->rbuf.buf=pp;
			s->s3->rbuf.len=newlen;
			s->packet= &(s->s3->rbuf.buf[0]);
			}

		/* now s->rstate == SSL_ST_READ_BODY */
		}

	/* s->rstate == SSL_ST_READ_BODY, get and decode the data */

	if (rr->length > s->packet_length-DTLS1_RT_HEADER_LENGTH)
		{
		/* now s->packet_length == DTLS1_RT_HEADER_LENGTH */
		i=rr->length;
		n=ssl3_read_n(s,i,i,1);
		if (n <= 0) return(n); /* error or non-blocking io */

		/* this packet contained a partial record, dump it */
		if ( n != i)
			{
			rr->length = 0;
			s->packet_length = 0;
			goto again;
			}

		/* now n == rr->length,
		 * and s->packet_length == DTLS1_RT_HEADER_LENGTH + rr->length */
		}
	s->rstate=SSL_ST_READ_HEADER; /* set state for later operations */

	/* match epochs.  NULL means the packet is dropped on the floor */
	bitmap = dtls1_get_bitmap(s, rr, &is_next_epoch);
	if ( bitmap == NULL)
		{
		rr->length = 0;
		s->packet_length = 0;  /* dump this record */
		goto again;   /* get another record */
		}

	/* Check whether this is a repeat, or aged record.
	 * Don't check if we're listening and this message is
	 * a ClientHello. They can look as if they're replayed,
	 * since they arrive from different connections and
	 * would be dropped unnecessarily.
	 */
	if (!(s->d1->listen && rr->type == SSL3_RT_HANDSHAKE &&
		*p == SSL3_MT_CLIENT_HELLO) &&
		!dtls1_record_replay_check(s, bitmap))
		{
		rr->length = 0;
		s->packet_length=0; /* dump this record */
		goto again;     /* get another record */
		}

	/* just read a 0 length packet */
	if (rr->length == 0) goto again;

	/* If this record is from the next epoch (either HM or ALERT),
	 * and a handshake is currently in progress, buffer it since it
	 * cannot be processed at this time. */
	if (is_next_epoch)
		{
		if (SSL_in_init(s) || s->in_handshake)
			{
			dtls1_buffer_record(s, &(s->d1->unprocessed_rcds), rr->seq_num);
			}
		rr->length = 0;
		s->packet_length = 0;
		goto again;
		}

	if (!dtls1_process_record(s))
		{
		rr->length = 0;
		s->packet_length = 0;  /* dump this record */
		goto again;   /* get another record */
		}

	dtls1_clear_timeouts(s);  /* done waiting */
	return(1);

	}

/* Return up to 'len' payload bytes received in 'type' records.
 * 'type' is one of the following:
 *
 *   -  SSL3_RT_HANDSHAKE (when ssl3_get_message calls us)
 *   -  SSL3_RT_APPLICATION_DATA (when ssl3_read calls us)
 *   -  0 (during a shutdown, no data has to be returned)
 *
 * If we don't have stored data to work from, read a SSL/TLS record first
 * (possibly multiple records if we still don't have anything to return).
 *
 * This function must handle any surprises the peer may have for us, such as
 * Alert records (e.g. close_notify), ChangeCipherSpec records (not really
 * a surprise, but handled as if it were), or renegotiation requests.
 * Also if record payloads contain fragments too small to process, we store
 * them until there is enough for the respective protocol (the record protocol
 * may use arbitrary fragmentation and even interleaving):
 *     Change cipher spec protocol
 *             just 1 byte needed, no need for keeping anything stored
 *     Alert protocol
 *             2 bytes needed (AlertLevel, AlertDescription)
 *     Handshake protocol
 *             4 bytes needed (HandshakeType, uint24 length) -- we just have
 *             to detect unexpected Client Hello and Hello Request messages
 *             here, anything else is handled by higher layers
 *     Application data protocol
 *             none of our business
 */
int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
	{
	int al,i,j,ret;
	unsigned int n;
	SSL3_RECORD *rr;
	void (*cb)(const SSL *ssl,int type2,int val)=NULL;

	if (s->s3->rbuf.buf == NULL) /* Not initialized yet */
		if (!ssl3_setup_buffers(s))
			return(-1);

    /* XXX: check what the second '&& type' is about */
	if ((type && (type != SSL3_RT_APPLICATION_DATA) && 
		(type != SSL3_RT_HANDSHAKE) && type) ||
	    (peek && (type != SSL3_RT_APPLICATION_DATA)))
		{
		SSLerr(SSL_F_DTLS1_READ_BYTES, ERR_R_INTERNAL_ERROR);
		return -1;
		}

	/* check whether there's a handshake message (client hello?) waiting */
	if ( (ret = have_handshake_fragment(s, type, buf, len, peek)))
		return ret;

	/* Now s->d1->handshake_fragment_len == 0 if type == SSL3_RT_HANDSHAKE. */

	if (!s->in_handshake && SSL_in_init(s))
		{
		/* type == SSL3_RT_APPLICATION_DATA */
		i=s->handshake_func(s);
		if (i < 0) return(i);
		if (i == 0)
			{
			SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE);
			return(-1);
			}
		}

start:
	s->rwstate=SSL_NOTHING;

	/* s->s3->rrec.type	    - is the type of record
	 * s->s3->rrec.data,    - data
	 * s->s3->rrec.off,     - offset into 'data' for next read
	 * s->s3->rrec.length,  - number of bytes. */
	rr = &(s->s3->rrec);

	/* We are not handshaking and have no data yet,
	 * so process data buffered during the last handshake
	 * in advance, if any.
	 */
	if (s->state == SSL_ST_OK && rr->length == 0)
		{
		pitem *item;
		item = pqueue_pop(s->d1->buffered_app_data.q);
		if (item)
			{
			dtls1_copy_record(s, item);

			OPENSSL_free(item->data);
			pitem_free(item);
			}
		}

	/* Check for timeout */
	if (dtls1_handle_timeout(s) > 0)
		goto start;

	/* get new packet if necessary */
	if ((rr->length == 0) || (s->rstate == SSL_ST_READ_BODY))
		{
		ret=dtls1_get_record(s);
		if (ret <= 0) 
			{
			ret = dtls1_read_failed(s, ret);
			/* anything other than a timeout is an error */
			if (ret <= 0)  
				return(ret);
			else
				goto start;
			}
		}

	/* we now have a packet which can be read and processed */

	if (s->s3->change_cipher_spec /* set when we receive ChangeCipherSpec,
	                               * reset by ssl3_get_finished */
		&& (rr->type != SSL3_RT_HANDSHAKE))
		{
		/* We now have application data between CCS and Finished.
		 * Most likely the packets were reordered on their way, so
		 * buffer the application data for later processing rather
		 * than dropping the connection.
		 */
		dtls1_buffer_record(s, &(s->d1->buffered_app_data), rr->seq_num);
		rr->length = 0;
		goto start;
		}

	/* If the other end has shut down, throw anything we read away
	 * (even in 'peek' mode) */
	if (s->shutdown & SSL_RECEIVED_SHUTDOWN)
		{
		rr->length=0;
		s->rwstate=SSL_NOTHING;
		return(0);
		}


	if (type == rr->type) /* SSL3_RT_APPLICATION_DATA or SSL3_RT_HANDSHAKE */
		{
		/* make sure that we are not getting application data when we
		 * are doing a handshake for the first time */
		if (SSL_in_init(s) && (type == SSL3_RT_APPLICATION_DATA) &&
			(s->enc_read_ctx == NULL))
			{
			al=SSL_AD_UNEXPECTED_MESSAGE;
			SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_APP_DATA_IN_HANDSHAKE);
			goto f_err;
			}

		if (len <= 0) return(len);

		if ((unsigned int)len > rr->length)
			n = rr->length;
		else
			n = (unsigned int)len;

		memcpy(buf,&(rr->data[rr->off]),n);
		if (!peek)
			{
			rr->length-=n;
			rr->off+=n;
			if (rr->length == 0)
				{
				s->rstate=SSL_ST_READ_HEADER;
				rr->off=0;
				}
			}
		return(n);
		}


	/* If we get here, then type != rr->type; if we have a handshake
	 * message, then it was unexpected (Hello Request or Client Hello). */

	/* In case of record types for which we have 'fragment' storage,
	 * fill that so that we can process the data at a fixed place.
	 */
		{
		unsigned int k, dest_maxlen = 0;
		unsigned char *dest = NULL;
		unsigned int *dest_len = NULL;

		if (rr->type == SSL3_RT_HANDSHAKE)
			{
			dest_maxlen = sizeof s->d1->handshake_fragment;
			dest = s->d1->handshake_fragment;
			dest_len = &s->d1->handshake_fragment_len;
			}
		else if (rr->type == SSL3_RT_ALERT)
			{
			dest_maxlen = sizeof(s->d1->alert_fragment);
			dest = s->d1->alert_fragment;
			dest_len = &s->d1->alert_fragment_len;
			}
		/* else it's a CCS message, or application data or wrong */
		else if (rr->type != SSL3_RT_CHANGE_CIPHER_SPEC)
			{
			/* Application data while renegotiating
			 * is allowed. Try again reading.
			 */
			if (rr->type == SSL3_RT_APPLICATION_DATA)
				{
				BIO *bio;
				s->s3->in_read_app_data=2;
				bio=SSL_get_rbio(s);
				s->rwstate=SSL_READING;
				BIO_clear_retry_flags(bio);
				BIO_set_retry_read(bio);
				return(-1);
				}

			/* Not certain if this is the right error handling */
			al=SSL_AD_UNEXPECTED_MESSAGE;
			SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_UNEXPECTED_RECORD);
			goto f_err;
			}

		if (dest_maxlen > 0)
			{
            /* XDTLS:  In a pathalogical case, the Client Hello
             *  may be fragmented--don't always expect dest_maxlen bytes */
			if ( rr->length < dest_maxlen)
				{
#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE
				/*
				 * for normal alerts rr->length is 2, while
				 * dest_maxlen is 7 if we were to handle this
				 * non-existing alert...
				 */
				FIX ME
#endif
				s->rstate=SSL_ST_READ_HEADER;
				rr->length = 0;
				goto start;
				}

			/* now move 'n' bytes: */
			for ( k = 0; k < dest_maxlen; k++)
				{
				dest[k] = rr->data[rr->off++];
				rr->length--;
				}
			*dest_len = dest_maxlen;
			}
		}

	/* s->d1->handshake_fragment_len == 12  iff  rr->type == SSL3_RT_HANDSHAKE;
	 * s->d1->alert_fragment_len == 7      iff  rr->type == SSL3_RT_ALERT.
	 * (Possibly rr is 'empty' now, i.e. rr->length may be 0.) */

	/* If we are a client, check for an incoming 'Hello Request': */
	if ((!s->server) &&
		(s->d1->handshake_fragment_len >= DTLS1_HM_HEADER_LENGTH) &&
		(s->d1->handshake_fragment[0] == SSL3_MT_HELLO_REQUEST) &&
		(s->session != NULL) && (s->session->cipher != NULL))
		{
		s->d1->handshake_fragment_len = 0;

		if ((s->d1->handshake_fragment[1] != 0) ||
			(s->d1->handshake_fragment[2] != 0) ||
			(s->d1->handshake_fragment[3] != 0))
			{
			al=SSL_AD_DECODE_ERROR;
			SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_BAD_HELLO_REQUEST);
			goto err;
			}

		/* no need to check sequence number on HELLO REQUEST messages */

		if (s->msg_callback)
			s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, 
				s->d1->handshake_fragment, 4, s, s->msg_callback_arg);

		if (SSL_is_init_finished(s) &&
			!(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) &&
			!s->s3->renegotiate)
			{
			ssl3_renegotiate(s);
			if (ssl3_renegotiate_check(s))
				{
				i=s->handshake_func(s);
				if (i < 0) return(i);
				if (i == 0)
					{
					SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE);
					return(-1);
					}

				if (!(s->mode & SSL_MODE_AUTO_RETRY))
					{
					if (s->s3->rbuf.left == 0) /* no read-ahead left? */
						{
						BIO *bio;
						/* In the case where we try to read application data,
						 * but we trigger an SSL handshake, we return -1 with
						 * the retry option set.  Otherwise renegotiation may
						 * cause nasty problems in the blocking world */
						s->rwstate=SSL_READING;
						bio=SSL_get_rbio(s);
						BIO_clear_retry_flags(bio);
						BIO_set_retry_read(bio);
						return(-1);
						}
					}
				}
			}
		/* we either finished a handshake or ignored the request,
		 * now try again to obtain the (application) data we were asked for */
		goto start;
		}

	if (s->d1->alert_fragment_len >= DTLS1_AL_HEADER_LENGTH)
		{
		int alert_level = s->d1->alert_fragment[0];
		int alert_descr = s->d1->alert_fragment[1];

		s->d1->alert_fragment_len = 0;

		if (s->msg_callback)
			s->msg_callback(0, s->version, SSL3_RT_ALERT, 
				s->d1->alert_fragment, 2, s, s->msg_callback_arg);

		if (s->info_callback != NULL)
			cb=s->info_callback;
		else if (s->ctx->info_callback != NULL)
			cb=s->ctx->info_callback;

		if (cb != NULL)
			{
			j = (alert_level << 8) | alert_descr;
			cb(s, SSL_CB_READ_ALERT, j);
			}

		if (alert_level == 1) /* warning */
			{
			s->s3->warn_alert = alert_descr;
			if (alert_descr == SSL_AD_CLOSE_NOTIFY)
				{
				s->shutdown |= SSL_RECEIVED_SHUTDOWN;
				return(0);
				}
#if 0
            /* XXX: this is a possible improvement in the future */
			/* now check if it's a missing record */
			if (alert_descr == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE)
				{
				unsigned short seq;
				unsigned int frag_off;
				unsigned char *p = &(s->d1->alert_fragment[2]);

				n2s(p, seq);
				n2l3(p, frag_off);

				dtls1_retransmit_message(s,
										 dtls1_get_queue_priority(frag->msg_header.seq, 0),
										 frag_off, &found);
				if ( ! found  && SSL_in_init(s))
					{
					/* fprintf( stderr,"in init = %d\n", SSL_in_init(s)); */
					/* requested a message not yet sent, 
					   send an alert ourselves */
					ssl3_send_alert(s,SSL3_AL_WARNING,
						DTLS1_AD_MISSING_HANDSHAKE_MESSAGE);
					}
				}
#endif
			}
		else if (alert_level == 2) /* fatal */
			{
			char tmp[16];

			s->rwstate=SSL_NOTHING;
			s->s3->fatal_alert = alert_descr;
			SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_AD_REASON_OFFSET + alert_descr);
			BIO_snprintf(tmp,sizeof tmp,"%d",alert_descr);
			ERR_add_error_data(2,"SSL alert number ",tmp);
			s->shutdown|=SSL_RECEIVED_SHUTDOWN;
			SSL_CTX_remove_session(s->ctx,s->session);
			return(0);
			}
		else
			{
			al=SSL_AD_ILLEGAL_PARAMETER;
			SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_UNKNOWN_ALERT_TYPE);
			goto f_err;
			}

		goto start;
		}

	if (s->shutdown & SSL_SENT_SHUTDOWN) /* but we have not received a shutdown */
		{
		s->rwstate=SSL_NOTHING;
		rr->length=0;
		return(0);
		}

	if (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC)
		{
		struct ccs_header_st ccs_hdr;
		unsigned int ccs_hdr_len = DTLS1_CCS_HEADER_LENGTH;

		dtls1_get_ccs_header(rr->data, &ccs_hdr);

		if (s->version == DTLS1_BAD_VER)
			ccs_hdr_len = 3;

		/* 'Change Cipher Spec' is just a single byte, so we know
		 * exactly what the record payload has to look like */
		/* XDTLS: check that epoch is consistent */
		if (	(rr->length != ccs_hdr_len) || 
			(rr->off != 0) || (rr->data[0] != SSL3_MT_CCS))
			{
			i=SSL_AD_ILLEGAL_PARAMETER;
			SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_BAD_CHANGE_CIPHER_SPEC);
			goto err;
			}

		rr->length=0;

		if (s->msg_callback)
			s->msg_callback(0, s->version, SSL3_RT_CHANGE_CIPHER_SPEC, 
				rr->data, 1, s, s->msg_callback_arg);

		/* We can't process a CCS now, because previous handshake
		 * messages are still missing, so just drop it.
		 */
		if (!s->d1->change_cipher_spec_ok)
			{
			goto start;
			}

		s->d1->change_cipher_spec_ok = 0;

		s->s3->change_cipher_spec=1;
		if (!ssl3_do_change_cipher_spec(s))
			goto err;

		/* do this whenever CCS is processed */
		dtls1_reset_seq_numbers(s, SSL3_CC_READ);

		if (s->version == DTLS1_BAD_VER)
			s->d1->handshake_read_seq++;

		goto start;
		}

	/* Unexpected handshake message (Client Hello, or protocol violation) */
	if ((s->d1->handshake_fragment_len >= DTLS1_HM_HEADER_LENGTH) && 
		!s->in_handshake)
		{
		struct hm_header_st msg_hdr;
		
		/* this may just be a stale retransmit */
		dtls1_get_message_header(rr->data, &msg_hdr);
		if( rr->epoch != s->d1->r_epoch)
			{
			rr->length = 0;
			goto start;
			}

		/* If we are server, we may have a repeated FINISHED of the
		 * client here, then retransmit our CCS and FINISHED.
		 */
		if (msg_hdr.type == SSL3_MT_FINISHED)
			{
			dtls1_retransmit_buffered_messages(s);
			rr->length = 0;
			goto start;
			}

		if (((s->state&SSL_ST_MASK) == SSL_ST_OK) &&
			!(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS))
			{
#if 0 /* worked only because C operator preferences are not as expected (and
       * because this is not really needed for clients except for detecting
       * protocol violations): */
			s->state=SSL_ST_BEFORE|(s->server)
				?SSL_ST_ACCEPT
				:SSL_ST_CONNECT;
#else
			s->state = s->server ? SSL_ST_ACCEPT : SSL_ST_CONNECT;
#endif
			s->new_session=1;
			}
		i=s->handshake_func(s);
		if (i < 0) return(i);
		if (i == 0)
			{
			SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE);
			return(-1);
			}

		if (!(s->mode & SSL_MODE_AUTO_RETRY))
			{
			if (s->s3->rbuf.left == 0) /* no read-ahead left? */
				{
				BIO *bio;
				/* In the case where we try to read application data,
				 * but we trigger an SSL handshake, we return -1 with
				 * the retry option set.  Otherwise renegotiation may
				 * cause nasty problems in the blocking world */
				s->rwstate=SSL_READING;
				bio=SSL_get_rbio(s);
				BIO_clear_retry_flags(bio);
				BIO_set_retry_read(bio);
				return(-1);
				}
			}
		goto start;
		}

	switch (rr->type)
		{
	default:
#ifndef OPENSSL_NO_TLS
		/* TLS just ignores unknown message types */
		if (s->version == TLS1_VERSION)
			{
			rr->length = 0;
			goto start;
			}
#endif
		al=SSL_AD_UNEXPECTED_MESSAGE;
		SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_UNEXPECTED_RECORD);
		goto f_err;
	case SSL3_RT_CHANGE_CIPHER_SPEC:
	case SSL3_RT_ALERT:
	case SSL3_RT_HANDSHAKE:
		/* we already handled all of these, with the possible exception
		 * of SSL3_RT_HANDSHAKE when s->in_handshake is set, but that
		 * should not happen when type != rr->type */
		al=SSL_AD_UNEXPECTED_MESSAGE;
		SSLerr(SSL_F_DTLS1_READ_BYTES,ERR_R_INTERNAL_ERROR);
		goto f_err;
	case SSL3_RT_APPLICATION_DATA:
		/* At this point, we were expecting handshake data,
		 * but have application data.  If the library was
		 * running inside ssl3_read() (i.e. in_read_app_data
		 * is set) and it makes sense to read application data
		 * at this point (session renegotiation not yet started),
		 * we will indulge it.
		 */
		if (s->s3->in_read_app_data &&
			(s->s3->total_renegotiations != 0) &&
			((
				(s->state & SSL_ST_CONNECT) &&
				(s->state >= SSL3_ST_CW_CLNT_HELLO_A) &&
				(s->state <= SSL3_ST_CR_SRVR_HELLO_A)
				) || (
					(s->state & SSL_ST_ACCEPT) &&
					(s->state <= SSL3_ST_SW_HELLO_REQ_A) &&
					(s->state >= SSL3_ST_SR_CLNT_HELLO_A)
					)
				))
			{
			s->s3->in_read_app_data=2;
			return(-1);
			}
		else
			{
			al=SSL_AD_UNEXPECTED_MESSAGE;
			SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_UNEXPECTED_RECORD);
			goto f_err;
			}
		}
	/* not reached */

f_err:
	ssl3_send_alert(s,SSL3_AL_FATAL,al);
err:
	return(-1);
	}

int
dtls1_write_app_data_bytes(SSL *s, int type, const void *buf_, int len)
	{
	int i;

	if (SSL_in_init(s) && !s->in_handshake)
		{
		i=s->handshake_func(s);
		if (i < 0) return(i);
		if (i == 0)
			{
			SSLerr(SSL_F_DTLS1_WRITE_APP_DATA_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE);
			return -1;
			}
		}

	if (len > SSL3_RT_MAX_PLAIN_LENGTH)
		{
			SSLerr(SSL_F_DTLS1_WRITE_APP_DATA_BYTES,SSL_R_DTLS_MESSAGE_TOO_BIG);
			return -1;
		}

	i = dtls1_write_bytes(s, type, buf_, len);
	return i;
	}


	/* this only happens when a client hello is received and a handshake 
	 * is started. */
static int
have_handshake_fragment(SSL *s, int type, unsigned char *buf, 
	int len, int peek)
	{
	
	if ((type == SSL3_RT_HANDSHAKE) && (s->d1->handshake_fragment_len > 0))
		/* (partially) satisfy request from storage */
		{
		unsigned char *src = s->d1->handshake_fragment;
		unsigned char *dst = buf;
		unsigned int k,n;
		
		/* peek == 0 */
		n = 0;
		while ((len > 0) && (s->d1->handshake_fragment_len > 0))
			{
			*dst++ = *src++;
			len--; s->d1->handshake_fragment_len--;
			n++;
			}
		/* move any remaining fragment bytes: */
		for (k = 0; k < s->d1->handshake_fragment_len; k++)
			s->d1->handshake_fragment[k] = *src++;
		return n;
		}
	
	return 0;
	}




/* Call this to write data in records of type 'type'
 * It will return <= 0 if not all data has been sent or non-blocking IO.
 */
int dtls1_write_bytes(SSL *s, int type, const void *buf, int len)
	{
	int i;

	OPENSSL_assert(len <= SSL3_RT_MAX_PLAIN_LENGTH);
	s->rwstate=SSL_NOTHING;
	i=do_dtls1_write(s, type, buf, len, 0);
	return i;
	}

int do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len, int create_empty_fragment)
	{
	unsigned char *p,*pseq;
	int i,mac_size,clear=0;
	int prefix_len = 0;
	SSL3_RECORD *wr;
	SSL3_BUFFER *wb;
	SSL_SESSION *sess;
	int bs;
	unsigned int len_with_overhead = len + SSL3_RT_DEFAULT_WRITE_OVERHEAD;

	/* first check if there is a SSL3_BUFFER still being written
	 * out.  This will happen with non blocking IO */
	if (s->s3->wbuf.left != 0)
		{
		OPENSSL_assert(0); /* XDTLS:  want to see if we ever get here */
		return(ssl3_write_pending(s,type,buf,len));
		}

	if (s->s3->wbuf.len < len_with_overhead)
		{
		if ((p=OPENSSL_realloc(s->s3->wbuf.buf, len_with_overhead)) == NULL) {
			SSLerr(SSL_F_DO_DTLS1_WRITE,ERR_R_MALLOC_FAILURE);
			goto err;
		}
		s->s3->wbuf.buf = p;
		s->s3->wbuf.len = len_with_overhead;
		}

	/* If we have an alert to send, lets send it */
	if (s->s3->alert_dispatch)
		{
		i=s->method->ssl_dispatch_alert(s);
		if (i <= 0)
			return(i);
		/* if it went, fall through and send more stuff */
		}

	if (len == 0 && !create_empty_fragment)
		return 0;

	wr= &(s->s3->wrec);
	wb= &(s->s3->wbuf);
	sess=s->session;

	if (	(sess == NULL) ||
		(s->enc_write_ctx == NULL) ||
		(EVP_MD_CTX_md(s->write_hash) == NULL))
		clear=1;

	if (clear)
		mac_size=0;
	else
		{
		mac_size=EVP_MD_CTX_size(s->write_hash);
		if (mac_size < 0)
			goto err;
		}

	/* DTLS implements explicit IV, so no need for empty fragments */
#if 0
	/* 'create_empty_fragment' is true only when this function calls itself */
	if (!clear && !create_empty_fragment && !s->s3->empty_fragment_done
	    && SSL_version(s) != DTLS1_VERSION && SSL_version(s) != DTLS1_BAD_VER)
		{
		/* countermeasure against known-IV weakness in CBC ciphersuites
		 * (see http://www.openssl.org/~bodo/tls-cbc.txt) 
		 */

		if (s->s3->need_empty_fragments && type == SSL3_RT_APPLICATION_DATA)
			{
			/* recursive function call with 'create_empty_fragment' set;
			 * this prepares and buffers the data for an empty fragment
			 * (these 'prefix_len' bytes are sent out later
			 * together with the actual payload) */
			prefix_len = s->method->do_ssl_write(s, type, buf, 0, 1);
			if (prefix_len <= 0)
				goto err;

			if (s->s3->wbuf.len < (size_t)prefix_len + SSL3_RT_MAX_PACKET_SIZE)
				{
				/* insufficient space */
				SSLerr(SSL_F_DO_DTLS1_WRITE, ERR_R_INTERNAL_ERROR);
				goto err;
				}
			}
		
		s->s3->empty_fragment_done = 1;
		}
#endif
	p = wb->buf + prefix_len;

	/* write the header */

	*(p++)=type&0xff;
	wr->type=type;

	*(p++)=(s->version>>8);
	*(p++)=s->version&0xff;

	/* field where we are to write out packet epoch, seq num and len */
	pseq=p; 
	p+=10;

	/* lets setup the record stuff. */

	/* Make space for the explicit IV in case of CBC.
	 * (this is a bit of a boundary violation, but what the heck).
	 */
	if ( s->enc_write_ctx && 
		(EVP_CIPHER_mode( s->enc_write_ctx->cipher ) & EVP_CIPH_CBC_MODE))
		bs = EVP_CIPHER_block_size(s->enc_write_ctx->cipher);
	else
		bs = 0;

	wr->data=p + bs;  /* make room for IV in case of CBC */
	wr->length=(int)len;
	wr->input=(unsigned char *)buf;

	/* we now 'read' from wr->input, wr->length bytes into
	 * wr->data */

	/* first we compress */
	if (s->compress != NULL)
		{
		if (!ssl3_do_compress(s))
			{
			SSLerr(SSL_F_DO_DTLS1_WRITE,SSL_R_COMPRESSION_FAILURE);
			goto err;
			}
		}
	else
		{
		memcpy(wr->data,wr->input,wr->length);
		wr->input=wr->data;
		}

	/* we should still have the output to wr->data and the input
	 * from wr->input.  Length should be wr->length.
	 * wr->data still points in the wb->buf */

	if (mac_size != 0)
		{
		if(s->method->ssl3_enc->mac(s,&(p[wr->length + bs]),1) < 0)
			goto err;
		wr->length+=mac_size;
		}

	/* this is true regardless of mac size */
	wr->input=p;
	wr->data=p;


	/* ssl3_enc can only have an error on read */
	if (bs)	/* bs != 0 in case of CBC */
		{
		RAND_pseudo_bytes(p,bs);
		/* master IV and last CBC residue stand for
		 * the rest of randomness */
		wr->length += bs;
		}

	s->method->ssl3_enc->enc(s,1);

	/* record length after mac and block padding */
/*	if (type == SSL3_RT_APPLICATION_DATA ||
	(type == SSL3_RT_ALERT && ! SSL_in_init(s))) */
	
	/* there's only one epoch between handshake and app data */
	
	s2n(s->d1->w_epoch, pseq);

	/* XDTLS: ?? */
/*	else
	s2n(s->d1->handshake_epoch, pseq); */

	memcpy(pseq, &(s->s3->write_sequence[2]), 6);
	pseq+=6;
	s2n(wr->length,pseq);

	/* we should now have
	 * wr->data pointing to the encrypted data, which is
	 * wr->length long */
	wr->type=type; /* not needed but helps for debugging */
	wr->length+=DTLS1_RT_HEADER_LENGTH;

#if 0  /* this is now done at the message layer */
	/* buffer the record, making it easy to handle retransmits */
	if ( type == SSL3_RT_HANDSHAKE || type == SSL3_RT_CHANGE_CIPHER_SPEC)
		dtls1_buffer_record(s, wr->data, wr->length, 
			*((PQ_64BIT *)&(s->s3->write_sequence[0])));
#endif

	ssl3_record_sequence_update(&(s->s3->write_sequence[0]));

	if (create_empty_fragment)
		{
		/* we are in a recursive call;
		 * just return the length, don't write out anything here
		 */
		return wr->length;
		}

	/* now let's set up wb */
	wb->left = prefix_len + wr->length;
	wb->offset = 0;

	/* memorize arguments so that ssl3_write_pending can detect bad write retries later */
	s->s3->wpend_tot=len;
	s->s3->wpend_buf=buf;
	s->s3->wpend_type=type;
	s->s3->wpend_ret=len;

	/* we now just need to write the buffer */
	return ssl3_write_pending(s,type,buf,len);
err:
	return -1;
	}



static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap)
	{
	int cmp;
	unsigned int shift;
	const unsigned char *seq = s->s3->read_sequence;

	cmp = satsub64be(seq,bitmap->max_seq_num);
	if (cmp > 0)
		{
		memcpy (s->s3->rrec.seq_num,seq,8);
		return 1; /* this record in new */
		}
	shift = -cmp;
	if (shift >= sizeof(bitmap->map)*8)
		return 0; /* stale, outside the window */
	else if (bitmap->map & (1UL<<shift))
		return 0; /* record previously received */

	memcpy (s->s3->rrec.seq_num,seq,8);
	return 1;
	}


static void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap)
	{
	int cmp;
	unsigned int shift;
	const unsigned char *seq = s->s3->read_sequence;

	cmp = satsub64be(seq,bitmap->max_seq_num);
	if (cmp > 0)
		{
		shift = cmp;
		if (shift < sizeof(bitmap->map)*8)
			bitmap->map <<= shift, bitmap->map |= 1UL;
		else
			bitmap->map = 1UL;
		memcpy(bitmap->max_seq_num,seq,8);
		}
	else	{
		shift = -cmp;
		if (shift < sizeof(bitmap->map)*8)
			bitmap->map |= 1UL<<shift;
		}
	}


int dtls1_dispatch_alert(SSL *s)
	{
	int i,j;
	void (*cb)(const SSL *ssl,int type,int val)=NULL;
	unsigned char buf[DTLS1_AL_HEADER_LENGTH];
	unsigned char *ptr = &buf[0];

	s->s3->alert_dispatch=0;

	memset(buf, 0x00, sizeof(buf));
	*ptr++ = s->s3->send_alert[0];
	*ptr++ = s->s3->send_alert[1];

#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE
	if (s->s3->send_alert[1] == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE)
		{	
		s2n(s->d1->handshake_read_seq, ptr);
#if 0
		if ( s->d1->r_msg_hdr.frag_off == 0)  /* waiting for a new msg */

		else
			s2n(s->d1->r_msg_hdr.seq, ptr); /* partial msg read */
#endif

#if 0
		fprintf(stderr, "s->d1->handshake_read_seq = %d, s->d1->r_msg_hdr.seq = %d\n",s->d1->handshake_read_seq,s->d1->r_msg_hdr.seq);
#endif
		l2n3(s->d1->r_msg_hdr.frag_off, ptr);
		}
#endif

	i = do_dtls1_write(s, SSL3_RT_ALERT, &buf[0], sizeof(buf), 0);
	if (i <= 0)
		{
		s->s3->alert_dispatch=1;
		/* fprintf( stderr, "not done with alert\n" ); */
		}
	else
		{
		if (s->s3->send_alert[0] == SSL3_AL_FATAL
#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE
		    || s->s3->send_alert[1] == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE
#endif
		    )
			(void)BIO_flush(s->wbio);

		if (s->msg_callback)
			s->msg_callback(1, s->version, SSL3_RT_ALERT, s->s3->send_alert, 
				2, s, s->msg_callback_arg);

		if (s->info_callback != NULL)
			cb=s->info_callback;
		else if (s->ctx->info_callback != NULL)
			cb=s->ctx->info_callback;

		if (cb != NULL)
			{
			j=(s->s3->send_alert[0]<<8)|s->s3->send_alert[1];
			cb(s,SSL_CB_WRITE_ALERT,j);
			}
		}
	return(i);
	}


static DTLS1_BITMAP *
dtls1_get_bitmap(SSL *s, SSL3_RECORD *rr, unsigned int *is_next_epoch)
    {
    
    *is_next_epoch = 0;

    /* In current epoch, accept HM, CCS, DATA, & ALERT */
    if (rr->epoch == s->d1->r_epoch)
        return &s->d1->bitmap;

    /* Only HM and ALERT messages can be from the next epoch */
    else if (rr->epoch == (unsigned long)(s->d1->r_epoch + 1) &&
        (rr->type == SSL3_RT_HANDSHAKE ||
            rr->type == SSL3_RT_ALERT))
        {
        *is_next_epoch = 1;
        return &s->d1->next_bitmap;
        }

    return NULL;
    }

#if 0
static int
dtls1_record_needs_buffering(SSL *s, SSL3_RECORD *rr, unsigned short *priority,
	unsigned long *offset)
	{

	/* alerts are passed up immediately */
	if ( rr->type == SSL3_RT_APPLICATION_DATA ||
		rr->type == SSL3_RT_ALERT)
		return 0;

	/* Only need to buffer if a handshake is underway.
	 * (this implies that Hello Request and Client Hello are passed up
	 * immediately) */
	if ( SSL_in_init(s))
		{
		unsigned char *data = rr->data;
		/* need to extract the HM/CCS sequence number here */
		if ( rr->type == SSL3_RT_HANDSHAKE ||
			rr->type == SSL3_RT_CHANGE_CIPHER_SPEC)
			{
			unsigned short seq_num;
			struct hm_header_st msg_hdr;
			struct ccs_header_st ccs_hdr;

			if ( rr->type == SSL3_RT_HANDSHAKE)
				{
				dtls1_get_message_header(data, &msg_hdr);
				seq_num = msg_hdr.seq;
				*offset = msg_hdr.frag_off;
				}
			else
				{
				dtls1_get_ccs_header(data, &ccs_hdr);
				seq_num = ccs_hdr.seq;
				*offset = 0;
				}
				
			/* this is either a record we're waiting for, or a
			 * retransmit of something we happened to previously 
			 * receive (higher layers will drop the repeat silently */
			if ( seq_num < s->d1->handshake_read_seq)
				return 0;
			if (rr->type == SSL3_RT_HANDSHAKE && 
				seq_num == s->d1->handshake_read_seq &&
				msg_hdr.frag_off < s->d1->r_msg_hdr.frag_off)
				return 0;
			else if ( seq_num == s->d1->handshake_read_seq &&
				(rr->type == SSL3_RT_CHANGE_CIPHER_SPEC ||
					msg_hdr.frag_off == s->d1->r_msg_hdr.frag_off))
				return 0;
			else
				{
				*priority = seq_num;
				return 1;
				}
			}
		else /* unknown record type */
			return 0;
		}

	return 0;
	}
#endif

void
dtls1_reset_seq_numbers(SSL *s, int rw)
	{
	unsigned char *seq;
	unsigned int seq_bytes = sizeof(s->s3->read_sequence);

	if ( rw & SSL3_CC_READ)
		{
		seq = s->s3->read_sequence;
		s->d1->r_epoch++;
		memcpy(&(s->d1->bitmap), &(s->d1->next_bitmap), sizeof(DTLS1_BITMAP));
		memset(&(s->d1->next_bitmap), 0x00, sizeof(DTLS1_BITMAP));
		}
	else
		{
		seq = s->s3->write_sequence;
		memcpy(s->d1->last_write_sequence, seq, sizeof(s->s3->write_sequence));
		s->d1->w_epoch++;
		}

	memset(seq, 0x00, seq_bytes);
	}


static void
dtls1_clear_timeouts(SSL *s)
	{
	memset(&(s->d1->timeout), 0x00, sizeof(struct dtls1_timeout_st));
	}
