/*
 *  OpenVPN -- An application to securely tunnel IP networks
 *             over a single UDP port, with support for SSL/TLS-based
 *             session authentication and key exchange,
 *             packet encryption, packet authentication, and
 *             packet compression.
 *
 *  Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2
 *  as published by the Free Software Foundation.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#elif defined(_MSC_VER)
#include "config-msvc.h"
#endif

#include "syshead.h"

#ifdef ENABLE_FRAGMENT

#include "misc.h"
#include "fragment.h"
#include "integer.h"
#include "memdbg.h"

#define FRAG_ERR(s) { errmsg = s; goto error; }

static void
fragment_list_buf_init(struct fragment_list *list, const struct frame *frame)
{
    int i;
    for (i = 0; i < N_FRAG_BUF; ++i)
    {
        list->fragments[i].buf = alloc_buf(BUF_SIZE(frame));
    }
}

static void
fragment_list_buf_free(struct fragment_list *list)
{
    int i;
    for (i = 0; i < N_FRAG_BUF; ++i)
    {
        free_buf(&list->fragments[i].buf);
    }
}

/*
 * Given a sequence ID number, get a fragment buffer.  Use a sliding window,
 * similar to packet_id code.
 */
static struct fragment *
fragment_list_get_buf(struct fragment_list *list, int seq_id)
{
    int diff;
    if (abs(diff = modulo_subtract(seq_id, list->seq_id, N_SEQ_ID)) >= N_FRAG_BUF)
    {
        int i;
        for (i = 0; i < N_FRAG_BUF; ++i)
        {
            list->fragments[i].defined = false;
        }
        list->index = 0;
        list->seq_id = seq_id;
        diff = 0;
    }
    while (diff > 0)
    {
        list->fragments[list->index = modulo_add(list->index, 1, N_FRAG_BUF)].defined = false;
        list->seq_id = modulo_add(list->seq_id, 1, N_SEQ_ID);
        --diff;
    }
    return &list->fragments[modulo_add(list->index, diff, N_FRAG_BUF)];
}

struct fragment_master *
fragment_init(struct frame *frame)
{
    struct fragment_master *ret;

    /* code that initializes other parts of
     * fragment_master assume an initial CLEAR */
    ALLOC_OBJ_CLEAR(ret, struct fragment_master);

    /* add in the size of our contribution to the expanded frame size */
    frame_add_to_extra_frame(frame, sizeof(fragment_header_type));

    /*
     * Outgoing sequence ID is randomized to reduce
     * the probability of sequence number collisions
     * when openvpn sessions are restarted.  This is
     * not done out of any need for security, as all
     * fragmentation control information resides
     * inside of the encrypted/authenticated envelope.
     */
    ret->outgoing_seq_id = (int)get_random() & (N_SEQ_ID - 1);

    event_timeout_init(&ret->wakeup, FRAG_WAKEUP_INTERVAL, now);

    return ret;
}

void
fragment_free(struct fragment_master *f)
{
    fragment_list_buf_free(&f->incoming);
    free_buf(&f->outgoing);
    free_buf(&f->outgoing_return);
    free(f);
}

void
fragment_frame_init(struct fragment_master *f, const struct frame *frame)
{
    fragment_list_buf_init(&f->incoming, frame);
    f->outgoing = alloc_buf(BUF_SIZE(frame));
    f->outgoing_return = alloc_buf(BUF_SIZE(frame));
}

/*
 * Accept an incoming datagram (which may be a fragment) from remote.
 * If the datagram is whole (i.e not a fragment), pass through.
 * If the datagram is a fragment, join with other fragments received so far.
 * If a fragment fully completes the datagram, return the datagram.
 */
