/*
 *  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-2021 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"

#include "pool.h"
#include "buffer.h"
#include "error.h"
#include "socket.h"
#include "otime.h"

#include "memdbg.h"

#if P2MP

static void
ifconfig_pool_entry_free(struct ifconfig_pool_entry *ipe, bool hard)
{
    ipe->in_use = false;
    if (hard && ipe->common_name)
    {
        free(ipe->common_name);
        ipe->common_name = NULL;
    }
    if (hard)
    {
        ipe->last_release = 0;
    }
    else
    {
        ipe->last_release = now;
    }
}

static int
ifconfig_pool_find(struct ifconfig_pool *pool, const char *common_name)
{
    int i;
    time_t earliest_release = 0;
    int previous_usage = -1;
    int new_usage = -1;

    for (i = 0; i < pool->size; ++i)
    {
        struct ifconfig_pool_entry *ipe = &pool->list[i];
        if (!ipe->in_use)
        {
            /*
             * If duplicate_cn mode, take first available IP address
             */
            if (pool->duplicate_cn)
            {
                new_usage = i;
                break;
            }

            /*
             * Keep track of the unused IP address entry which
             * was released earliest.
             */
            if ((new_usage == -1 || ipe->last_release < earliest_release) && !ipe->fixed)
            {
                earliest_release = ipe->last_release;
                new_usage = i;
            }

            /*
             * Keep track of a possible allocation to us
             * from an earlier session.
             */
            if (previous_usage < 0
                && common_name
                && ipe->common_name
                && !strcmp(common_name, ipe->common_name))
            {
                previous_usage = i;
            }

        }
    }

    if (previous_usage >= 0)
    {
        return previous_usage;
    }

    if (new_usage >= 0)
    {
        return new_usage;
    }

    return -1;
}

/*
 * Verify start/end range
 */
bool
ifconfig_pool_verify_range(const int msglevel, const in_addr_t start, const in_addr_t end)
{
    struct gc_arena gc = gc_new();
    bool ret = true;

    if (start > end)
    {
        msg(msglevel, "--ifconfig-pool start IP [%s] is greater than end IP [%s]",
            print_in_addr_t(start, 0, &gc),
            print_in_addr_t(end, 0, &gc));
        ret = false;
    }
    if (end - start >= IFCONFIG_POOL_MAX)
    {
        msg(msglevel, "--ifconfig-pool address range is too large [%s -> %s].  Current maximum is %d addresses, as defined by IFCONFIG_POOL_MAX variable.",
            print_in_addr_t(start, 0, &gc),
            print_in_addr_t(end, 0, &gc),
            IFCONFIG_POOL_MAX);
        ret = false;
    }
    gc_free(&gc);
    return ret;
}

