/*
 * 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 <assert.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>

#include <openssl/buf.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/mem.h>
#include <openssl/obj.h>
#include <openssl/rand.h>
#include <openssl/x509.h>

#include "ssl_locl.h"

#define RSMBLY_BITMASK_SIZE(msg_len) (((msg_len) + 7) / 8)

#define RSMBLY_BITMASK_MARK(bitmask, start, end)                     \
  {                                                                  \
    if ((end) - (start) <= 8) {                                      \
      long ii;                                                       \
      for (ii = (start); ii < (end); ii++)                           \
        bitmask[((ii) >> 3)] |= (1 << ((ii)&7));                     \
    } else {                                                         \
      long ii;                                                       \
      bitmask[((start) >> 3)] |= bitmask_start_values[((start)&7)];  \
      for (ii = (((start) >> 3) + 1); ii < ((((end)-1)) >> 3); ii++) \
        bitmask[ii] = 0xff;                                          \
      bitmask[(((end)-1) >> 3)] |= bitmask_end_values[((end)&7)];    \
    }                                                                \
  }

#define RSMBLY_BITMASK_IS_COMPLETE(bitmask, msg_len, is_complete)           \
  {                                                                         \
    long ii;                                                                \
    assert((msg_len) > 0);                                                  \
    is_complete = 1;                                                        \
    if (bitmask[(((msg_len)-1) >> 3)] != bitmask_end_values[((msg_len)&7)]) \
      is_complete = 0;                                                      \
    if (is_complete)                                                        \
      for (ii = (((msg_len)-1) >> 3) - 1; ii >= 0; ii--)                    \
        if (bitmask[ii] != 0xff) {                                          \
          is_complete = 0;                                                  \
          break;                                                            \
        }                                                                   \
  }

static const uint8_t bitmask_start_values[] = {0xff, 0xfe, 0xfc, 0xf8,
                                               0xf0, 0xe0, 0xc0, 0x80};
static const uint8_t bitmask_end_values[] = {0xff, 0x01, 0x03, 0x07,
                                             0x0f, 0x1f, 0x3f, 0x7f};

/* XDTLS:  figure out the right values */
static const unsigned int g_probable_mtu[] = {1500 - 28, 512 - 28, 256 - 28};

static unsigned int dtls1_guess_mtu(unsigned int curr_mtu);
static void dtls1_fix_message_header(SSL *s, unsigned long frag_off,
                                     unsigned long frag_len);
static unsigned char *dtls1_write_message_header(SSL *s, unsigned char *p);
static void dtls1_set_message_header_int(SSL *s, unsigned char mt,
                                         unsigned long len,
                                         unsigned short seq_num,
                                         unsigned long frag_off,
                                         unsigned long frag_len);
static long dtls1_get_message_fragment(SSL *s, int stn, long max, int *ok);

static hm_fragment *dtls1_hm_fragment_new(unsigned long frag_len,
                                          int reassembly) {
  hm_fragment *frag = NULL;
  unsigned char *buf = NULL;
  unsigned char *bitmask = NULL;

  frag = (hm_fragment *)OPENSSL_malloc(sizeof(hm_fragment));
  if (frag == NULL) {
    return NULL;
  }

  if (frag_len) {
    buf = (unsigned char *)OPENSSL_malloc(frag_len);
    if (buf == NULL) {
      OPENSSL_free(frag);
      return NULL;
    }
  }

  /* zero length fragment gets zero frag->fragment */
  frag->fragment = buf;

  /* Initialize reassembly bitmask if necessary */
  if (reassembly) {
    bitmask = (unsigned char *)OPENSSL_malloc(RSMBLY_BITMASK_SIZE(frag_len));
    if (bitmask == NULL) {
      if (buf != NULL) {
        OPENSSL_free(buf);
      }
      OPENSSL_free(frag);
      return NULL;
    }
    memset(bitmask, 0, RSMBLY_BITMASK_SIZE(frag_len));
  }

  frag->reassembly = bitmask;

  return frag;
}

void dtls1_hm_fragment_free(hm_fragment *frag) {
  if (frag->msg_header.is_ccs) {
    EVP_CIPHER_CTX_free(frag->msg_header.saved_retransmit_state.enc_write_ctx);
    EVP_MD_CTX_destroy(frag->msg_header.saved_retransmit_state.write_hash);
  }
  if (frag->fragment) {
    OPENSSL_free(frag->fragment);
  }
  if (frag->reassembly) {
    OPENSSL_free(frag->reassembly);
  }
  OPENSSL_free(frag);
}

/* send s->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or
 * SSL3_RT_CHANGE_CIPHER_SPEC) */
