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; }
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; }
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; }
/* 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; }
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); }
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; }
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; }
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); }
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; }