struct ifconfig_pool *
ifconfig_pool_init(const bool ipv4_pool, enum pool_type type, in_addr_t start,
                   in_addr_t end, const bool duplicate_cn,
                   const bool ipv6_pool, const struct in6_addr ipv6_base,
                   const int ipv6_netbits )
{
    struct gc_arena gc = gc_new();
    struct ifconfig_pool *pool = NULL;
    int pool_ipv4_size = -1, pool_ipv6_size = -1;

    ASSERT(start <= end && end - start < IFCONFIG_POOL_MAX);
    ALLOC_OBJ_CLEAR(pool, struct ifconfig_pool);

    pool->duplicate_cn = duplicate_cn;

    pool->ipv4.enabled = ipv4_pool;

    if (pool->ipv4.enabled)
    {
        pool->ipv4.type = type;
        switch (pool->ipv4.type)
        {
            case IFCONFIG_POOL_30NET:
                pool->ipv4.base = start & ~3;
                pool_ipv4_size = (((end | 3) + 1) - pool->ipv4.base) >> 2;
                break;

            case IFCONFIG_POOL_INDIV:
                pool->ipv4.base = start;
                pool_ipv4_size = end - start + 1;
                break;

            default:
                ASSERT(0);
        }

        if (pool_ipv4_size < 2)
        {
            msg(M_FATAL, "IPv4 pool size is too small (%d), must be at least 2",
                pool_ipv4_size);
        }

        msg(D_IFCONFIG_POOL, "IFCONFIG POOL IPv4: base=%s size=%d",
            print_in_addr_t(pool->ipv4.base, 0, &gc), pool_ipv4_size);

        pool->size = pool_ipv4_size;
    }

    /* IPv6 pools are always "INDIV" type */
    pool->ipv6.enabled = ipv6_pool;

    if (pool->ipv6.enabled)
    {
        /* the host portion of the address will always be contained in the last
         * 4 bytes, therefore we can just extract that and use it as base in
         * integer form
         */
        uint32_t base = (ipv6_base.s6_addr[12] << 24)
                        | (ipv6_base.s6_addr[13] << 16)
                        | (ipv6_base.s6_addr[14] << 8)
                        | ipv6_base.s6_addr[15];
        /* some bits of the last 4 bytes may still be part of the network
         * portion of the address, therefore we need to set them to 0
         */
        if ((128 - ipv6_netbits) < 32)
        {
            /* extract only the bits that are really part of the host portion of
             * the address.
             *
             * Example: if we have netbits=31, the first bit has to be zero'd,
             * the following operation first computes mask=0x3fffff and then
             * uses mask to extract the wanted bits from base
             */
            uint32_t mask = (1 << (128 - ipv6_netbits) ) - 1;
            base &= mask;
        }

        pool->ipv6.base = ipv6_base;

        /* if a pool starts at a base address that has all-zero in the
         * host part, that first IPv6 address must not be assigned to
         * clients because it is not usable (subnet anycast address).
         * Start with 1, then.
         *
         * NOTE: this will also (mis-)fire for something like
         *    ifconfig-ipv6-pool 2001:db8:0:1:1234::0/64
         * as we only check the rightmost 32 bits of the host part.  So be it.
         */
        if (base == 0)
        {
            msg(D_IFCONFIG_POOL, "IFCONFIG POOL IPv6: incrementing pool start "
                "to avoid ::0 assignment");
            base++;
            pool->ipv6.base.s6_addr[15]++;
        }

        pool_ipv6_size = ipv6_netbits >= 112
                          ? (1 << (128 - ipv6_netbits)) - base
                          : IFCONFIG_POOL_MAX;

        if (pool_ipv6_size < 2)
        {
            msg(M_FATAL, "IPv6 pool size is too small (%d), must be at least 2",
                pool_ipv6_size);
        }

        msg(D_IFCONFIG_POOL, "IFCONFIG POOL IPv6: base=%s size=%d netbits=%d",
            print_in6_addr(pool->ipv6.base, 0, &gc), pool_ipv6_size,
            ipv6_netbits);

        /* if there is no v4 pool, or the v6 pool is smaller, use
         * v6 pool size as "unified pool size"
         */
        if (pool->size <= 0 || pool_ipv6_size < pool->size)
        {
            pool->size = pool_ipv6_size;
        }
    }

    if (pool->ipv4.enabled && pool->ipv6.enabled)
    {
        if (pool_ipv4_size < pool_ipv6_size)
        {
            msg(M_INFO, "NOTE: IPv4 pool size is %d, IPv6 pool size is %d. "
                "IPv4 pool size limits the number of clients that can be "
                "served from the pool", pool_ipv4_size, pool_ipv6_size);
        }
        else if (pool_ipv4_size > pool_ipv6_size)
        {
            msg(M_WARN, "WARNING: IPv4 pool size is %d, IPv6 pool size is %d. "
                "IPv6 pool size limits the number of clients that can be "
                "served from the pool. This is likely a MISTAKE - please check "
                "your configuration", pool_ipv4_size, pool_ipv6_size);
        }
    }

    ASSERT(pool->size > 0);

    ALLOC_ARRAY_CLEAR(pool->list, struct ifconfig_pool_entry, pool->size);

    gc_free(&gc);
    return pool;
}