int dtls1_do_write(
    SSL *s, int type,
    enum should_add_to_finished_hash should_add_to_finished_hash) {
  int ret;
  int curr_mtu;
  unsigned int len, frag_off, mac_size = 0, blocksize = 0;

  /* AHA!  Figure out the MTU, and stick to the right size */
  if (s->d1->mtu < dtls1_min_mtu() &&
      !(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)) {
    s->d1->mtu = BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL);

    /* I've seen the kernel return bogus numbers when it doesn't know
     * (initial write), so just make sure we have a reasonable number */
    if (s->d1->mtu < dtls1_min_mtu()) {
      s->d1->mtu = 0;
      s->d1->mtu = dtls1_guess_mtu(s->d1->mtu);
      BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SET_MTU, s->d1->mtu, NULL);
    }
  }

  /* should have something reasonable now */
  assert(s->d1->mtu >= dtls1_min_mtu());

  if (s->init_off == 0 && type == SSL3_RT_HANDSHAKE) {
    assert(s->init_num ==
           (int)s->d1->w_msg_hdr.msg_len + DTLS1_HM_HEADER_LENGTH);
  }

  if (s->write_hash &&
      (s->enc_write_ctx == NULL ||
       EVP_CIPHER_CTX_mode(s->enc_write_ctx) != EVP_CIPH_GCM_MODE)) {
    mac_size = EVP_MD_CTX_size(s->write_hash);
  }

  if (s->enc_write_ctx &&
      (EVP_CIPHER_CTX_mode(s->enc_write_ctx) == EVP_CIPH_CBC_MODE)) {
    blocksize = 2 * EVP_CIPHER_block_size(s->enc_write_ctx->cipher);
  }

  frag_off = 0;
  while (s->init_num) {
    curr_mtu = s->d1->mtu - BIO_wpending(SSL_get_wbio(s)) -
               DTLS1_RT_HEADER_LENGTH - mac_size - blocksize;

    if (curr_mtu <= DTLS1_HM_HEADER_LENGTH) {
      /* grr.. we could get an error if MTU picked was wrong */
      ret = BIO_flush(SSL_get_wbio(s));
      if (ret <= 0) {
        return ret;
      }
      curr_mtu = s->d1->mtu - DTLS1_RT_HEADER_LENGTH - mac_size - blocksize;
    }

    if (s->init_num > curr_mtu) {
      len = curr_mtu;
    } else {
      len = s->init_num;
    }

    /* XDTLS: this function is too long.  split out the CCS part */
    if (type == SSL3_RT_HANDSHAKE) {
      if (s->init_off != 0) {
        assert(s->init_off > DTLS1_HM_HEADER_LENGTH);
        s->init_off -= DTLS1_HM_HEADER_LENGTH;
        s->init_num += DTLS1_HM_HEADER_LENGTH;

        if (s->init_num > curr_mtu) {
          len = curr_mtu;
        } else {
          len = s->init_num;
        }
      }

      dtls1_fix_message_header(s, frag_off, len - DTLS1_HM_HEADER_LENGTH);

      dtls1_write_message_header(
          s, (uint8_t *)&s->init_buf->data[s->init_off]);

      assert(len >= DTLS1_HM_HEADER_LENGTH);
    }

    ret = dtls1_write_bytes(s, type, &s->init_buf->data[s->init_off], len);
    if (ret < 0) {
      /* might need to update MTU here, but we don't know which previous packet
       * caused the failure -- so can't really retransmit anything.  continue
       * as if everything is fine and wait for an alert to handle the
       * retransmit. */
      if (BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_MTU_EXCEEDED, 0, NULL) > 0) {
        s->d1->mtu =
            BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL);
      } else {
        return (-1);
      }
    } else {
      /* bad if this assert fails, only part of the handshake message got sent.
       * But why would this happen? */
      assert(len == (unsigned int)ret);

      if (type == SSL3_RT_HANDSHAKE && !s->d1->retransmitting &&
          should_add_to_finished_hash == add_to_finished_hash) {
        /* should not be done for 'Hello Request's, but in that case
         * we'll ignore the result anyway */
        uint8_t *p = (uint8_t *)&s->init_buf->data[s->init_off];
        const struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr;
        int xlen;

        if (frag_off == 0) {
          /* reconstruct message header is if it
           * is being sent in single fragment */
          *p++ = msg_hdr->type;
          l2n3(msg_hdr->msg_len, p);
          s2n(msg_hdr->seq, p);
          l2n3(0, p);
          l2n3(msg_hdr->msg_len, p);
          p -= DTLS1_HM_HEADER_LENGTH;
          xlen = ret;
        } else {
          p += DTLS1_HM_HEADER_LENGTH;
          xlen = ret - DTLS1_HM_HEADER_LENGTH;
        }

        ssl3_finish_mac(s, p, xlen);
      }

      if (ret == s->init_num) {
        if (s->msg_callback) {
          s->msg_callback(1, s->version, type, s->init_buf->data,
                          (size_t)(s->init_off + s->init_num), s,
                          s->msg_callback_arg);
        }

        s->init_off = 0; /* done writing this message */
        s->init_num = 0;

        return 1;
      }
      s->init_off += ret;
      s->init_num -= ret;
      frag_off += (ret -= DTLS1_HM_HEADER_LENGTH);
    }
  }

  return 0;
}


