<commit_before>#include "common.h"
#include "ctl.h"
#include "iface.h"
#include "ip.h"
#include "str.h"
#include "tun.h"

#include <fcntl.h>
#include <netinet/in.h>
#include <stdio.h>

#include "../argz/argz.h"
#include "../mud/mud.h"

#ifndef O_CLOEXEC
#define O_CLOEXEC 0
#endif

#define GT_MTU(X) ((X)-28)

static void
fd_set_nonblock(int fd)
{
    int ret;

    if (fd == -1)
        return;

    do {
        ret = fcntl(fd, F_GETFL, 0);
    } while (ret == -1 && errno == EINTR);

    int flags = (ret == -1) ? 0 : ret;

    do {
        ret = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
    } while (ret == -1 && errno == EINTR);

    if (ret == -1)
        perror("fcntl O_NONBLOCK");
}

static int
gt_setup_secretkey(struct mud *mud, const char *keyfile)
{
    int fd;

    do {
        fd = open(keyfile, O_RDONLY | O_CLOEXEC);
    } while (fd == -1 && errno == EINTR);

    if (fd == -1) {
        perror("open keyfile");
        return -1;
    }

    unsigned char key[32];
    char buf[2 * sizeof(key)];
    size_t size = 0;

    while (size < sizeof(buf)) {
        ssize_t r = read(fd, &buf[size], sizeof(buf) - size);

        if (r <= (ssize_t)0) {
            if (r && (errno == EAGAIN || errno == EINTR))
                continue;
            break;
        }

        size += r;
    }

    close(fd);

    if (size != sizeof(buf)) {
        gt_log("unable to read secret key\n");
        return -1;
    }

    if (gt_fromhex(key, sizeof(key), buf, sizeof(buf))) {
        gt_log("secret key is not valid\n");
        return -1;
    }

    mud_set_key(mud, key, sizeof(key));

    return 0;
}

static void
gt_setup_mtu(struct mud *mud, const char *tun_name, size_t *old_mtu)
{
    int mtu = mud_get_mtu(mud);

    if ((size_t)mtu == *old_mtu)
        return;

    gt_log("setup MTU to %i on interface %s\n", mtu, tun_name);

    if (iface_set_mtu(tun_name, mtu) == -1)
        perror("tun_set_mtu");

    *old_mtu = (size_t)mtu;
}