void
ifconfig_pool_free(struct ifconfig_pool *pool)
{
    if (pool)
    {
        int i;

        for (i = 0; i < pool->size; ++i)
        {
            ifconfig_pool_entry_free(&pool->list[i], true);
        }
        free(pool->list);
        free(pool);
    }
}

ifconfig_pool_handle
ifconfig_pool_acquire(struct ifconfig_pool *pool, in_addr_t *local, in_addr_t *remote, struct in6_addr *remote_ipv6, const char *common_name)
{
    int i;

    i = ifconfig_pool_find(pool, common_name);
    if (i >= 0)
    {
        struct ifconfig_pool_entry *ipe = &pool->list[i];
        ASSERT(!ipe->in_use);
        ifconfig_pool_entry_free(ipe, true);
        ipe->in_use = true;
        if (common_name)
        {
            ipe->common_name = string_alloc(common_name, NULL);
        }

        if (pool->ipv4.enabled && local && remote)
        {
            switch (pool->ipv4.type)
            {
                case IFCONFIG_POOL_30NET:
                {
                    in_addr_t b = pool->ipv4.base + (i << 2);
                    *local = b + 1;
                    *remote = b + 2;
                    break;
                }

                case IFCONFIG_POOL_INDIV:
                {
                    in_addr_t b = pool->ipv4.base + i;
                    *local = 0;
                    *remote = b;
                    break;
                }

                default:
                    ASSERT(0);
            }
        }

        /* IPv6 pools are always INDIV (--linear) */
        if (pool->ipv6.enabled && remote_ipv6)
        {
            *remote_ipv6 = add_in6_addr(pool->ipv6.base, i);
        }
    }
    return i;
}

bool
ifconfig_pool_release(struct ifconfig_pool *pool, ifconfig_pool_handle hand, const bool hard)
{
    bool ret = false;

    if (pool && hand >= 0 && hand < pool->size)
    {
        ifconfig_pool_entry_free(&pool->list[hand], hard);
        ret = true;
    }
    return ret;
}

/*
 * private access functions
 */

/* currently handling IPv4 logic only */
static ifconfig_pool_handle
ifconfig_pool_ip_base_to_handle(const struct ifconfig_pool *pool, const in_addr_t addr)
{
    ifconfig_pool_handle ret = -1;

    switch (pool->ipv4.type)
    {
        case IFCONFIG_POOL_30NET:
        {
            ret = (addr - pool->ipv4.base) >> 2;
            break;
        }

        case IFCONFIG_POOL_INDIV:
        {
            ret = (addr - pool->ipv4.base);
            break;
        }

        default:
            ASSERT(0);
    }

    if (ret < 0 || ret >= pool->size)
    {
        ret = -1;
    }

    return ret;
}

static ifconfig_pool_handle
ifconfig_pool_ipv6_base_to_handle(const struct ifconfig_pool *pool,
                                  const struct in6_addr *in_addr)
{
    ifconfig_pool_handle ret;
    uint32_t base, addr;

    /* IPv6 pool is always IFCONFIG_POOL_INDIV.
     *
     * We assume the offset can't be larger than 2^32-1, therefore we compute
     * the difference only among the last 4 bytes like if they were two 32bit
     * long integers. The rest of the address must match.
     */
    for (int i = 0; i < (12); i++)
    {
        if (pool->ipv6.base.s6_addr[i] != in_addr->s6_addr[i])
        {
            return -1;
        }
    }

    base = (pool->ipv6.base.s6_addr[12] << 24)
           | (pool->ipv6.base.s6_addr[13] << 16)
           | (pool->ipv6.base.s6_addr[14] << 8)
           | pool->ipv6.base.s6_addr[15];

    addr = (in_addr->s6_addr[12] << 24)
           | (in_addr->s6_addr[13] << 16)
           | (in_addr->s6_addr[14] << 8)
           | in_addr->s6_addr[15];

    ret = addr - base;
    if (ret < 0 || ret >= pool->size)
    {
        ret = -1;
    }

    return ret;
}

