diff --git a/src/main.c b/src/main.c index 83a69bb..b28a02e 100644 --- a/src/main.c +++ b/src/main.c @@ -116,12 +116,17 @@ static Tox *init_tox() return m; } -#define MAXLINE 90 /* Approx max number of chars in a sever line (IP + port + key) */ -#define MINLINE 70 +#define MINLINE 50 /* IP: 7 + port: 5 + key: 38 + spaces: 2 = 70. ! (& e.g. tox.im = 6) */ +#define MAXLINE 256 /* Approx max number of chars in a sever line (name + port + key) */ #define MAXSERVERS 50 +#define SERVERLEN (MAXLINE - TOX_CLIENT_ID_SIZE - 7) -/* Connects to a random DHT server listed in the DHTservers file */ -int init_connection(Tox *m) +static int linecnt = 0; +static char servers[MAXSERVERS][SERVERLEN]; +static uint16_t ports[MAXSERVERS]; +static uint8_t keys[MAXSERVERS][TOX_CLIENT_ID_SIZE]; + +int serverlist_load() { FILE *fp = NULL; @@ -130,13 +135,26 @@ int init_connection(Tox *m) if (fp == NULL) return 1; - char servers[MAXSERVERS][MAXLINE]; char line[MAXLINE]; - int linecnt = 0; - while (fgets(line, sizeof(line), fp) && linecnt < MAXSERVERS) { - if (strlen(line) > MINLINE) - strcpy(servers[linecnt++], line); + if (strlen(line) > MINLINE) { + char *name = strtok(line, " "); + char *port = strtok(NULL, " "); + char *key_ascii = strtok(NULL, " "); + /* invalid line */ + if (name == NULL || port == NULL || key_ascii == NULL) + continue; + + strncpy(servers[linecnt], name, SERVERLEN); + servers[linecnt][SERVERLEN - 1] = 0; + ports[linecnt] = htons(atoi(port)); + + uint8_t *key_binary = hex_string_to_bin(key_ascii); + memcpy(keys[linecnt], key_binary, TOX_CLIENT_ID_SIZE); + free(key_binary); + + linecnt++; + } } if (linecnt < 1) { @@ -145,22 +163,56 @@ int init_connection(Tox *m) } fclose(fp); - - char *server = servers[rand() % linecnt]; - char *ip = strtok(server, " "); - char *port = strtok(NULL, " "); - char *key = strtok(NULL, " "); - - if (ip == NULL || port == NULL || key == NULL) - return 3; - - uint8_t *binary_string = hex_string_to_bin(key); - tox_bootstrap_from_address(m, ip, TOX_ENABLE_IPV6_DEFAULT, - htons(atoi(port)), binary_string); - free(binary_string); return 0; } +int init_connection_helper(Tox *m, int linenumber) +{ + return tox_bootstrap_from_address(m, servers[linenumber], TOX_ENABLE_IPV6_DEFAULT, + ports[linenumber], keys[linenumber]); +} + +/* Connects to a random DHT server listed in the DHTservers file + * + * return codes: + * 1: failed to open server file + * 2: no line of sufficient length in server file + * 3: (old, removed) failed to split a selected line in the server file + * 4: failed to resolve name to IP + * 5: serverlist file contains no acceptable line + */ +static uint8_t init_connection_serverlist_loaded = 0; +int init_connection(Tox *m) +{ + if (linecnt > 0) /* already loaded serverlist */ + return init_connection_helper(m, rand() % linecnt) ? 0 : 4; + + /* only once: + * - load the serverlist + * - connect to "everyone" inside + */ + if (!init_connection_serverlist_loaded) { + init_connection_serverlist_loaded = 1; + int res = serverlist_load(); + if (res) + return res; + + if (!linecnt) + return 4; + + res = 6; + int linenumber; + for(linenumber = 0; linenumber < linecnt; linenumber++) + if (init_connection_helper(m, linenumber)) + res = 0; + + return res; + } + + /* empty serverlist file */ + return 5; +} + static void do_tox(Tox *m, ToxWindow *prompt) { static int conn_try = 0;