int
gt_bind(int argc, char **argv)
{
    unsigned short bind_port = 5000;
    unsigned short port = bind_port;
    const char *host = NULL;
    const char *dev = NULL;
    const char *keyfile = NULL;
    unsigned long timeout = 5000;
    unsigned long timetolerance = 0;
    size_t bufsize = 64 * 1024 * 1024;
    size_t mtu = 1500;

    struct argz mtuz[] = {
        {"auto", NULL, NULL, argz_option},
        {NULL, "BYTES", &mtu, argz_bytes},
        {}};

    struct argz toz[] = {
        {NULL, "IPADDR", &host, argz_str},
        {NULL, "PORT", &port, argz_ushort},
        {}};

    struct argz bindz[] = {
        {"port", "PORT", &bind_port, argz_ushort},
        {"to", NULL, &toz, argz_option},
        {"dev", "NAME", &dev, argz_str},
        {"v4only|v6only", NULL, NULL, argz_option},
        {"mtu", NULL, &mtuz, argz_option},
        {"keyfile", "FILE", &keyfile, argz_str},
        {"chacha", NULL, NULL, argz_option},
        {"timeout", "SECONDS", &timeout, argz_time},
        {"timetolerance", "SECONDS", &timetolerance, argz_time},
        {"persist", NULL, NULL, argz_option},
        {"bufsize", "BYTES", &bufsize, argz_bytes},
        {}};

    if (argz(bindz, argc, argv))
        return 1;

    unsigned char *buf = malloc(bufsize);

    if (!buf) {
        perror("malloc");
        return 1;
    }

    int ipv4 = 1;
    int ipv6 = !!(__linux__ + 0);

    if (argz_is_set(bindz, "v4only")) {
        ipv4 = 1;
        ipv6 = 0;
    }

    if (argz_is_set(bindz, "v6only")) {
        ipv4 = 0;
        ipv6 = 1;
    }

    int mtu_auto = argz_is_set(mtuz, "auto");
    int chacha = argz_is_set(bindz, "chacha");
    int persist = argz_is_set(bindz, "persist");

    int icmp_fd = -1;
<commit_msg>Fix ipv6 default value<commit_after>#include "common.h"
#include "ctl.h"
#include "iface.h"
#include "ip.h"
#include "str.h"
#include "tun.h"

#include <fcntl.h>
#include <netinet/in.h>
#include <stdio.h>

#include "../argz/argz.h"
#include "../mud/mud.h"

#ifndef O_CLOEXEC
#define O_CLOEXEC 0
#endif

#ifdef __linux__
#define GT_IPV6 1
#else
#define GT_IPV6 0
#endif

#define GT_MTU(X) ((X)-28)

static void
fd_set_nonblock(int fd)
{
    int ret;

    if (fd == -1)
        return;

    do {
        ret = fcntl(fd, F_GETFL, 0);
    } while (ret == -1 && errno == EINTR);

    int flags = (ret == -1) ? 0 : ret;

    do {
        ret = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
    } while (ret == -1 && errno == EINTR);

    if (ret == -1)
        perror("fcntl O_NONBLOCK");
}

static int
gt_setup_secretkey(struct mud *mud, const char *keyfile)
{
    int fd;

    do {
        fd = open(keyfile, O_RDONLY | O_CLOEXEC);
    } while (fd == -1 && errno == EINTR);

    if (fd == -1) {
        perror("open keyfile");
        return -1;
    }

    unsigned char key[32];
    char buf[2 * sizeof(key)];
    size_t size = 0;

    while (size < sizeof(buf)) {
        ssize_t r = read(fd, &buf[size], sizeof(buf) - size);

        if (r <= (ssize_t)0) {
            if (r && (errno == EAGAIN || errno == EINTR))
                continue;
            break;
        }

        size += r;
    }

    close(fd);

    if (size != sizeof(buf)) {
        gt_log("unable to read secret key\n");
        return -1;
    }

    if (gt_fromhex(key, sizeof(key), buf, sizeof(buf))) {
        gt_log("secret key is not valid\n");
        return -1;
    }

    mud_set_key(mud, key, sizeof(key));

    return 0;
}

static void
gt_setup_mtu(struct mud *mud, const char *tun_name, size_t *old_mtu)
{
    int mtu = mud_get_mtu(mud);

    if ((size_t)mtu == *old_mtu)
        return;

    gt_log("setup MTU to %i on interface %s\n", mtu, tun_name);

    if (iface_set_mtu(tun_name, mtu) == -1)
        perror("tun_set_mtu");

    *old_mtu = (size_t)mtu;
}

int
gt_bind(int argc, char **argv)
{
    unsigned short bind_port = 5000;
    unsigned short port = bind_port;
    const char *host = NULL;
    const char *dev = NULL;
    const char *keyfile = NULL;
    unsigned long timeout = 5000;
    unsigned long timetolerance = 0;
    size_t bufsize = 64 * 1024 * 1024;
    size_t mtu = 1500;

    struct argz mtuz[] = {
        {"auto", NULL, NULL, argz_option},
        {NULL, "BYTES", &mtu, argz_bytes},
        {}};

    struct argz toz[] = {
        {NULL, "IPADDR", &host, argz_str},
        {NULL, "PORT", &port, argz_ushort},
        {}};

    struct argz bindz[] = {
        {"port", "PORT", &bind_port, argz_ushort},
        {"to", NULL, &toz, argz_option},
        {"dev", "NAME", &dev, argz_str},
        {"v4only|v6only", NULL, NULL, argz_option},
        {"mtu", NULL, &mtuz, argz_option},
        {"keyfile", "FILE", &keyfile, argz_str},
        {"chacha", NULL, NULL, argz_option},
        {"timeout", "SECONDS", &timeout, argz_time},
        {"timetolerance", "SECONDS", &timetolerance, argz_time},
        {"persist", NULL, NULL, argz_option},
        {"bufsize", "BYTES", &bufsize, argz_bytes},
        {}};

    if (argz(bindz, argc, argv))
        return 1;

    unsigned char *buf = malloc(bufsize);

    if (!buf) {
        perror("malloc");
        return 1;
    }

    int ipv4 = 1;
    int ipv6 = GT_IPV6;

    if (argz_is_set(bindz, "v4only")) {
        ipv4 = 1;
        ipv6 = 0;
    }

    if (argz_is_set(bindz, "v6only")) {
        ipv4 = 0;
        ipv6 = 1;
    }

    int mtu_auto = argz_is_set(mtuz, "auto");
    int chacha = argz_is_set(bindz, "chacha");
    int persist = argz_is_set(bindz, "persist");

    int icmp_fd = -1;

{'fraction_non_alphanumeric': 0.16324878575283325, 'fraction_numerical': 0.01794387479762547, 'mean_word_length': 2.2699602999558888, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4455503', 'n_tokens_mistral': 3047, 'n_tokens_neox': 2858, 'n_words': 718}