SSLerr(SSL_F_SSL3_GET_MESSAGE,SSL_R_UNEXPECTED_MESSAGE);
SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT,SSL_R_UNEXPECTED_MESSAGE);
dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok)	{	unsigned char *p;	unsigned long l, frag_off, frag_len;	int i,al;	struct hm_header_st msg_hdr;    unsigned long overlap;        /* see if we have the required fragment already */    if (dtls1_retrieve_buffered_fragment(s, &l))    {        /* compute MAC, remove fragment headers */        dtls1_process_handshake_fragment(s, l);        s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH;        s->state = stn;        return 1;    }    /* get a handshake fragment from the record layer */	p = (unsigned char *)s->init_buf->data;    /* read handshake message header */	i=s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,&p[s->init_num],		DTLS1_HM_HEADER_LENGTH, 0);	if (i <= 0) 	/* nbio, or an error */		{		s->rwstate=SSL_READING;		*ok = 0;		return i;		}	OPENSSL_assert(i == DTLS1_HM_HEADER_LENGTH);	p += s->init_num;    /* parse the message fragment header */        dtls1_get_message_header(p, &msg_hdr);    /*      * if this is a future (or stale) message it gets buffered     * (or dropped)--no further processing at this time      */    if ( msg_hdr.seq != s->d1->handshake_read_seq)        return dtls1_process_out_of_seq_message(s, &msg_hdr, ok);    l = msg_hdr.msg_len;    frag_off = msg_hdr.frag_off;	frag_len = msg_hdr.frag_len;    /* sanity checking */    if ( frag_off + frag_len > l)        {        al=SSL_AD_ILLEGAL_PARAMETER;        SSLerr(SSL_F_SSL3_GET_MESSAGE,SSL_R_EXCESSIVE_MESSAGE_SIZE);        goto f_err;        }	if (!s->server && s->d1->r_msg_hdr.frag_off == 0 &&        p[0] == SSL3_MT_HELLO_REQUEST)        {        /* The server may always send 'Hello Request' messages --         * we are doing a handshake anyway now, so ignore them         * if their format is correct. Does not count for         * 'Finished' MAC. */        if (p[1] == 0 && p[2] == 0 &&p[3] == 0)            {            if (s->msg_callback)                s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE,                     p, DTLS1_HM_HEADER_LENGTH, s,                     s->msg_callback_arg);                        s->init_num = 0;            return dtls1_get_message_fragment(s, st1, stn,                max, ok);            }        else /* Incorrectly formated Hello request */            {            al=SSL_AD_UNEXPECTED_MESSAGE;            SSLerr(SSL_F_SSL3_GET_MESSAGE,SSL_R_UNEXPECTED_MESSAGE);            goto f_err;            }        }    /* XDTLS: do a sanity check on the fragment */    s->init_num += i;	if ( s->d1->r_msg_hdr.frag_off == 0) /* first fragment */		{		/* BUF_MEM_grow takes an 'int' parameter */		if (l > (INT_MAX-DTLS1_HM_HEADER_LENGTH)) 			{			al=SSL_AD_ILLEGAL_PARAMETER;			SSLerr(SSL_F_SSL3_GET_MESSAGE,SSL_R_EXCESSIVE_MESSAGE_SIZE);			goto f_err;			}		if (l && !BUF_MEM_grow_clean(s->init_buf,(int)l			+ DTLS1_HM_HEADER_LENGTH))			{			SSLerr(SSL_F_SSL3_GET_MESSAGE,ERR_R_BUF_LIB);			goto err;			}        /* Only do this test when we're reading the expected message.         * Stale messages will be dropped and future messages will be buffered */        if ( l > (unsigned long)max)			{			al=SSL_AD_ILLEGAL_PARAMETER;			SSLerr(SSL_F_SSL3_GET_MESSAGE,SSL_R_EXCESSIVE_MESSAGE_SIZE);			goto f_err;			}		s->s3->tmp.message_size=l;		}    if ( frag_len > (unsigned long)max)        {        al=SSL_AD_ILLEGAL_PARAMETER;        SSLerr(SSL_F_SSL3_GET_MESSAGE,SSL_R_EXCESSIVE_MESSAGE_SIZE);        goto f_err;        }    if ( frag_len + s->init_num > (INT_MAX - DTLS1_HM_HEADER_LENGTH))        {        al=SSL_AD_ILLEGAL_PARAMETER;        SSLerr(SSL_F_SSL3_GET_MESSAGE,SSL_R_EXCESSIVE_MESSAGE_SIZE);        goto f_err;        }    if ( frag_len & !BUF_MEM_grow_clean(s->init_buf, (int)frag_len              + DTLS1_HM_HEADER_LENGTH + s->init_num))        {        SSLerr(SSL_F_SSL3_GET_MESSAGE,ERR_R_BUF_LIB);        goto err;        }	if ( s->d1->r_msg_hdr.frag_off == 0)		{		s->s3->tmp.message_type = msg_hdr.type;		s->d1->r_msg_hdr.type = msg_hdr.type;		s->d1->r_msg_hdr.msg_len = l;		/* s->d1->r_msg_hdr.seq = seq_num; */		}	/* XDTLS:  ressurect this when restart is in place */	s->state=stn;		/* next state (stn) */	p = (unsigned char *)s->init_buf->data;	if ( frag_len > 0)		{		i=s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,            &p[s->init_num],             frag_len,0);        /* XDTLS:  fix this--message fragments cannot span multiple packets */		if (i <= 0)			{			s->rwstate=SSL_READING;			*ok = 0;			return i;			}		}	else		i = 0;    /* XDTLS:  an incorrectly formatted fragment should cause the      * handshake to fail */	OPENSSL_assert(i == frag_len);#if 0    /* Successfully read a fragment.     * It may be (1) out of order, or     *           (2) it's a repeat, in which case we dump it     *           (3) the one we are expecting next (maybe with overlap)     * If it is next one, it may overlap with previously read bytes     */    /* case (1): buffer the future fragment      * (we can treat fragments from a future message the same     * as future fragments from the message being currently read, since     * they are sematically simply out of order.     */    if ( msg_hdr.seq > s->d1->handshake_read_seq ||        frag_off > s->init_num - DTLS1_HM_HEADER_LENGTH)    {        dtls1_buffer_handshake_fragment(s, &msg_hdr);        return DTLS1_HM_FRAGMENT_RETRY;    }    /* case (2):  drop the entire fragment, and try again */    if ( msg_hdr.seq < s->d1->handshake_read_seq ||        frag_off + frag_len < s->init_num - DTLS1_HM_HEADER_LENGTH)        {        s->init_num -= DTLS1_HM_HEADER_LENGTH;        return DTLS1_HM_FRAGMENT_RETRY;        }#endif    /* case (3): received a immediately useful fragment.  Determine the      * possible overlap and copy the fragment.     */    overlap = (s->init_num - DTLS1_HM_HEADER_LENGTH) - frag_off;            /* retain the header for the first fragment */    if ( s->init_num > DTLS1_HM_HEADER_LENGTH)        {        memmove(&(s->init_buf->data[s->init_num]),            &(s->init_buf->data[s->init_num + DTLS1_HM_HEADER_LENGTH + overlap]),            frag_len - overlap);        s->init_num += frag_len - overlap;        }    else        s->init_num += frag_len;    dtls1_process_handshake_fragment(s, frag_len - overlap);	if (s->msg_callback)		s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, s->init_buf->data, 			(size_t)s->init_num, s, 			s->msg_callback_arg);	*ok=1;	return s->init_num;f_err:	ssl3_send_alert(s,SSL3_AL_FATAL,al);    s->init_num = 0;err:	*ok=0;	return(-1);	}