/* Obtain handshake message of message type 'mt' (any if mt == -1), maximum
 * acceptable body length 'max'. Read an entire handshake message. Handshake
 * messages arrive in fragments. */
long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max,
                       int hash_message, int *ok) {
  int i, al;
  struct hm_header_st *msg_hdr;
  uint8_t *p;
  unsigned long msg_len;

  /* s3->tmp is used to store messages that are unexpected, caused
   * by the absence of an optional handshake message */
  if (s->s3->tmp.reuse_message) {
    /* A SSL_GET_MESSAGE_DONT_HASH_MESSAGE call cannot be combined
     * with reuse_message; the SSL_GET_MESSAGE_DONT_HASH_MESSAGE
     * would have to have been applied to the previous call. */
    assert(hash_message != SSL_GET_MESSAGE_DONT_HASH_MESSAGE);
    s->s3->tmp.reuse_message = 0;
    if (mt >= 0 && s->s3->tmp.message_type != mt) {
      al = SSL_AD_UNEXPECTED_MESSAGE;
      OPENSSL_PUT_ERROR(SSL, dtls1_get_message, SSL_R_UNEXPECTED_MESSAGE);
      goto f_err;
    }
    *ok = 1;
    s->init_msg = (uint8_t *)s->init_buf->data + DTLS1_HM_HEADER_LENGTH;
    s->init_num = (int)s->s3->tmp.message_size;
    return s->init_num;
  }

  msg_hdr = &s->d1->r_msg_hdr;
  memset(msg_hdr, 0x00, sizeof(struct hm_header_st));

again:
  i = dtls1_get_message_fragment(s, stn, max, ok);
  if (i == DTLS1_HM_BAD_FRAGMENT ||
      i == DTLS1_HM_FRAGMENT_RETRY) {
    /* bad fragment received */
    goto again;
  } else if (i <= 0 && !*ok) {
    return i;
  }

  p = (uint8_t *)s->init_buf->data;
  msg_len = msg_hdr->msg_len;

  /* reconstruct message header */
  *(p++) = msg_hdr->type;
  l2n3(msg_len, p);
  s2n(msg_hdr->seq, p);
  l2n3(0, p);
  l2n3(msg_len, p);
  p -= DTLS1_HM_HEADER_LENGTH;
  msg_len += DTLS1_HM_HEADER_LENGTH;

  s->init_msg = (uint8_t *)s->init_buf->data + DTLS1_HM_HEADER_LENGTH;

  if (hash_message != SSL_GET_MESSAGE_DONT_HASH_MESSAGE) {
    ssl3_hash_current_message(s);
  }
  if (s->msg_callback) {
    s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, p, msg_len, s,
                    s->msg_callback_arg);
  }

  memset(msg_hdr, 0x00, sizeof(struct hm_header_st));

  s->d1->handshake_read_seq++;

  return s->init_num;

f_err:
  ssl3_send_alert(s, SSL3_AL_FATAL, al);
  *ok = 0;
  return -1;
}

static int dtls1_preprocess_fragment(SSL *s, struct hm_header_st *msg_hdr,
                                     int max) {
  size_t frag_off, frag_len, msg_len;

  msg_len = msg_hdr->msg_len;
  frag_off = msg_hdr->frag_off;
  frag_len = msg_hdr->frag_len;

  /* sanity checking */
  if ((frag_off + frag_len) > msg_len) {
    OPENSSL_PUT_ERROR(SSL, dtls1_preprocess_fragment,
                      SSL_R_EXCESSIVE_MESSAGE_SIZE);
    return SSL_AD_ILLEGAL_PARAMETER;
  }

  if ((frag_off + frag_len) > (unsigned long)max) {
    OPENSSL_PUT_ERROR(SSL, dtls1_preprocess_fragment,
                      SSL_R_EXCESSIVE_MESSAGE_SIZE);
    return SSL_AD_ILLEGAL_PARAMETER;
  }

  if (s->d1->r_msg_hdr.frag_off == 0) {
    /* first fragment */
    /* msg_len is limited to 2^24, but is effectively checked
     * against max above */
    if (!BUF_MEM_grow_clean(s->init_buf, msg_len + DTLS1_HM_HEADER_LENGTH)) {
      OPENSSL_PUT_ERROR(SSL, dtls1_preprocess_fragment, ERR_R_BUF_LIB);
      return SSL_AD_INTERNAL_ERROR;
    }

    s->s3->tmp.message_size = msg_len;
    s->d1->r_msg_hdr.msg_len = msg_len;
    s->s3->tmp.message_type = msg_hdr->type;
    s->d1->r_msg_hdr.type = msg_hdr->type;
    s->d1->r_msg_hdr.seq = msg_hdr->seq;
  } else if (msg_len != s->d1->r_msg_hdr.msg_len) {
    /* They must be playing with us! BTW, failure to enforce
     * upper limit would open possibility for buffer overrun. */
    OPENSSL_PUT_ERROR(SSL, dtls1_preprocess_fragment,
                      SSL_R_EXCESSIVE_MESSAGE_SIZE);
    return SSL_AD_ILLEGAL_PARAMETER;
  }

  return 0; /* no error */
}