void
fragment_incoming(struct fragment_master *f, struct buffer *buf,
                  const struct frame *frame)
{
    const char *errmsg = NULL;
    fragment_header_type flags = 0;
    int frag_type = 0;

    if (buf->len > 0)
    {
        /* get flags from packet head */
        if (!buf_read(buf, &flags, sizeof(flags)))
        {
            FRAG_ERR("flags not found in packet");
        }
        flags = ntoh_fragment_header_type(flags);

        /* get fragment type from flags */
        frag_type = ((flags >> FRAG_TYPE_SHIFT) & FRAG_TYPE_MASK);

#if 0
        /*
         * If you want to extract FRAG_EXTRA_MASK/FRAG_EXTRA_SHIFT bits,
         * do it here.
         */
        if (frag_type == FRAG_WHOLE || frag_type == FRAG_YES_NOTLAST)
        {
        }
#endif

        /* handle the fragment type */
        if (frag_type == FRAG_WHOLE)
        {
            dmsg(D_FRAG_DEBUG,
                 "FRAG_IN buf->len=%d type=FRAG_WHOLE flags="
                 fragment_header_format,
                 buf->len,
                 flags);

            if (flags & (FRAG_SEQ_ID_MASK | FRAG_ID_MASK))
            {
                FRAG_ERR("spurrious FRAG_WHOLE flags");
            }
        }
        else if (frag_type == FRAG_YES_NOTLAST || frag_type == FRAG_YES_LAST)
        {
            const int seq_id = ((flags >> FRAG_SEQ_ID_SHIFT) & FRAG_SEQ_ID_MASK);
            const int n = ((flags >> FRAG_ID_SHIFT) & FRAG_ID_MASK);
            const int size = ((frag_type == FRAG_YES_LAST)
                              ? (int)(((flags >> FRAG_SIZE_SHIFT) & FRAG_SIZE_MASK) << FRAG_SIZE_ROUND_SHIFT)
                              : buf->len);

            /* get the appropriate fragment buffer based on received seq_id */
            struct fragment *frag = fragment_list_get_buf(&f->incoming, seq_id);

            dmsg(D_FRAG_DEBUG,
                 "FRAG_IN len=%d type=%d seq_id=%d frag_id=%d size=%d flags="
                 fragment_header_format,
                 buf->len,
                 frag_type,
                 seq_id,
                 n,
                 size,
                 flags);

            /* make sure that size is an even multiple of 1<<FRAG_SIZE_ROUND_SHIFT */
            if (size & FRAG_SIZE_ROUND_MASK)
            {
                FRAG_ERR("bad fragment size");
            }

            /* is this the first fragment for our sequence number? */
            if (!frag->defined || frag->max_frag_size != size)
            {
                frag->defined = true;
                frag->max_frag_size = size;
                frag->map = 0;
                ASSERT(buf_init(&frag->buf, FRAME_HEADROOM_ADJ(frame, FRAME_HEADROOM_MARKER_FRAGMENT)));
            }

            /* copy the data to fragment buffer */
            if (!buf_copy_range(&frag->buf, n * size, buf, 0, buf->len))
            {
                FRAG_ERR("fragment buffer overflow");
            }

            /* set elements in bit array to reflect which fragments have been received */
            frag->map |= (((frag_type == FRAG_YES_LAST) ? FRAG_MAP_MASK : 1) << n);

            /* update timestamp on partially built datagram */
            frag->timestamp = now;

            /* received full datagram? */
            if ((frag->map & FRAG_MAP_MASK) == FRAG_MAP_MASK)
            {
                frag->defined = false;
                *buf = frag->buf;
            }
            else
            {
                buf->len = 0;
            }
        }
        else if (frag_type == FRAG_TEST)
        {
            FRAG_ERR("FRAG_TEST not implemented");
        }
        else
        {
            FRAG_ERR("unknown fragment type");
        }
    }

    return;

error:
    if (errmsg)
    {
        msg(D_FRAG_ERRORS, "FRAG_IN error flags=" fragment_header_format ": %s", flags, errmsg);
    }
    buf->len = 0;
    return;
}

/* pack fragment parms into a uint32_t and prepend to buffer */
static void
fragment_prepend_flags(struct buffer *buf,
                       int type,
                       int seq_id,
                       int frag_id,
                       int frag_size)
{
    fragment_header_type flags = ((type & FRAG_TYPE_MASK) << FRAG_TYPE_SHIFT)
                                 | ((seq_id & FRAG_SEQ_ID_MASK) << FRAG_SEQ_ID_SHIFT)
                                 | ((frag_id & FRAG_ID_MASK) << FRAG_ID_SHIFT);

    if (type == FRAG_WHOLE || type == FRAG_YES_NOTLAST)
    {
        /*
         * If you want to set FRAG_EXTRA_MASK/FRAG_EXTRA_SHIFT bits,
         * do it here.
         */
        dmsg(D_FRAG_DEBUG,
             "FRAG_OUT len=%d type=%d seq_id=%d frag_id=%d frag_size=%d flags="
             fragment_header_format,
             buf->len, type, seq_id, frag_id, frag_size, flags);
    }
    else
    {
        flags |= (((frag_size >> FRAG_SIZE_ROUND_SHIFT) & FRAG_SIZE_MASK) << FRAG_SIZE_SHIFT);

        dmsg(D_FRAG_DEBUG,
             "FRAG_OUT len=%d type=%d seq_id=%d frag_id=%d frag_size=%d flags="
             fragment_header_format,
             buf->len, type, seq_id, frag_id, frag_size, flags);
    }

    flags = hton_fragment_header_type(flags);
    ASSERT(buf_write_prepend(buf, &flags, sizeof(flags)));
}

