int main(int argc, char *argv[])
{
    /* Initialize networking -
       Bind to ip 0.0.0.0:PORT */
    IP ip;
    ip.uint32 = 0;
    DHT *dht = new_DHT(new_net_crypto(new_networking(ip, PORT)));
    manage_keys(dht);
    printf("Public key: ");
    uint32_t i;

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

    for (i = 0; i < 32; i++) {
        if (dht->c->self_public_key[i] < 16)
            printf("0");

        printf("%hhX", dht->c->self_public_key[i]);
        fprintf(file, "%hhX", dht->c->self_public_key[i]);
    }

    fclose(file);

    printf("\n");
    printf("Port: %u\n", PORT);

    perror("Initialization.");

    if (argc > 3) {
        printf("Trying to bootstrap into the network...\n");
        IP_Port bootstrap_info;
        bootstrap_info.ip.uint32 = inet_addr(argv[1]);
        bootstrap_info.port = htons(atoi(argv[2]));
        uint8_t *bootstrap_key = hex_string_to_bin(argv[3]);
        DHT_bootstrap(dht, bootstrap_info, bootstrap_key);
        free(bootstrap_key);
    }

    int is_waiting_for_dht_connection = 1;

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

        do_DHT(dht);

        networking_poll(dht->c->lossless_udp->net);

        c_sleep(1);
    }

    return 0;
}
Esempio n. 2
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;
}
Esempio n. 3
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;
}
Esempio n. 4
0
/* run this at startup */
Messenger *initMessenger(void)
{
    Messenger *m = calloc(1, sizeof(Messenger));

    if ( ! m )
        return NULL;

    IP ip;
    ip.i = 0;
    m->net = new_networking(ip, PORT);

    if (m->net == NULL) {
        free(m);
        return NULL;
    }

    m->net_crypto = new_net_crypto(m->net);

    if (m->net_crypto == NULL) {
        kill_networking(m->net);
        free(m);
        return NULL;
    }

    m->dht = new_DHT(m->net_crypto);

    if (m->dht == NULL) {
        kill_net_crypto(m->net_crypto);
        kill_networking(m->net);
        free(m);
        return NULL;
    }

    new_keys(m->net_crypto);
    m_set_statusmessage(m, (uint8_t *)"Online", sizeof("Online"));

    friendreq_init(&(m->fr), m->net_crypto);
    LANdiscovery_init(m->dht);
    set_nospam(&(m->fr), random_int());
    init_cryptopackets(m->dht);

    return m;
}
Esempio n. 5
0
void test_addto_lists(IP ip)
{
    Networking_Core *net = new_networking(ip, TOX_PORT_DEFAULT);
    ck_assert_msg(net != 0, "Failed to create Networking_Core");

    DHT *dht = new_DHT(net);
    ck_assert_msg(dht != 0, "Failed to create DHT");

    IP_Port ip_port = { .ip = ip, .port = TOX_PORT_DEFAULT };
    uint8_t client_id[CLIENT_ID_SIZE];
    int i, used;

    // check lists filling
    for (i = 0; i < MAX(LCLIENT_LIST, MAX_FRIEND_CLIENTS); ++i) {
        randombytes(client_id, sizeof(client_id));
        used = addto_lists(dht, ip_port, client_id);
        ck_assert_msg(used == dht->num_friends + 1, "Wrong number of added clients with existing ip_port");
    }

    for (i = 0; i < MAX(LCLIENT_LIST, MAX_FRIEND_CLIENTS); ++i) {
        ip_port.port += 1;
        used = addto_lists(dht, ip_port, client_id);
        ck_assert_msg(used == dht->num_friends + 1, "Wrong number of added clients with existing client_id");
    }

    for (i = 0; i < MAX(LCLIENT_LIST, MAX_FRIEND_CLIENTS); ++i) {
        ip_port.port += 1;
        randombytes(client_id, sizeof(client_id));
        used = addto_lists(dht, ip_port, client_id);
        ck_assert_msg(used >= 1, "Wrong number of added clients");
    }

    /*check: Current behavior if there are two clients with the same id is
     * to replace the first ip by the second. */
    test_addto_lists_update(dht, dht->close_clientlist, LCLIENT_LIST, &ip_port);

    for (i = 0; i < dht->num_friends; ++i)
        test_addto_lists_update(dht, dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS, &ip_port);

    // check "bad" entries
    test_addto_lists_bad(dht, dht->close_clientlist, LCLIENT_LIST, &ip_port);

    for (i = 0; i < dht->num_friends; ++i)
        test_addto_lists_bad(dht, dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS, &ip_port);

    // check "possibly bad" entries
    /*
    test_addto_lists_possible_bad(dht, dht->close_clientlist, LCLIENT_LIST, &ip_port, dht->self_public_key);

    for (i = 0; i < dht->num_friends; ++i)
        test_addto_lists_possible_bad(dht, dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS, &ip_port,
                                      dht->friends_list[i].client_id);
    */
    // check "good" entries
    test_addto_lists_good(dht, dht->close_clientlist, LCLIENT_LIST, &ip_port, dht->self_public_key);

    for (i = 0; i < dht->num_friends; ++i)
        test_addto_lists_good(dht, dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS, &ip_port,
                              dht->friends_list[i].client_id);

    kill_DHT(dht);
    kill_networking(net);
}
Esempio n. 6
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;
}
Esempio n. 7
0
void test_list_main()
{
    DHT *dhts[NUM_DHT];

    uint8_t cmp_list1[NUM_DHT][MAX_FRIEND_CLIENTS][crypto_box_PUBLICKEYBYTES + 1];
    memset(cmp_list1, 0, sizeof(cmp_list1));

    IP ip;
    ip_init(&ip, 1);

    unsigned int i, j, k, l;

    for (i = 0; i < NUM_DHT; ++i) {
        IP ip;
        ip_init(&ip, 1);

        dhts[i] = new_DHT(new_networking(ip, DHT_DEFAULT_PORT + i));
        ck_assert_msg(dhts[i] != 0, "Failed to create dht instances %u", i);
        ck_assert_msg(dhts[i]->net->port != DHT_DEFAULT_PORT + i, "Bound to wrong port");
    }

    for (j = 0; j < NUM_DHT; ++j) {
        for (i = 1; i < NUM_DHT; ++i) {
            test_add_to_list(cmp_list1[j], MAX_FRIEND_CLIENTS, dhts[(i + j) % NUM_DHT]->self_public_key, dhts[j]->self_public_key);
        }
    }

    for (j = 0; j < NUM_DHT; ++j) {
        for (i = 0; i < NUM_DHT; ++i) {
            if (i == j)
                continue;

            IP_Port ip_port;
            ip_init(&ip_port.ip, 0);
            ip_port.ip.ip4.uint32 = rand();
            ip_port.port = rand() % (UINT16_MAX - 1);
            ++ip_port.port;
            addto_lists(dhts[j], ip_port, dhts[i]->self_public_key);
        }
    }

    /*
        print_pk(dhts[0]->self_public_key);

        for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) {
            printf("----Entry %u----\n", i);

            print_pk(cmp_list1[i]);
        }
    */
    unsigned int m_count = 0;

    for (l = 0; l < NUM_DHT; ++l) {
        for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) {
            for (j = 1; j < NUM_DHT; ++j) {
                if (memcmp(cmp_list1[l][i], dhts[(l + j) % NUM_DHT]->self_public_key, crypto_box_PUBLICKEYBYTES) != 0)
                    continue;

                unsigned int count = 0;

                for (k = 0; k < LCLIENT_LIST; ++k) {
                    if (memcmp(dhts[l]->self_public_key, dhts[(l + j) % NUM_DHT]->close_clientlist[k].public_key,
                               crypto_box_PUBLICKEYBYTES) == 0)
                        ++count;
                }

                if (count != 1) {
                    print_pk(dhts[l]->self_public_key);

                    for (k = 0; k < MAX_FRIEND_CLIENTS; ++k) {
                        printf("----Entry %u----\n", k);

                        print_pk(cmp_list1[l][k]);
                    }

                    for (k = 0; k < LCLIENT_LIST; ++k) {
                        printf("----Closel %u----\n", k);
                        print_pk(dhts[(l + j) % NUM_DHT]->close_clientlist[k].public_key);
                    }

                    print_pk(dhts[(l + j) % NUM_DHT]->self_public_key);
                }

                ck_assert_msg(count == 1, "Nodes in search don't know ip of friend. %u %u %u", i, j, count);

                Node_format ln[MAX_SENT_NODES];
                int n = get_close_nodes(dhts[(l + j) % NUM_DHT], dhts[l]->self_public_key, ln, 0, 1, 0);
                ck_assert_msg(n == MAX_SENT_NODES, "bad num close %u | %u %u", n, i, j);

                count = 0;

                for (k = 0; k < MAX_SENT_NODES; ++k) {
                    if (memcmp(dhts[l]->self_public_key, ln[k].public_key, crypto_box_PUBLICKEYBYTES) == 0)
                        ++count;
                }

                ck_assert_msg(count == 1, "Nodes in search don't know ip of friend. %u %u %u", i, j, count);
                /*
                            for (k = 0; k < MAX_SENT_NODES; ++k) {
                                printf("----gn %u----\n", k);
                                print_pk(ln[k].public_key);
                            }*/
                ++m_count;
            }
        }
    }

    ck_assert_msg(m_count == (NUM_DHT) * (MAX_FRIEND_CLIENTS), "Bad count. %u != %u", m_count,
                  (NUM_DHT) * (MAX_FRIEND_CLIENTS));

    for (i = 0; i < NUM_DHT; ++i) {
        void *n = dhts[i]->net;
        kill_DHT(dhts[i]);
        kill_networking(n);
    }
}
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;
}
Esempio n. 9
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;
}
int main(int argc, char *argv[])
{

    pid_t pid, sid; /* Process- and Session-ID */
    struct server_conf_s server_conf;

    FILE *pidf; /* The PID file */

    if (argc < 2) {
        printf("Please specify a configuration file.\n");
        exit(EXIT_FAILURE);
    }

    server_conf = configure_server(argv[1]);

    /* initialize networking
    bind to ip 0.0.0.0:PORT */
    IP ip;
    ip.i = 0;
    DHT *dht = new_DHT(new_net_crypto(new_networking(ip, server_conf.port)));
    /* Read the config file */
    printf("PID file: %s\n", server_conf.pid_file);
    printf("Key file: %s\n", server_conf.keys_file);

    if (server_conf.err == -1)
        printf("Config file not read.\n");

    if (server_conf.err == -2)
        printf("No valid servers in list.\n");

    /* Open PID file for writing - if an error happens,
    it will be caught down the line */
    pidf = fopen(server_conf.pid_file, "w");

    /* Manage the keys */
    /* for now, just ignore any errors after this call. */
    int tmperr = errno;
    manage_keys(dht, server_conf.keys_file);
    errno = tmperr;

    /* Public key */
    int i;
    printf("\nPublic Key: ");

    for (i = 0; i < 32; ++i) {
        uint8_t ln, hn;
        ln = 0x0F & dht->c->self_public_key[i];
        hn = 0xF0 & dht->c->self_public_key[i];
        hn = hn >> 4;
        printf("%X%X", hn, ln);
    }

    printf("\n");

    /* Bootstrap the DHT
    This one throws odd errors, too. Ignore. I assume they come
    from somewhere in the core. */
    tmperr = errno;
    connect_to_servers(dht, server_conf.info);
    errno = tmperr;

    if (!DHT_isconnected(dht)) {
        puts("Could not establish DHT connection. Check server settings.\n");
        exit(EXIT_FAILURE);
    } else {
        printf("Connected to DHT successfully.\n");
    }

    /* If there's been an error, exit before forking off */
    if (errno != 0) {
        perror("Error");
        printf("Error(s) occured during start-up. Exiting.\n");
        exit(EXIT_FAILURE);
    }

    /* Things that make the daemon work come past here.
    There should be nothing here but the daemon code and
    the main loop. */

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

    if (pid < 0) {
        printf("Forking failed.\n");
        exit(EXIT_FAILURE);
    }

    /* If we got a good PID, then
    we can exit the parent process. */
    if (pid > 0) {
        printf("Forked successfully: %d\n", pid);

        /* Write the PID file */
        fprintf(pidf, "%d\n", pid);
        fclose(pidf);

        /* Exit parent */
        exit(EXIT_SUCCESS);
    }

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

    /* Create a new SID for the child process */
    sid = setsid();

    if (sid < 0) {
        printf("SID creation failure.\n");
        exit(EXIT_FAILURE);
    }

    /* Change the current working directory */
    if ((chdir("/")) < 0) {
        exit(EXIT_FAILURE);
    }

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

    while (1) {
        do_DHT(dht);

        networking_poll(dht->c->lossless_udp->net);
        usleep(10000);
    }

    shutdown_networking();
    exit(EXIT_SUCCESS);
}
Esempio n. 11
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_net_crypto(new_networking(ip, PORT)));
    perror("Initialization");

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

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

    for (i = 0; i < 32; i++) {
        if (dht->c->self_public_key[i] < 16)
            printf("0");

        printf("%hhX", dht->c->self_public_key[i]);
        fprintf(file, "%hhX", dht->c->self_public_key[i]);
    }

    fclose(file);

    printf("\n");
    printf("Port: %u\n", ntohs(dht->c->lossless_udp->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 server successfully.\n");
            is_waiting_for_dht_connection = 0;
        }

        do_DHT(dht);

        if (last_LANdiscovery + (is_waiting_for_dht_connection ? 5 : LAN_DISCOVERY_INTERVAL) < unix_time()) {
            send_LANdiscovery(htons(PORT), dht->c);
            last_LANdiscovery = unix_time();
        }

        networking_poll(dht->c->lossless_udp->net);

        c_sleep(1);
    }

    return 0;
}