static int dtls1_retrieve_buffered_fragment(SSL *s, long max, int *ok) {
  /* (0) check whether the desired fragment is available
   * if so:
   * (1) copy over the fragment to s->init_buf->data[]
   * (2) update s->init_num */
  pitem *item;
  hm_fragment *frag;
  int al;
  unsigned long frag_len;

  *ok = 0;
  item = pqueue_peek(s->d1->buffered_messages);
  if (item == NULL) {
    return 0;
  }

  frag = (hm_fragment *)item->data;

  /* Don't return if reassembly still in progress */
  if (frag->reassembly != NULL) {
    return 0;
  }

  if (s->d1->handshake_read_seq != frag->msg_header.seq) {
    return 0;
  }

  frag_len = frag->msg_header.frag_len;
  pqueue_pop(s->d1->buffered_messages);

  al = dtls1_preprocess_fragment(s, &frag->msg_header, max);

  if (al == 0) {
    /* no alert */
    uint8_t *p = (uint8_t *)s->init_buf->data + DTLS1_HM_HEADER_LENGTH;
    memcpy(&p[frag->msg_header.frag_off], frag->fragment,
           frag->msg_header.frag_len);
  }

  dtls1_hm_fragment_free(frag);
  pitem_free(item);

  if (al == 0) {
    *ok = 1;
    return frag_len;
  }

  ssl3_send_alert(s, SSL3_AL_FATAL, al);
  s->init_num = 0;
  *ok = 0;
  return -1;
}

/* dtls1_max_handshake_message_len returns the maximum number of bytes
 * permitted in a DTLS handshake message for |s|. The minimum is 16KB, but may
 * be greater if the maximum certificate list size requires it. */
static unsigned long dtls1_max_handshake_message_len(const SSL *s) {
  unsigned long max_len = DTLS1_HM_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH;
  if (max_len < (unsigned long)s->max_cert_list) {
    return s->max_cert_list;
  }
  return max_len;
}

static int dtls1_reassemble_fragment(SSL *s, const struct hm_header_st *msg_hdr,
                                     int *ok) {
  hm_fragment *frag = NULL;
  pitem *item = NULL;
  int i = -1, is_complete;
  uint8_t seq64be[8];
  unsigned long frag_len = msg_hdr->frag_len;

  if ((msg_hdr->frag_off + frag_len) > msg_hdr->msg_len ||
      msg_hdr->msg_len > dtls1_max_handshake_message_len(s)) {
    goto err;
  }

  if (frag_len == 0) {
    return DTLS1_HM_FRAGMENT_RETRY;
  }

  /* Try to find item in queue */
  memset(seq64be, 0, sizeof(seq64be));
  seq64be[6] = (uint8_t)(msg_hdr->seq >> 8);
  seq64be[7] = (uint8_t)msg_hdr->seq;
  item = pqueue_find(s->d1->buffered_messages, seq64be);

  if (item == NULL) {
    frag = dtls1_hm_fragment_new(msg_hdr->msg_len, 1);
    if (frag == NULL) {
      goto err;
    }
    memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr));
    frag->msg_header.frag_len = frag->msg_header.msg_len;
    frag->msg_header.frag_off = 0;
  } else {
    frag = (hm_fragment *)item->data;
    if (frag->msg_header.msg_len != msg_hdr->msg_len) {
      item = NULL;
      frag = NULL;
      goto err;
    }
  }

  /* If message is already reassembled, this must be a
   * retransmit and can be dropped. In this case item != NULL and so frag
   * does not need to be freed. */
  if (frag->reassembly == NULL) {
    uint8_t devnull[256];

    assert(item != NULL);
    while (frag_len) {
      i = s->method->ssl_read_bytes(
          s, SSL3_RT_HANDSHAKE, devnull,
          frag_len > sizeof(devnull) ? sizeof(devnull) : frag_len, 0);
      if (i <= 0) {
        goto err;
      }
      frag_len -= i;
    }
    return DTLS1_HM_FRAGMENT_RETRY;
  }

  /* read the body of the fragment (header has already been read */
  i = s->method->ssl_read_bytes(
      s, SSL3_RT_HANDSHAKE, frag->fragment + msg_hdr->frag_off, frag_len, 0);
  if ((unsigned long)i != frag_len) {
    i = -1;
  }
  if (i <= 0) {
    goto err;
  }

  RSMBLY_BITMASK_MARK(frag->reassembly, (long)msg_hdr->frag_off,
                      (long)(msg_hdr->frag_off + frag_len));

  RSMBLY_BITMASK_IS_COMPLETE(frag->reassembly, (long)msg_hdr->msg_len,
                             is_complete);

  if (is_complete) {
    OPENSSL_free(frag->reassembly);
    frag->reassembly = NULL;
  }

  if (item == NULL) {
    item = pitem_new(seq64be, frag);
    if (item == NULL) {
      i = -1;
      goto err;
    }

    item = pqueue_insert(s->d1->buffered_messages, item);
    /* pqueue_insert fails iff a duplicate item is inserted.
     * However, |item| cannot be a duplicate. If it were,
     * |pqueue_find|, above, would have returned it and control
     * would never have reached this branch. */
    assert(item != NULL);
  }

  return DTLS1_HM_FRAGMENT_RETRY;