/*
 * Without changing the number of fragments, return a possibly smaller
 * max fragment size that will allow for the last fragment to be of
 * similar size as previous fragments.
 */
static inline int
optimal_fragment_size(int len, int max_frag_size)
{
    const int mfs_aligned = (max_frag_size & ~FRAG_SIZE_ROUND_MASK);
    const int div = len / mfs_aligned;
    const int mod = len % mfs_aligned;

    if (div > 0 && mod > 0 && mod < mfs_aligned * 3 / 4)
    {
        return min_int(mfs_aligned, (max_frag_size - ((max_frag_size - mod) / (div + 1))
                                     + FRAG_SIZE_ROUND_MASK) & ~FRAG_SIZE_ROUND_MASK);
    }
    else
    {
        return mfs_aligned;
    }
}

/* process an outgoing datagram, possibly breaking it up into fragments */
void
fragment_outgoing(struct fragment_master *f, struct buffer *buf,
                  const struct frame *frame)
{
    const char *errmsg = NULL;
    if (buf->len > 0)
    {
        /* The outgoing buffer should be empty so we can put new data in it */
        if (f->outgoing.len)
        {
            msg(D_FRAG_ERRORS, "FRAG: outgoing buffer is not empty, len=[%d,%d]",
                buf->len, f->outgoing.len);
        }
        if (buf->len > PAYLOAD_SIZE_DYNAMIC(frame)) /* should we fragment? */
        {
            /*
             * Send the datagram as a series of 2 or more fragments.
             */
            f->outgoing_frag_size = optimal_fragment_size(buf->len, PAYLOAD_SIZE_DYNAMIC(frame));
            if (buf->len > f->outgoing_frag_size * MAX_FRAGS)
            {
                FRAG_ERR("too many fragments would be required to send datagram");
            }
            ASSERT(buf_init(&f->outgoing, FRAME_HEADROOM(frame)));
            ASSERT(buf_copy(&f->outgoing, buf));
            f->outgoing_seq_id = modulo_add(f->outgoing_seq_id, 1, N_SEQ_ID);
            f->outgoing_frag_id = 0;
            buf->len = 0;
            ASSERT(fragment_ready_to_send(f, buf, frame));
        }
        else
        {
            /*
             * Send the datagram whole.
             */
            fragment_prepend_flags(buf,
                                   FRAG_WHOLE,
                                   0,
                                   0,
                                   0);
        }
    }
    return;

error:
    if (errmsg)
    {
        msg(D_FRAG_ERRORS, "FRAG_OUT error, len=%d frag_size=%d MAX_FRAGS=%d: %s",
            buf->len, f->outgoing_frag_size, MAX_FRAGS, errmsg);
    }
    buf->len = 0;
    return;
}

/* return true (and set buf) if we have an outgoing fragment which is ready to send */
bool
fragment_ready_to_send(struct fragment_master *f, struct buffer *buf,
                       const struct frame *frame)
{
    if (fragment_outgoing_defined(f))
    {
        /* get fragment size, and determine if it is the last fragment */
        int size = f->outgoing_frag_size;
        int last = false;
        if (f->outgoing.len <= size)
        {
            size = f->outgoing.len;
            last = true;
        }

        /* initialize return buffer */
        *buf = f->outgoing_return;
        ASSERT(buf_init(buf, FRAME_HEADROOM(frame)));
        ASSERT(buf_copy_n(buf, &f->outgoing, size));

        /* fragment flags differ based on whether or not we are sending the last fragment */
        fragment_prepend_flags(buf,
                               last ? FRAG_YES_LAST : FRAG_YES_NOTLAST,
                               f->outgoing_seq_id,
                               f->outgoing_frag_id++,
                               f->outgoing_frag_size);

        ASSERT(!last || !f->outgoing.len); /* outgoing buffer length should be zero after last fragment sent */

        return true;
    }
    else
    {
        return false;
    }
}

static void
fragment_ttl_reap(struct fragment_master *f)
{
    int i;
    for (i = 0; i < N_FRAG_BUF; ++i)
    {
        struct fragment *frag = &f->incoming.fragments[i];
        if (frag->defined && frag->timestamp + FRAG_TTL_SEC <= now)
        {
            msg(D_FRAG_ERRORS, "FRAG TTL expired i=%d", i);
            frag->defined = false;
        }
    }
}

/* called every FRAG_WAKEUP_INTERVAL seconds */
void
fragment_wakeup(struct fragment_master *f, struct frame *frame)
{
    /* delete fragments with expired TTLs */
    fragment_ttl_reap(f);
}

#else  /* ifdef ENABLE_FRAGMENT */
static void
dummy(void)
{
}
#endif /* ifdef ENABLE_FRAGMENT */
