/*
 *  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.
 */

/**
 * @file Data Channel Compression module function definitions.
 */

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

#include "syshead.h"

#if defined(ENABLE_LZO)

#include "comp.h"
#include "error.h"
#include "otime.h"

#include "memdbg.h"

/**
 * Perform adaptive compression housekeeping.
 *
 * @param ac the adaptive compression state structure.
 *
 * @return
 */
static bool
lzo_adaptive_compress_test(struct lzo_adaptive_compress *ac)
{
    const bool save = ac->compress_state;
    const time_t local_now = now;

    if (!ac->compress_state)
    {
        if (local_now >= ac->next)
        {
            if (ac->n_total > AC_MIN_BYTES
                && (ac->n_total - ac->n_comp) < (ac->n_total / (100 / AC_SAVE_PCT)))
            {
                ac->compress_state = true;
                ac->next = local_now + AC_OFF_SEC;
            }
            else
            {
                ac->next = local_now + AC_SAMP_SEC;
            }
            dmsg(D_COMP, "lzo_adaptive_compress_test: comp=%d total=%d", ac->n_comp, ac->n_total);
            ac->n_total = ac->n_comp = 0;
        }
    }
    else
    {
        if (local_now >= ac->next)
        {
            ac->next = local_now + AC_SAMP_SEC;
            ac->n_total = ac->n_comp = 0;
            ac->compress_state = false;
        }
    }

    if (ac->compress_state != save)
    {
        dmsg(D_COMP_LOW, "Adaptive compression state %s", (ac->compress_state ? "OFF" : "ON"));
    }

    return !ac->compress_state;
}

static inline void
lzo_adaptive_compress_data(struct lzo_adaptive_compress *ac, int n_total, int n_comp)
{
    ac->n_total += n_total;
    ac->n_comp += n_comp;
}

static void
lzo_compress_init(struct compress_context *compctx)
{
    msg(D_INIT_MEDIUM, "LZO compression initializing");
    ASSERT(!(compctx->flags & COMP_F_SWAP));
    compctx->wu.lzo.wmem_size = LZO_WORKSPACE;
    if (lzo_init() != LZO_E_OK)
    {
        msg(M_FATAL, "Cannot initialize LZO compression library");
    }
    compctx->wu.lzo.wmem = (lzo_voidp) lzo_malloc(compctx->wu.lzo.wmem_size);
    check_malloc_return(compctx->wu.lzo.wmem);
}

static void
lzo_compress_uninit(struct compress_context *compctx)
{
    lzo_free(compctx->wu.lzo.wmem);
    compctx->wu.lzo.wmem = NULL;
}

static inline bool
lzo_compression_enabled(struct compress_context *compctx)
{
    if (compctx->flags & COMP_F_ASYM)
    {
        return false;
    }
    else
    {
        if (compctx->flags & COMP_F_ADAPTIVE)
        {
            return lzo_adaptive_compress_test(&compctx->wu.lzo.ac);
        }
        else
        {
            return true;
        }
    }
}

static void
lzo_compress(struct buffer *buf, struct buffer work,
             struct compress_context *compctx,
             const struct frame *frame)
{
    lzo_uint zlen = 0;
    int err;
    bool compressed = false;

    if (buf->len <= 0)
    {
        return;
    }

    /*
     * In order to attempt compression, length must be at least COMPRESS_THRESHOLD,
     * and our adaptive level must give the OK.
     */
    if (buf->len >= COMPRESS_THRESHOLD && lzo_compression_enabled(compctx))
    {
        const size_t ps = PAYLOAD_SIZE(frame);
        ASSERT(buf_init(&work, FRAME_HEADROOM(frame)));
        ASSERT(buf_safe(&work, ps + COMP_EXTRA_BUFFER(ps)));

        if (buf->len > ps)
        {
            dmsg(D_COMP_ERRORS, "LZO compression buffer overflow");
            buf->len = 0;
            return;
        }

        err = LZO_COMPRESS(BPTR(buf), BLEN(buf), BPTR(&work), &zlen, compctx->wu.lzo.wmem);
        if (err != LZO_E_OK)
        {
            dmsg(D_COMP_ERRORS, "LZO compression error: %d", err);
            buf->len = 0;
            return;
        }

        ASSERT(buf_safe(&work, zlen));
        work.len = zlen;
        compressed = true;

        dmsg(D_COMP, "LZO compress %d -> %d", buf->len, work.len);
        compctx->pre_compress += buf->len;
        compctx->post_compress += work.len;

        /* tell adaptive level about our success or lack thereof in getting any size reduction */
        if (compctx->flags & COMP_F_ADAPTIVE)
        {
            lzo_adaptive_compress_data(&compctx->wu.lzo.ac, buf->len, work.len);
        }
    }

    /* did compression save us anything ? */
    if (compressed && work.len < buf->len)
    {
        uint8_t *header = buf_prepend(&work, 1);
        *header = LZO_COMPRESS_BYTE;
        *buf = work;
    }
    else
    {
        uint8_t *header = buf_prepend(buf, 1);
        *header = NO_COMPRESS_BYTE;
    }
}

static void
lzo_decompress(struct buffer *buf, struct buffer work,
               struct compress_context *compctx,
               const struct frame *frame)
{
    lzo_uint zlen = EXPANDED_SIZE(frame);
    int err;
    uint8_t c;          /* flag indicating whether or not our peer compressed */

    if (buf->len <= 0)
    {
        return;
    }

    ASSERT(buf_init(&work, FRAME_HEADROOM(frame)));

    c = *BPTR(buf);
    ASSERT(buf_advance(buf, 1));

    if (c == LZO_COMPRESS_BYTE) /* packet was compressed */
    {
        ASSERT(buf_safe(&work, zlen));
        err = LZO_DECOMPRESS(BPTR(buf), BLEN(buf), BPTR(&work), &zlen,
                             compctx->wu.lzo.wmem);
        if (err != LZO_E_OK)
        {
            dmsg(D_COMP_ERRORS, "LZO decompression error: %d", err);
            buf->len = 0;
            return;
        }

        ASSERT(buf_safe(&work, zlen));
        work.len = zlen;

        dmsg(D_COMP, "LZO decompress %d -> %d", buf->len, work.len);
        compctx->pre_decompress += buf->len;
        compctx->post_decompress += work.len;

        *buf = work;
    }
    else if (c == NO_COMPRESS_BYTE)     /* packet was not compressed */
    {
    }
    else
    {
        dmsg(D_COMP_ERRORS, "Bad LZO decompression header byte: %d", c);
        buf->len = 0;
    }
}

const struct compress_alg lzo_alg = {
    "lzo",
    lzo_compress_init,
    lzo_compress_uninit,
    lzo_compress,
    lzo_decompress
};

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