err:
  if (frag != NULL && item == NULL) {
    dtls1_hm_fragment_free(frag);
  }
  *ok = 0;
  return i;
}

static int dtls1_process_out_of_seq_message(SSL *s,
                                            const struct hm_header_st *msg_hdr,
                                            int *ok) {
  int i = -1;
  hm_fragment *frag = NULL;
  pitem *item = NULL;
  uint8_t seq64be[8];
  unsigned long frag_len = msg_hdr->frag_len;

  if ((msg_hdr->frag_off + frag_len) > msg_hdr->msg_len) {
    goto err;
  }

  /* Try to find item in queue, to prevent duplicate entries */
  memset(seq64be, 0, sizeof(seq64be));
  seq64be[6] = (uint8_t)(msg_hdr->seq >> 8);
  seq64be[7] = (uint8_t)msg_hdr->seq;
  item = pqueue_find(s->d1->buffered_messages, seq64be);

  /* If we already have an entry and this one is a fragment,
   * don't discard it and rather try to reassemble it. */
  if (item != NULL && frag_len != msg_hdr->msg_len) {
    item = NULL;
  }

  /* Discard the message if sequence number was already there, is
   * too far in the future, already in the queue or if we received
   * a FINISHED before the SERVER_HELLO, which then must be a stale
   * retransmit. */
  if (msg_hdr->seq <= s->d1->handshake_read_seq ||
      msg_hdr->seq > s->d1->handshake_read_seq + 10 || item != NULL ||
      (s->d1->handshake_read_seq == 0 && msg_hdr->type == SSL3_MT_FINISHED)) {
    uint8_t devnull[256];

    while (frag_len) {
      i = s->method->ssl_read_bytes(
          s, SSL3_RT_HANDSHAKE, devnull,
          frag_len > sizeof(devnull) ? sizeof(devnull) : frag_len, 0);
      if (i <= 0) {
        goto err;
      }
      frag_len -= i;
    }
  } else {
    if (frag_len != msg_hdr->msg_len) {
      return dtls1_reassemble_fragment(s, msg_hdr, ok);
    }

    if (frag_len > dtls1_max_handshake_message_len(s)) {
      goto err;
    }

    frag = dtls1_hm_fragment_new(frag_len, 0);
    if (frag == NULL) {
      goto err;
    }

    memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr));

    if (frag_len) {
      /* read the body of the fragment (header has already been read */
      i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, frag->fragment,
                                    frag_len, 0);
      if ((unsigned long)i != frag_len) {
        i = -1;
      }
      if (i <= 0) {
        goto err;
      }
    }

    item = pitem_new(seq64be, frag);
    if (item == NULL) {
      goto err;
    }

    item = pqueue_insert(s->d1->buffered_messages, item);
    /* pqueue_insert fails iff a duplicate item is inserted.
     * However, |item| cannot be a duplicate. If it were,
     * |pqueue_find|, above, would have returned it. Then, either
     * |frag_len| != |msg_hdr->msg_len| in which case |item| is set
     * to NULL and it will have been processed with
     * |dtls1_reassemble_fragment|, above, or the record will have
     * been discarded. */
    assert(item != NULL);
  }

  return DTLS1_HM_FRAGMENT_RETRY;

err:
  if (frag != NULL && item == NULL) {
    dtls1_hm_fragment_free(frag);
  }
  *ok = 0;
  return i;
}