static in_addr_t
ifconfig_pool_handle_to_ip_base(const struct ifconfig_pool *pool, ifconfig_pool_handle hand)
{
    in_addr_t ret = 0;

    if (pool->ipv4.enabled && hand >= 0 && hand < pool->size)
    {
        switch (pool->ipv4.type)
        {
            case IFCONFIG_POOL_30NET:
            {
                ret = pool->ipv4.base + (hand << 2);
                break;
            }

            case IFCONFIG_POOL_INDIV:
            {
                ret = pool->ipv4.base + hand;
                break;
            }

            default:
                ASSERT(0);
        }
    }

    return ret;
}

static struct in6_addr
ifconfig_pool_handle_to_ipv6_base(const struct ifconfig_pool *pool, ifconfig_pool_handle hand)
{
    struct in6_addr ret = IN6ADDR_ANY_INIT;

    /* IPv6 pools are always INDIV (--linear) */
    if (pool->ipv6.enabled && hand >= 0 && hand < pool->size)
    {
        ret = add_in6_addr( pool->ipv6.base, hand );
    }
    return ret;
}

static void
ifconfig_pool_set(struct ifconfig_pool *pool, const char *cn,
                  ifconfig_pool_handle h, const bool fixed)
{
    struct ifconfig_pool_entry *e = &pool->list[h];
    ifconfig_pool_entry_free(e, true);
    e->in_use = false;
    e->common_name = string_alloc(cn, NULL);
    e->last_release = now;
    e->fixed = fixed;
}

static void
ifconfig_pool_list(const struct ifconfig_pool *pool, struct status_output *out)
{
    if (pool && out)
    {
        struct gc_arena gc = gc_new();
        int i;

        for (i = 0; i < pool->size; ++i)
        {
            const struct ifconfig_pool_entry *e = &pool->list[i];
            struct in6_addr ip6;
            in_addr_t ip;
            const char *ip6_str = "";
            const char *ip_str = "";

            if (e->common_name)
            {
                if (pool->ipv4.enabled)
                {
                    ip = ifconfig_pool_handle_to_ip_base(pool, i);
                    ip_str = print_in_addr_t(ip, 0, &gc);
                }

                if (pool->ipv6.enabled)
                {
                    ip6 = ifconfig_pool_handle_to_ipv6_base(pool, i);
                    ip6_str = print_in6_addr(ip6, 0, &gc);
                }

                status_printf(out, "%s,%s,%s", e->common_name, ip_str, ip6_str);
            }
        }
        gc_free(&gc);
    }
}

static void
ifconfig_pool_msg(const struct ifconfig_pool *pool, int msglevel)
{
    struct status_output *so = status_open(NULL, 0, msglevel, NULL, 0);
    ASSERT(so);
    status_printf(so, "IFCONFIG POOL LIST");
    ifconfig_pool_list(pool, so);
    status_close(so);
}

/*
 * Deal with reading/writing the ifconfig pool database to a file
 */

struct ifconfig_pool_persist *
ifconfig_pool_persist_init(const char *filename, int refresh_freq)
{
    struct ifconfig_pool_persist *ret;

    ASSERT(filename);

    ALLOC_OBJ_CLEAR(ret, struct ifconfig_pool_persist);
    if (refresh_freq > 0)
    {
        ret->fixed = false;
        ret->file = status_open(filename, refresh_freq, -1, NULL, STATUS_OUTPUT_READ|STATUS_OUTPUT_WRITE);
    }
    else
    {
        ret->fixed = true;
        ret->file = status_open(filename, 0, -1, NULL, STATUS_OUTPUT_READ);
    }
    return ret;
}

