Ejemplo n.º 1
0
Onions *new_onions(uint16_t port)
{
    IP ip;
    ip_init(&ip, 1);
    ip.ip6.uint8[15] = 1;
    Onions *on = malloc(sizeof(Onions));
    DHT *dht = new_DHT(new_net_crypto(new_networking(ip, port)));
    on->onion = new_onion(dht);
    on->onion_a = new_onion_announce(dht);

    if (on->onion && on->onion_a)
        return on;

    return NULL;
}
Ejemplo n.º 2
0
static Onions *new_onions(uint16_t port)
{
    IP ip;
    ip_init(&ip, 1);
    ip.ip6.uint8[15] = 1;
    Onions *on = (Onions *)malloc(sizeof(Onions));
    DHT *dht = new_DHT(NULL, new_networking(NULL, ip, port));
    on->onion = new_onion(dht);
    on->onion_a = new_onion_announce(dht);
    TCP_Proxy_Info inf = {{{0}}};
    on->onion_c = new_onion_client(new_net_crypto(NULL, dht, &inf));

    if (on->onion && on->onion_a && on->onion_c) {
        return on;
    }

    return NULL;
}
Ejemplo n.º 3
0
int main(int argc, char *argv[])
{
    if (argc == 2 && !strncasecmp(argv[1], "-h", 3)) {
        printf("Usage (connected)  : %s [--ipv4|--ipv6] IP PORT KEY\n", argv[0]);
        printf("Usage (unconnected): %s [--ipv4|--ipv6]\n", argv[0]);
        exit(0);
    }

    /* let user override default by cmdline */
    uint8_t ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; /* x */
    int argvoffset = cmdline_parsefor_ipv46(argc, argv, &ipv6enabled);

    if (argvoffset < 0)
        exit(1);

    /* Initialize networking -
       Bind to ip 0.0.0.0 / [::] : PORT */
    IP ip;
    ip_init(&ip, ipv6enabled);

    DHT *dht = new_DHT(new_networking(ip, PORT));
    Onion *onion = new_onion(dht);
    Onion_Announce *onion_a = new_onion_announce(dht);

#ifdef DHT_NODE_EXTRA_PACKETS
    bootstrap_set_callbacks(dht->net, DHT_VERSION_NUMBER, DHT_MOTD, sizeof(DHT_MOTD));
#endif

    if (!(onion && onion_a)) {
        printf("Something failed to initialize.\n");
        exit(1);
    }

    perror("Initialization");

    manage_keys(dht);
    printf("Public key: ");
    uint32_t i;

#ifdef TCP_RELAY_ENABLED
#define NUM_PORTS 3
    uint16_t ports[NUM_PORTS] = {443, 3389, PORT};
    TCP_Server *tcp_s = new_TCP_server(ipv6enabled, NUM_PORTS, ports, dht->self_public_key, dht->self_secret_key, onion);

    if (tcp_s == NULL) {
        printf("TCP server failed to initialize.\n");
        exit(1);
    }

#endif

    FILE *file;
    file = fopen("PUBLIC_ID.txt", "w");

    for (i = 0; i < 32; i++) {
        printf("%02hhX", dht->self_public_key[i]);
        fprintf(file, "%02hhX", dht->self_public_key[i]);
    }

    fclose(file);

    printf("\n");
    printf("Port: %u\n", ntohs(dht->net->port));

    if (argc > argvoffset + 3) {
        printf("Trying to bootstrap into the network...\n");
        uint16_t port = htons(atoi(argv[argvoffset + 2]));
        uint8_t *bootstrap_key = hex_string_to_bin(argv[argvoffset + 3]);
        int res = DHT_bootstrap_from_address(dht, argv[argvoffset + 1],
                                             ipv6enabled, port, bootstrap_key);
        free(bootstrap_key);

        if (!res) {
            printf("Failed to convert \"%s\" into an IP address. Exiting...\n", argv[argvoffset + 1]);
            exit(1);
        }
    }

    int is_waiting_for_dht_connection = 1;

    uint64_t last_LANdiscovery = 0;
    LANdiscovery_init(dht);

    while (1) {
        if (is_waiting_for_dht_connection && DHT_isconnected(dht)) {
            printf("Connected to other bootstrap node successfully.\n");
            is_waiting_for_dht_connection = 0;
        }

        do_DHT(dht);

        if (is_timeout(last_LANdiscovery, is_waiting_for_dht_connection ? 5 : LAN_DISCOVERY_INTERVAL)) {
            send_LANdiscovery(htons(PORT), dht);
            last_LANdiscovery = unix_time();
        }

#ifdef TCP_RELAY_ENABLED
        do_TCP_server(tcp_s);
#endif
        networking_poll(dht->net);

        c_sleep(1);
    }

    return 0;
}
int main(int argc, char *argv[])
{
    openlog(DAEMON_NAME, LOG_NOWAIT | LOG_PID, LOG_DAEMON);

    if (argc < 2) {
        syslog(LOG_ERR, "Please specify a path to a configuration file as the first argument. Exiting.\n");
        return 1;
    }

    char *cfg_file_path = argv[1];
    char *pid_file_path, *keys_file_path;
    int port;
    int enable_ipv6;
    int enable_lan_discovery;

    if (get_general_config(cfg_file_path, &pid_file_path, &keys_file_path, &port, &enable_ipv6, &enable_lan_discovery)) {
        syslog(LOG_DEBUG, "General config read successfully\n");
    } else {
        syslog(LOG_ERR, "Couldn't read config file: %s. Exiting.\n", cfg_file_path);
        return 1;
    }

    // not (1 <= port <= 65535)
    if (port < 1 || port > 65535) {
        syslog(LOG_ERR, "Invalid port: %d, must be 1 <= port <= 65535. Exiting.\n", port);
        return 1;
    }

    // Check if the PID file exists
    if (fopen(pid_file_path, "r")) {
        syslog(LOG_ERR, "Another instance of the daemon is already running, PID file %s exists. Exiting.\n", pid_file_path);
        return 1;
    }

    IP ip;
    ip_init(&ip, enable_ipv6);

    DHT *dht = new_DHT(new_net_crypto(new_networking(ip, port)));

    if (dht == NULL) {
        syslog(LOG_ERR, "Couldn't initialize Tox DHT instance. Exiting.\n");
        return 1;
    }

    Onion *onion = new_onion(dht);
    Onion_Announce *onion_a = new_onion_announce(dht);

    if (!(onion && onion_a)) {
        syslog(LOG_ERR, "Couldn't initialize Tox Onion. Exiting.\n");
        return 1;
    }

    if (enable_lan_discovery) {
        LANdiscovery_init(dht);
    }

    if (manage_keys(dht, keys_file_path)) {
        syslog(LOG_DEBUG, "Keys are managed successfully\n");
    } else {
        syslog(LOG_ERR, "Couldn't read/write: %s. Exiting.\n", keys_file_path);
        return 1;
    }

    if (bootstrap_from_config(cfg_file_path, dht, enable_ipv6)) {
        syslog(LOG_DEBUG, "List of bootstrap servers read successfully\n");
    } else {
        syslog(LOG_ERR, "Couldn't read list of bootstrap servers in %s. Exiting.\n", cfg_file_path);
        return 1;
    }

    print_public_key(dht->c->self_public_key);

    // Write the PID file
    FILE *pidf = fopen(pid_file_path, "w");

    if (pidf == NULL) {
        syslog(LOG_ERR, "Can't open the PID file for writing: %s. Exiting.\n", pid_file_path);
        return 1;
    }

    free(pid_file_path);
    free(keys_file_path);

    // Fork off from the parent process
    pid_t pid = fork();

    if (pid < 0) {
        syslog(LOG_ERR, "Forking failed. Exiting.\n");
        return 1;
    }

    if (pid > 0) {
        syslog(LOG_DEBUG, "Forked successfully: PID: %d.\n", pid);
        return 0;
    }

    // Change the file mode mask
    umask(0);

    fprintf(pidf, "%d\n", pid);
    fclose(pidf);

    // Create a new SID for the child process
    if (setsid() < 0) {
        syslog(LOG_ERR, "SID creation failure. Exiting.\n");
        return 1;
    }

    // Change the current working directory
    if ((chdir("/")) < 0) {
        syslog(LOG_ERR, "Couldn't change working directory to '/'. Exiting.\n");
        return 1;
    }

    // Go quiet
    close(STDOUT_FILENO);
    close(STDIN_FILENO);
    close(STDERR_FILENO);

    uint64_t last_LANdiscovery = 0;
    uint16_t htons_port = htons(port);

    int waiting_for_dht_connection = 1;

    while (1) {
        do_DHT(dht);

        if (enable_lan_discovery && is_timeout(last_LANdiscovery, LAN_DISCOVERY_INTERVAL)) {
            send_LANdiscovery(htons_port, dht);
            last_LANdiscovery = unix_time();
        }

        networking_poll(dht->net);

        if (waiting_for_dht_connection && DHT_isconnected(dht)) {
            syslog(LOG_DEBUG, "Connected to other bootstrap server successfully.\n");
            waiting_for_dht_connection = 0;
        }

        sleep;
    }

    return 1;
}
Ejemplo n.º 5
0
int main(int argc, char *argv[])
{
    openlog(DAEMON_NAME, LOG_NOWAIT | LOG_PID, LOG_DAEMON);

    syslog(LOG_INFO, "Running \"%s\" version %lu.\n", DAEMON_NAME, DAEMON_VERSION_NUMBER);

    if (argc < 2) {
        syslog(LOG_ERR, "Please specify a path to a configuration file as the first argument. Exiting.\n");
        return 1;
    }

    const char *cfg_file_path = argv[1];
    char *pid_file_path, *keys_file_path;
    int port;
    int enable_ipv6;
    int enable_ipv4_fallback;
    int enable_lan_discovery;
    int enable_tcp_relay;
    uint16_t *tcp_relay_ports;
    int tcp_relay_port_count;
    int enable_motd;
    char *motd;

    if (get_general_config(cfg_file_path, &pid_file_path, &keys_file_path, &port, &enable_ipv6, &enable_ipv4_fallback,
                           &enable_lan_discovery, &enable_tcp_relay, &tcp_relay_ports, &tcp_relay_port_count, &enable_motd, &motd)) {
        syslog(LOG_DEBUG, "General config read successfully\n");
    } else {
        syslog(LOG_ERR, "Couldn't read config file: %s. Exiting.\n", cfg_file_path);
        return 1;
    }

    if (port < MIN_ALLOWED_PORT || port > MAX_ALLOWED_PORT) {
        syslog(LOG_ERR, "Invalid port: %d, should be in [%d, %d]. Exiting.\n", port, MIN_ALLOWED_PORT, MAX_ALLOWED_PORT);
        return 1;
    }

    // Check if the PID file exists
    FILE *pid_file;

    if ((pid_file = fopen(pid_file_path, "r"))) {
        syslog(LOG_ERR, "Another instance of the daemon is already running, PID file %s exists.\n", pid_file_path);
        fclose(pid_file);
    }

    IP ip;
    ip_init(&ip, enable_ipv6);

    Networking_Core *net = new_networking(ip, port);

    if (net == NULL) {
        if (enable_ipv6 && enable_ipv4_fallback) {
            syslog(LOG_DEBUG, "Couldn't initialize IPv6 networking. Falling back to using IPv4.\n");
            enable_ipv6 = 0;
            ip_init(&ip, enable_ipv6);
            net = new_networking(ip, port);

            if (net == NULL) {
                syslog(LOG_DEBUG, "Couldn't fallback to IPv4. Exiting.\n");
                return 1;
            }
        } else {
            syslog(LOG_DEBUG, "Couldn't initialize networking. Exiting.\n");
            return 1;
        }
    }


    DHT *dht = new_DHT(net);

    if (dht == NULL) {
        syslog(LOG_ERR, "Couldn't initialize Tox DHT instance. Exiting.\n");
        return 1;
    }

    Onion *onion = new_onion(dht);
    Onion_Announce *onion_a = new_onion_announce(dht);

    if (!(onion && onion_a)) {
        syslog(LOG_ERR, "Couldn't initialize Tox Onion. Exiting.\n");
        return 1;
    }

    if (enable_motd) {
        if (bootstrap_set_callbacks(dht->net, DAEMON_VERSION_NUMBER, (uint8_t *)motd, strlen(motd) + 1) == 0) {
            syslog(LOG_DEBUG, "Set MOTD successfully.\n");
        } else {
            syslog(LOG_ERR, "Couldn't set MOTD: %s. Exiting.\n", motd);
            return 1;
        }

        free(motd);
    }

    if (manage_keys(dht, keys_file_path)) {
        syslog(LOG_DEBUG, "Keys are managed successfully.\n");
    } else {
        syslog(LOG_ERR, "Couldn't read/write: %s. Exiting.\n", keys_file_path);
        return 1;
    }

    TCP_Server *tcp_server = NULL;

    if (enable_tcp_relay) {
        if (tcp_relay_port_count == 0) {
            syslog(LOG_ERR, "No TCP relay ports read. Exiting.\n");
            return 1;
        }

        tcp_server = new_TCP_server(enable_ipv6, tcp_relay_port_count, tcp_relay_ports, dht->self_public_key,
                                    dht->self_secret_key, onion);

        // tcp_relay_port_count != 0 at this point
        free(tcp_relay_ports);

        if (tcp_server != NULL) {
            syslog(LOG_DEBUG, "Initialized Tox TCP server successfully.\n");
        } else {
            syslog(LOG_ERR, "Couldn't initialize Tox TCP server. Exiting.\n");
            return 1;
        }
    }

    if (bootstrap_from_config(cfg_file_path, dht, enable_ipv6)) {
        syslog(LOG_DEBUG, "List of bootstrap nodes read successfully.\n");
    } else {
        syslog(LOG_ERR, "Couldn't read list of bootstrap nodes in %s. Exiting.\n", cfg_file_path);
        return 1;
    }

    print_public_key(dht->self_public_key);

    // Write the PID file
    FILE *pidf = fopen(pid_file_path, "a+");

    if (pidf == NULL) {
        syslog(LOG_ERR, "Couldn't open the PID file for writing: %s. Exiting.\n", pid_file_path);
        return 1;
    }

    free(pid_file_path);
    free(keys_file_path);

    // Fork off from the parent process
    const pid_t pid = fork();

    if (pid > 0) {
        fprintf(pidf, "%d", pid);
        fclose(pidf);
        syslog(LOG_DEBUG, "Forked successfully: PID: %d.\n", pid);
        return 0;
    } else {
        fclose(pidf);
    }

    if (pid < 0) {
        syslog(LOG_ERR, "Forking failed. Exiting.\n");
        return 1;
    }

    // Change the file mode mask
    umask(0);

    // Create a new SID for the child process
    if (setsid() < 0) {
        syslog(LOG_ERR, "SID creation failure. Exiting.\n");
        return 1;
    }

    // Change the current working directory
    if ((chdir("/")) < 0) {
        syslog(LOG_ERR, "Couldn't change working directory to '/'. Exiting.\n");
        return 1;
    }

    // Go quiet
    close(STDOUT_FILENO);
    close(STDIN_FILENO);
    close(STDERR_FILENO);

    uint64_t last_LANdiscovery = 0;
    const uint16_t htons_port = htons(port);

    int waiting_for_dht_connection = 1;

    if (enable_lan_discovery) {
        LANdiscovery_init(dht);
        syslog(LOG_DEBUG, "Initialized LAN discovery.\n");
    }

    while (1) {
        do_DHT(dht);

        if (enable_lan_discovery && is_timeout(last_LANdiscovery, LAN_DISCOVERY_INTERVAL)) {
            send_LANdiscovery(htons_port, dht);
            last_LANdiscovery = unix_time();
        }

        if (enable_tcp_relay) {
            do_TCP_server(tcp_server);
        }

        networking_poll(dht->net);

        if (waiting_for_dht_connection && DHT_isconnected(dht)) {
            syslog(LOG_DEBUG, "Connected to other bootstrap node successfully.\n");
            waiting_for_dht_connection = 0;
        }

        sleep;
    }

    return 1;
}
Ejemplo n.º 6
0
int main(int argc, char *argv[])
{
    if (argc == 2 && !tox_strncasecmp(argv[1], "-h", 3)) {
        printf("Usage (connected)  : %s [--ipv4|--ipv6] IP PORT KEY\n", argv[0]);
        printf("Usage (unconnected): %s [--ipv4|--ipv6]\n", argv[0]);
        exit(0);
    }

    /* let user override default by cmdline */
    bool ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; /* x */
    int argvoffset = cmdline_parsefor_ipv46(argc, argv, &ipv6enabled);

    if (argvoffset < 0) {
        exit(1);
    }

    /* Initialize networking -
       Bind to ip 0.0.0.0 / [::] : PORT */
    IP ip;
    ip_init(&ip, ipv6enabled);

    Logger *logger = logger_new();

    if (MIN_LOGGER_LEVEL == LOGGER_LEVEL_TRACE || MIN_LOGGER_LEVEL == LOGGER_LEVEL_DEBUG) {
        logger_callback_log(logger, print_log, nullptr, nullptr);
    }

    Mono_Time *mono_time = mono_time_new();
    DHT *dht = new_dht(logger, mono_time, new_networking(logger, ip, PORT), true);
    Onion *onion = new_onion(mono_time, dht);
    Onion_Announce *onion_a = new_onion_announce(mono_time, dht);

#ifdef DHT_NODE_EXTRA_PACKETS
    bootstrap_set_callbacks(dht_get_net(dht), DHT_VERSION_NUMBER, DHT_MOTD, sizeof(DHT_MOTD));
#endif

    if (!(onion && onion_a)) {
        printf("Something failed to initialize.\n");
        exit(1);
    }

    perror("Initialization");

    manage_keys(dht);
    printf("Public key: ");
    uint32_t i;

#ifdef TCP_RELAY_ENABLED
#define NUM_PORTS 3
    uint16_t ports[NUM_PORTS] = {443, 3389, PORT};
    TCP_Server *tcp_s = new_TCP_server(ipv6enabled, NUM_PORTS, ports, dht_get_self_secret_key(dht), onion);

    if (tcp_s == nullptr) {
        printf("TCP server failed to initialize.\n");
        exit(1);
    }

#endif

    const char *const public_id_filename = "PUBLIC_ID.txt";
    FILE *file = fopen(public_id_filename, "w");

    if (file == nullptr) {
        printf("Could not open file \"%s\" for writing. Exiting...\n", public_id_filename);
        exit(1);
    }

    for (i = 0; i < 32; i++) {
        const uint8_t *const self_public_key = dht_get_self_public_key(dht);
        printf("%02X", self_public_key[i]);
        fprintf(file, "%02X", self_public_key[i]);
    }

    fclose(file);

    printf("\n");
    printf("Port: %u\n", net_ntohs(net_port(dht_get_net(dht))));

    if (argc > argvoffset + 3) {
        printf("Trying to bootstrap into the network...\n");
        uint16_t port = net_htons(atoi(argv[argvoffset + 2]));
        uint8_t *bootstrap_key = hex_string_to_bin(argv[argvoffset + 3]);
        int res = dht_bootstrap_from_address(dht, argv[argvoffset + 1],
                                             ipv6enabled, port, bootstrap_key);
        free(bootstrap_key);

        if (!res) {
            printf("Failed to convert \"%s\" into an IP address. Exiting...\n", argv[argvoffset + 1]);
            exit(1);
        }
    }

    int is_waiting_for_dht_connection = 1;

    uint64_t last_LANdiscovery = 0;
    lan_discovery_init(dht);

    while (1) {
        mono_time_update(mono_time);

        if (is_waiting_for_dht_connection && dht_isconnected(dht)) {
            printf("Connected to other bootstrap node successfully.\n");
            is_waiting_for_dht_connection = 0;
        }

        do_dht(dht);

        if (mono_time_is_timeout(mono_time, last_LANdiscovery, is_waiting_for_dht_connection ? 5 : LAN_DISCOVERY_INTERVAL)) {
            lan_discovery_send(net_htons(PORT), dht);
            last_LANdiscovery = mono_time_get(mono_time);
        }

#ifdef TCP_RELAY_ENABLED
        do_TCP_server(tcp_s, mono_time);
#endif
        networking_poll(dht_get_net(dht), nullptr);

        c_sleep(1);
    }
}