static long dtls1_get_message_fragment(SSL *s, int stn, long max, int *ok) {
  uint8_t wire[DTLS1_HM_HEADER_LENGTH];
  unsigned long len, frag_off, frag_len;
  int i, al;
  struct hm_header_st msg_hdr;

redo:
  /* see if we have the required fragment already */
  if ((frag_len = dtls1_retrieve_buffered_fragment(s, max, ok)) || *ok) {
    if (*ok) {
      s->init_num = frag_len;
    }
    return frag_len;
  }

  /* read handshake message header */
  i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, wire,
                                DTLS1_HM_HEADER_LENGTH, 0);
  if (i <= 0) {
    /* nbio, or an error */
    s->rwstate = SSL_READING;
    *ok = 0;
    return i;
  }

  /* Handshake fails if message header is incomplete */
  if (i != DTLS1_HM_HEADER_LENGTH) {
    al = SSL_AD_UNEXPECTED_MESSAGE;
    OPENSSL_PUT_ERROR(SSL, dtls1_get_message_fragment,
                      SSL_R_UNEXPECTED_MESSAGE);
    goto f_err;
  }

  /* parse the message fragment header */
  dtls1_get_message_header(wire, &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);
  }

  len = msg_hdr.msg_len;
  frag_off = msg_hdr.frag_off;
  frag_len = msg_hdr.frag_len;

  if (frag_len && frag_len < len) {
    return dtls1_reassemble_fragment(s, &msg_hdr, ok);
  }

  if (!s->server && s->d1->r_msg_hdr.frag_off == 0 &&
      wire[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 (wire[1] == 0 && wire[2] == 0 && wire[3] == 0) {
      if (s->msg_callback) {
        s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, wire,
                        DTLS1_HM_HEADER_LENGTH, s, s->msg_callback_arg);
      }

      s->init_num = 0;
      goto redo;
    } else {
      /* Incorrectly formated Hello request */
      al = SSL_AD_UNEXPECTED_MESSAGE;
      OPENSSL_PUT_ERROR(SSL, dtls1_get_message_fragment,
                        SSL_R_UNEXPECTED_MESSAGE);
      goto f_err;
    }
  }

  if ((al = dtls1_preprocess_fragment(s, &msg_hdr, max))) {
    goto f_err;
  }

  /* XDTLS:  ressurect this when restart is in place */
  s->state = stn;

  if (frag_len > 0) {
    uint8_t *p = (uint8_t *)s->init_buf->data + DTLS1_HM_HEADER_LENGTH;

    i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, &p[frag_off], 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 */
  if (i != (int)frag_len) {
    al = SSL3_AD_ILLEGAL_PARAMETER;
    OPENSSL_PUT_ERROR(SSL, dtls1_get_message_fragment,
                      SSL3_AD_ILLEGAL_PARAMETER);
    goto f_err;
  }

  *ok = 1;

  /* Note that s->init_num is *not* used as current offset in
   * s->init_buf->data, but as a counter summing up fragments'
   * lengths: as soon as they sum up to handshake packet
   * length, we assume we have got all the fragments. */
  s->init_num = frag_len;
  return frag_len;

f_err:
  ssl3_send_alert(s, SSL3_AL_FATAL, al);
  s->init_num = 0;

  *ok = 0;
  return -1;
}

/* for these 2 messages, we need to
 * ssl->enc_read_ctx			re-init
 * ssl->s3->read_sequence		zero
 * ssl->s3->read_mac_secret		re-init
 * ssl->session->read_sym_enc		assign
 * ssl->session->read_compression	assign
 * ssl->session->read_hash		assign */
int dtls1_send_change_cipher_spec(SSL *s, int a, int b) {
  uint8_t *p;

  if (s->state == a) {
    p = (uint8_t *)s->init_buf->data;
    *p++ = SSL3_MT_CCS;
    s->d1->handshake_write_seq = s->d1->next_handshake_write_seq;
    s->init_num = DTLS1_CCS_HEADER_LENGTH;

    s->init_off = 0;

    dtls1_set_message_header_int(s, SSL3_MT_CCS, 0, s->d1->handshake_write_seq,
                                 0, 0);

    /* buffer the message to handle re-xmits */
    dtls1_buffer_message(s, 1);

    s->state = b;
  }

  /* SSL3_ST_CW_CHANGE_B */
  return dtls1_do_write(s, SSL3_RT_CHANGE_CIPHER_SPEC,
                        dont_add_to_finished_hash);
}

int dtls1_read_failed(SSL *s, int code) {
  if (code > 0) {
    fprintf(stderr, "invalid state reached %s:%d", __FILE__, __LINE__);
    return 1;
  }

  if (!dtls1_is_timer_expired(s)) {
    /* not a timeout, none of our business, let higher layers handle this. In
     * fact, it's probably an error */
    return code;
  }

  if (!SSL_in_init(s)) {
    /* done, no need to send a retransmit */
    BIO_set_flags(SSL_get_rbio(s), BIO_FLAGS_READ);
    return code;
  }

  return dtls1_handle_timeout(s);
}

int dtls1_get_queue_priority(unsigned short seq, int is_ccs) {
  /* The index of the retransmission queue actually is the message sequence
   * number, since the queue only contains messages of a single handshake.
   * However, the ChangeCipherSpec has no message sequence number and so using
   * only the sequence will result in the CCS and Finished having the same
   * index. To prevent this, the sequence number is multiplied by 2. In case of
   * a CCS 1 is subtracted. This does not only differ CSS and Finished, it also
   * maintains the order of the index (important for priority queues) and fits
   * in the unsigned short variable. */
  return seq * 2 - is_ccs;
}

