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

/*
 * Test protocol robustness by simulating dropped packets and
 * network outages when the --gremlin option is used.
 */

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

#include "syshead.h"

#ifdef ENABLE_DEBUG

#include "error.h"
#include "common.h"
#include "misc.h"
#include "otime.h"
#include "gremlin.h"

#include "memdbg.h"

/*
 * Parameters for packet corruption and droppage.
 * Each parameter has 4 possible levels, 0 = disabled,
 * while 1, 2, and 3 are enumerated in the below arrays.
 * The parameter is a 2-bit field within the --gremlin
 * parameter.
 */

/*
 * Probability that we will drop a packet is 1 / n
 */
static const int drop_freq[] = { 500, 100, 50 };

/*
 * Probability that we will corrupt a packet is 1 / n
 */
static const int corrupt_freq[] = { 500, 100, 50 };

/*
 * When network goes up, it will be up for between
 * UP_LOW and UP_HIGH seconds.
 */
static const int up_low[] =  {  60, 10,  5 };
static const int up_high[] = { 600, 60, 10 };

/*
 * When network goes down, it will be down for between
 * DOWN_LOW and DOWN_HIGH seconds.
 */
static const int down_low[] =  {  5, 10,  10 };
static const int down_high[] = { 10, 60, 120 };

/*
 * Packet flood levels:
 *  { number of packets, packet size }
 */
static const struct packet_flood_parms packet_flood_data[] =
{{10, 100}, {10, 1500}, {100, 1500}};

struct packet_flood_parms
get_packet_flood_parms(int level)
{
    ASSERT(level > 0 && level < 4);
    return packet_flood_data [level - 1];
}

/*
 * Return true with probability 1/n
 */
static bool
flip(int n)
{
    return (get_random() % n) == 0;
}

/*
 * Return uniformly distributed random number between
 * low and high.
 */
static int
roll(int low, int high)
{
    int ret;
    ASSERT(low <= high);
    ret = low + (get_random() % (high - low + 1));
    ASSERT(ret >= low && ret <= high);
    return ret;
}

static bool initialized; /* GLOBAL */
static bool up;          /* GLOBAL */
static time_t next;      /* GLOBAL */

/*
 * Return false if we should drop a packet.
 */
bool
ask_gremlin(int flags)
{
    const int up_down_level = GREMLIN_UP_DOWN_LEVEL(flags);
    const int drop_level = GREMLIN_DROP_LEVEL(flags);

    if (!initialized)
    {
        initialized = true;

        if (up_down_level)
        {
            up = false;
        }
        else
        {
            up = true;
        }

        next = now;
    }

    if (up_down_level) /* change up/down state? */
    {
        if (now >= next)
        {
            int delta;
            if (up)
            {
                delta = roll(down_low[up_down_level-1], down_high[up_down_level-1]);
                up = false;
            }
            else
            {
                delta = roll(up_low[up_down_level-1], up_high[up_down_level-1]);
                up = true;
            }

            msg(D_GREMLIN,
                "GREMLIN: CONNECTION GOING %s FOR %d SECONDS",
                (up ? "UP" : "DOWN"),
                delta);
            next = now + delta;
        }
    }

    if (drop_level)
    {
        if (up && flip(drop_freq[drop_level-1]))
        {
            dmsg(D_GREMLIN_VERBOSE, "GREMLIN: Random packet drop");
            return false;
        }
    }

    return up;
}

/*
 * Possibly corrupt a packet.
 */
void
corrupt_gremlin(struct buffer *buf, int flags)
{
    const int corrupt_level = GREMLIN_CORRUPT_LEVEL(flags);
    if (corrupt_level)
    {
        if (flip(corrupt_freq[corrupt_level-1]))
        {
            do
            {
                if (buf->len > 0)
                {
                    uint8_t r = roll(0, 255);
                    int method = roll(0, 5);

                    switch (method)
                    {
                        case 0: /* corrupt the first byte */
                            *BPTR(buf) = r;
                            break;

                        case 1: /* corrupt the last byte */
                            *(BPTR(buf) + buf->len - 1) = r;
                            break;

                        case 2: /* corrupt a random byte */
                            *(BPTR(buf) + roll(0, buf->len - 1)) = r;
                            break;

                        case 3: /* append a random byte */
                            buf_write(buf, &r, 1);
                            break;

                        case 4: /* reduce length by 1 */
                            --buf->len;
                            break;

                        case 5: /* reduce length by a random amount */
                            buf->len -= roll(0, buf->len - 1);
                            break;
                    }
                    dmsg(D_GREMLIN_VERBOSE, "GREMLIN: Packet Corruption, method=%d", method);
                }
                else
                {
                    break;
                }
            } while (flip(2));  /* a 50% chance we will corrupt again */
        }
    }
}

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