void
ifconfig_pool_persist_close(struct ifconfig_pool_persist *persist)
{
    if (persist)
    {
        if (persist->file)
        {
            status_close(persist->file);
        }
        free(persist);
    }
}

bool
ifconfig_pool_write_trigger(struct ifconfig_pool_persist *persist)
{
    if (persist->file)
    {
        return status_trigger(persist->file);
    }
    else
    {
        return false;
    }
}

void
ifconfig_pool_read(struct ifconfig_pool_persist *persist, struct ifconfig_pool *pool)
{
    const int buf_size = 128;

    update_time();

    if (persist && persist->file && pool)
    {
        struct gc_arena gc = gc_new();
        struct buffer in = alloc_buf_gc(256, &gc);
        char *cn_buf, *ip_buf, *ip6_buf;
        int line = 0;

        ALLOC_ARRAY_CLEAR_GC(cn_buf, char, buf_size, &gc);
        ALLOC_ARRAY_CLEAR_GC(ip_buf, char, buf_size, &gc);
        ALLOC_ARRAY_CLEAR_GC(ip6_buf, char, buf_size, &gc);

        while (true)
        {
            ASSERT(buf_init(&in, 0));
            if (!status_read(persist->file, &in))
            {
                break;
            }
            ++line;
            if (!BLEN(&in))
            {
                continue;
            }

            int c = *BSTR(&in);
            if (c == '#' || c == ';')
            {
                continue;
            }

            msg(M_INFO, "ifconfig_pool_read(), in='%s'", BSTR(&in));

            /* The expected format of a line is: "CN,IP4,IP6".
             *
             * IP4 or IP6 may be empty when respectively no v4 or v6 pool
             * was previously specified.
             *
             * This means that accepted strings can be:
             * - CN,IP4,IP6
             * - CN,IP4
             * - CN,,IP6
             */
            if (!buf_parse(&in, ',', cn_buf, buf_size)
                || !buf_parse(&in, ',', ip_buf, buf_size))
            {
                continue;
            }

            ifconfig_pool_handle h = -1, h6 = -1;

            if (strlen(ip_buf) > 0)
            {
                bool v4_ok = true;
                in_addr_t addr = getaddr(GETADDR_HOST_ORDER, ip_buf, 0, &v4_ok,
                                         NULL);

                if (!v4_ok)
                {
                    msg(M_WARN, "pool: invalid IPv4 (%s) for CN=%s", ip_buf,
                        cn_buf);
                }
                else
                {
                    h = ifconfig_pool_ip_base_to_handle(pool, addr);
                    if (h < 0)
                    {
                        msg(M_WARN,
                            "pool: IPv4 (%s) out of pool range for CN=%s",
                            ip_buf, cn_buf);
                    }
                }
            }

            if (buf_parse(&in, ',', ip6_buf, buf_size) && strlen(ip6_buf) > 0)
            {
                struct in6_addr addr6;

                if (!get_ipv6_addr(ip6_buf, &addr6, NULL, M_WARN))
                {
                    msg(M_WARN, "pool: invalid IPv6 (%s) for CN=%s", ip6_buf,
                        cn_buf);
                }
                else
                {
                    h6 = ifconfig_pool_ipv6_base_to_handle(pool, &addr6);
                    if (h6 < 0)
                    {
                        msg(M_WARN,
                            "pool: IPv6 (%s) out of pool range for CN=%s",
                            ip6_buf, cn_buf);
                    }

                    /* Rely on IPv6 if no IPv4 was provided or the one provided
                     * was not valid
                     */
                    if (h < 0)
                    {
                        h = h6;
                    }
                }
            }

            /* at the moment IPv4 and IPv6 share the same pool, therefore offsets
             * have to match for the same client.
             *
             * If offsets differ we use the IPv4, therefore warn the user about this.
             */
            if ((h6 >= 0) && (h != h6))
            {
                msg(M_WARN,
                    "pool: IPv4 (%s) and IPv6 (%s) have different offsets! Relying on IPv4",
                    ip_buf, ip6_buf);
            }

            /* if at least one among v4 and v6 was properly parsed, attempt
             * setting an handle for this client
             */
            if (h >= 0)
            {
                msg(M_INFO, "succeeded -> ifconfig_pool_set(hand=%d)",h);
                ifconfig_pool_set(pool, cn_buf, h, persist->fixed);
            }
        }

        ifconfig_pool_msg(pool, D_IFCONFIG_POOL);

        gc_free(&gc);
    }
}