int dtls1_retransmit_buffered_messages(SSL *s) {
  pqueue sent = s->d1->sent_messages;
  piterator iter;
  pitem *item;
  hm_fragment *frag;
  int found = 0;

  iter = pqueue_iterator(sent);

  for (item = pqueue_next(&iter); item != NULL; item = pqueue_next(&iter)) {
    frag = (hm_fragment *)item->data;
    if (dtls1_retransmit_message(
            s, (unsigned short)dtls1_get_queue_priority(
                   frag->msg_header.seq, frag->msg_header.is_ccs),
            0, &found) <= 0 &&
        found) {
      fprintf(stderr, "dtls1_retransmit_message() failed\n");
      return -1;
    }
  }

  return 1;
}

int dtls1_buffer_message(SSL *s, int is_ccs) {
  pitem *item;
  hm_fragment *frag;
  uint8_t seq64be[8];

  /* this function is called immediately after a message has
   * been serialized */
  assert(s->init_off == 0);

  frag = dtls1_hm_fragment_new(s->init_num, 0);
  if (!frag) {
    return 0;
  }

  memcpy(frag->fragment, s->init_buf->data, s->init_num);

  if (is_ccs) {
    assert(s->d1->w_msg_hdr.msg_len + DTLS1_CCS_HEADER_LENGTH ==
           (unsigned int)s->init_num);
  } else {
    assert(s->d1->w_msg_hdr.msg_len + DTLS1_HM_HEADER_LENGTH ==
           (unsigned int)s->init_num);
  }

  frag->msg_header.msg_len = s->d1->w_msg_hdr.msg_len;
  frag->msg_header.seq = s->d1->w_msg_hdr.seq;
  frag->msg_header.type = s->d1->w_msg_hdr.type;
  frag->msg_header.frag_off = 0;
  frag->msg_header.frag_len = s->d1->w_msg_hdr.msg_len;
  frag->msg_header.is_ccs = is_ccs;

  /* save current state*/
  frag->msg_header.saved_retransmit_state.enc_write_ctx = s->enc_write_ctx;
  frag->msg_header.saved_retransmit_state.write_hash = s->write_hash;
  frag->msg_header.saved_retransmit_state.session = s->session;
  frag->msg_header.saved_retransmit_state.epoch = s->d1->w_epoch;

  memset(seq64be, 0, sizeof(seq64be));
  seq64be[6] = (uint8_t)(
      dtls1_get_queue_priority(frag->msg_header.seq, frag->msg_header.is_ccs) >>
      8);
  seq64be[7] = (uint8_t)(
      dtls1_get_queue_priority(frag->msg_header.seq, frag->msg_header.is_ccs));

  item = pitem_new(seq64be, frag);
  if (item == NULL) {
    dtls1_hm_fragment_free(frag);
    return 0;
  }

  pqueue_insert(s->d1->sent_messages, item);
  return 1;
}

int dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off,
                             int *found) {
  int ret;
  /* XDTLS: for now assuming that read/writes are blocking */
  pitem *item;
  hm_fragment *frag;
  unsigned long header_length;
  uint8_t seq64be[8];
  struct dtls1_retransmit_state saved_state;
  uint8_t save_write_sequence[8];

  /* assert(s->init_num == 0);
     assert(s->init_off == 0); */

  /* XDTLS:  the requested message ought to be found, otherwise error */
  memset(seq64be, 0, sizeof(seq64be));
  seq64be[6] = (uint8_t)(seq >> 8);
  seq64be[7] = (uint8_t)seq;

  item = pqueue_find(s->d1->sent_messages, seq64be);
  if (item == NULL) {
    fprintf(stderr, "retransmit:  message %d non-existant\n", seq);
    *found = 0;
    return 0;
  }

  *found = 1;
  frag = (hm_fragment *)item->data;

  if (frag->msg_header.is_ccs) {
    header_length = DTLS1_CCS_HEADER_LENGTH;
  } else {
    header_length = DTLS1_HM_HEADER_LENGTH;
  }

  memcpy(s->init_buf->data, frag->fragment,
         frag->msg_header.msg_len + header_length);
  s->init_num = frag->msg_header.msg_len + header_length;

  dtls1_set_message_header_int(s, frag->msg_header.type,
                               frag->msg_header.msg_len, frag->msg_header.seq,
                               0, frag->msg_header.frag_len);

  /* save current state */
  saved_state.enc_write_ctx = s->enc_write_ctx;
  saved_state.write_hash = s->write_hash;
  saved_state.session = s->session;
  saved_state.epoch = s->d1->w_epoch;

  s->d1->retransmitting = 1;

  /* restore state in which the message was originally sent */
  s->enc_write_ctx = frag->msg_header.saved_retransmit_state.enc_write_ctx;
  s->write_hash = frag->msg_header.saved_retransmit_state.write_hash;
  s->session = frag->msg_header.saved_retransmit_state.session;
  s->d1->w_epoch = frag->msg_header.saved_retransmit_state.epoch;

  if (frag->msg_header.saved_retransmit_state.epoch == saved_state.epoch - 1) {
    memcpy(save_write_sequence, s->s3->write_sequence,
           sizeof(s->s3->write_sequence));
    memcpy(s->s3->write_sequence, s->d1->last_write_sequence,
           sizeof(s->s3->write_sequence));
  }

  ret = dtls1_do_write(s, frag->msg_header.is_ccs ? SSL3_RT_CHANGE_CIPHER_SPEC
                                                  : SSL3_RT_HANDSHAKE,
                       add_to_finished_hash);

  /* restore current state */
  s->enc_write_ctx = saved_state.enc_write_ctx;
  s->write_hash = saved_state.write_hash;
  s->session = saved_state.session;
  s->d1->w_epoch = saved_state.epoch;

  if (frag->msg_header.saved_retransmit_state.epoch == saved_state.epoch - 1) {
    memcpy(s->d1->last_write_sequence, s->s3->write_sequence,
           sizeof(s->s3->write_sequence));
    memcpy(s->s3->write_sequence, save_write_sequence,
           sizeof(s->s3->write_sequence));
  }

  s->d1->retransmitting = 0;

  (void)BIO_flush(SSL_get_wbio(s));
  return ret;
}

