/*
 *  OpenVPN -- An application to securely tunnel IP networks
 *             over a single TCP/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"

#if P2MP

#include "buffer.h"
#include "error.h"
#include "integer.h"
#include "misc.h"
#include "mbuf.h"

#include "memdbg.h"

struct mbuf_set *
mbuf_init(unsigned int size)
{
    struct mbuf_set *ret;
    ALLOC_OBJ_CLEAR(ret, struct mbuf_set);
    ret->capacity = adjust_power_of_2(size);
    ALLOC_ARRAY(ret->array, struct mbuf_item, ret->capacity);
    return ret;
}

void
mbuf_free(struct mbuf_set *ms)
{
    if (ms)
    {
        int i;
        for (i = 0; i < (int) ms->len; ++i)
        {
            struct mbuf_item *item = &ms->array[MBUF_INDEX(ms->head, i, ms->capacity)];
            mbuf_free_buf(item->buffer);
        }
        free(ms->array);
        free(ms);
    }
}

struct mbuf_buffer *
mbuf_alloc_buf(const struct buffer *buf)
{
    struct mbuf_buffer *ret;
    ALLOC_OBJ(ret, struct mbuf_buffer);
    ret->buf = clone_buf(buf);
    ret->refcount = 1;
    ret->flags = 0;
    return ret;
}

void
mbuf_free_buf(struct mbuf_buffer *mb)
{
    if (mb)
    {
        if (--mb->refcount <= 0)
        {
            free_buf(&mb->buf);
            free(mb);
        }
    }
}

void
mbuf_add_item(struct mbuf_set *ms, const struct mbuf_item *item)
{
    ASSERT(ms);
    if (ms->len == ms->capacity)
    {
        struct mbuf_item rm;
        ASSERT(mbuf_extract_item(ms, &rm));
        mbuf_free_buf(rm.buffer);
        msg(D_MULTI_DROPPED, "MBUF: mbuf packet dropped");
    }

    ASSERT(ms->len < ms->capacity);

    ms->array[MBUF_INDEX(ms->head, ms->len, ms->capacity)] = *item;
    if (++ms->len > ms->max_queued)
    {
        ms->max_queued = ms->len;
    }
    ++item->buffer->refcount;
}

bool
mbuf_extract_item(struct mbuf_set *ms, struct mbuf_item *item)
{
    bool ret = false;
    if (ms)
    {
        while (ms->len)
        {
            *item = ms->array[ms->head];
            ms->head = MBUF_INDEX(ms->head, 1, ms->capacity);
            --ms->len;
            if (item->instance) /* ignore dereferenced instances */
            {
                ret = true;
                break;
            }
        }
    }
    return ret;
}

struct multi_instance *
mbuf_peek_dowork(struct mbuf_set *ms)
{
    struct multi_instance *ret = NULL;
    if (ms)
    {
        int i;
        for (i = 0; i < (int) ms->len; ++i)
        {
            struct mbuf_item *item = &ms->array[MBUF_INDEX(ms->head, i, ms->capacity)];
            if (item->instance)
            {
                ret = item->instance;
                break;
            }
        }
    }
    return ret;
}

void
mbuf_dereference_instance(struct mbuf_set *ms, struct multi_instance *mi)
{
    if (ms)
    {
        int i;
        for (i = 0; i < (int) ms->len; ++i)
        {
            struct mbuf_item *item = &ms->array[MBUF_INDEX(ms->head, i, ms->capacity)];
            if (item->instance == mi)
            {
                mbuf_free_buf(item->buffer);
                item->buffer = NULL;
                item->instance = NULL;
                msg(D_MBUF, "MBUF: dereferenced queued packet");
            }
        }
    }
}

#else  /* if P2MP */
static void
dummy(void)
{
}
#endif /* P2MP */