void
ifconfig_pool_write(struct ifconfig_pool_persist *persist, const struct ifconfig_pool *pool)
{
    if (persist && persist->file && (status_rw_flags(persist->file) & STATUS_OUTPUT_WRITE) && pool)
    {
        status_reset(persist->file);
        ifconfig_pool_list(pool, persist->file);
        status_flush(persist->file);
    }
}

/*
 * TESTING ONLY
 */

#ifdef IFCONFIG_POOL_TEST

#define DUP_CN

void
ifconfig_pool_test(in_addr_t start, in_addr_t end)
{
    struct gc_arena gc = gc_new();
    struct ifconfig_pool *p = ifconfig_pool_init(IFCONFIG_POOL_30NET, start, end);
    /*struct ifconfig_pool *p = ifconfig_pool_init (IFCONFIG_POOL_INDIV, start, end);*/
    ifconfig_pool_handle array[256];
    int i;

    CLEAR(array);

    msg(M_INFO | M_NOPREFIX, "************ 1");
    for (i = 0; i < (int) SIZE(array); ++i)
    {
        char *cn;
        ifconfig_pool_handle h;
        in_addr_t local, remote;
        char buf[256];
        openvpn_snprintf(buf, sizeof(buf), "common-name-%d", i);
#ifdef DUP_CN
        cn = NULL;
#else
        cn = buf;
#endif
        h = ifconfig_pool_acquire(p, &local, &remote, NULL, cn);
        if (h < 0)
        {
            break;
        }
        msg(M_INFO | M_NOPREFIX, "IFCONFIG_POOL TEST pass 1: l=%s r=%s cn=%s",
            print_in_addr_t(local, 0, &gc),
            print_in_addr_t(remote, 0, &gc),
            cn);
        array[i] = h;

    }

    msg(M_INFO | M_NOPREFIX, "************* 2");
    for (i = (int) SIZE(array) / 16; i < (int) SIZE(array) / 8; ++i)
    {
        msg(M_INFO, "Attempt to release %d cn=%s", array[i], p->list[i].common_name);
        if (!ifconfig_pool_release(p, array[i]))
        {
            break;
        }
        msg(M_INFO, "Succeeded");
    }

    CLEAR(array);

    msg(M_INFO | M_NOPREFIX, "**************** 3");
    for (i = 0; i < (int) SIZE(array); ++i)
    {
        char *cn;
        ifconfig_pool_handle h;
        in_addr_t local, remote;
        char buf[256];
        snprintf(buf, sizeof(buf), "common-name-%d", i+24);
#ifdef DUP_CN
        cn = NULL;
#else
        cn = buf;
#endif
        h = ifconfig_pool_acquire(p, &local, &remote, NULL, cn);
        if (h < 0)
        {
            break;
        }
        msg(M_INFO | M_NOPREFIX, "IFCONFIG_POOL TEST pass 3: l=%s r=%s cn=%s",
            print_in_addr_t(local, 0, &gc),
            print_in_addr_t(remote, 0, &gc),
            cn);
        array[i] = h;

    }

    ifconfig_pool_free(p);
    gc_free(&gc);
}

#endif /* ifdef IFCONFIG_POOL_TEST */

#endif /* if P2MP */