/* call this function when the buffered messages are no longer needed */
void dtls1_clear_record_buffer(SSL *s) {
  pitem *item;

  for (item = pqueue_pop(s->d1->sent_messages); item != NULL;
       item = pqueue_pop(s->d1->sent_messages)) {
    dtls1_hm_fragment_free((hm_fragment *)item->data);
    pitem_free(item);
  }
}

uint8_t *dtls1_set_message_header(SSL *s, uint8_t *p, uint8_t mt,
                                  unsigned long len, unsigned long frag_off,
                                  unsigned long frag_len) {
  if (frag_off == 0) {
    s->d1->handshake_write_seq = s->d1->next_handshake_write_seq;
    s->d1->next_handshake_write_seq++;
  }

  dtls1_set_message_header_int(s, mt, len, s->d1->handshake_write_seq, frag_off,
                               frag_len);

  return p += DTLS1_HM_HEADER_LENGTH;
}

/* don't actually do the writing, wait till the MTU has been retrieved */
static void dtls1_set_message_header_int(SSL *s, uint8_t mt, unsigned long len,
                                         unsigned short seq_num,
                                         unsigned long frag_off,
                                         unsigned long frag_len) {
  struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr;

  msg_hdr->type = mt;
  msg_hdr->msg_len = len;
  msg_hdr->seq = seq_num;
  msg_hdr->frag_off = frag_off;
  msg_hdr->frag_len = frag_len;
}

static void dtls1_fix_message_header(SSL *s, unsigned long frag_off,
                                     unsigned long frag_len) {
  struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr;

  msg_hdr->frag_off = frag_off;
  msg_hdr->frag_len = frag_len;
}

static uint8_t *dtls1_write_message_header(SSL *s, uint8_t *p) {
  struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr;

  *p++ = msg_hdr->type;
  l2n3(msg_hdr->msg_len, p);

  s2n(msg_hdr->seq, p);
  l2n3(msg_hdr->frag_off, p);
  l2n3(msg_hdr->frag_len, p);

  return p;
}

unsigned int dtls1_min_mtu(void) {
  return g_probable_mtu[(sizeof(g_probable_mtu) / sizeof(g_probable_mtu[0])) -
                        1];
}

static unsigned int dtls1_guess_mtu(unsigned int curr_mtu) {
  unsigned int i;

  if (curr_mtu == 0) {
    return g_probable_mtu[0];
  }

  for (i = 0; i < sizeof(g_probable_mtu) / sizeof(g_probable_mtu[0]); i++) {
    if (curr_mtu > g_probable_mtu[i]) {
      return g_probable_mtu[i];
    }
  }

  return curr_mtu;
}

void dtls1_get_message_header(uint8_t *data,
                              struct hm_header_st *msg_hdr) {
  memset(msg_hdr, 0x00, sizeof(struct hm_header_st));
  msg_hdr->type = *(data++);
  n2l3(data, msg_hdr->msg_len);

  n2s(data, msg_hdr->seq);
  n2l3(data, msg_hdr->frag_off);
  n2l3(data, msg_hdr->frag_len);
}

void dtls1_get_ccs_header(uint8_t *data, struct ccs_header_st *ccs_hdr) {
  memset(ccs_hdr, 0x00, sizeof(struct ccs_header_st));

  ccs_hdr->type = *(data++);
}

int dtls1_shutdown(SSL *s) {
  int ret;
  ret = ssl3_shutdown(s);
  return ret;
}
