From a1f4f14c6c5e269c901e6e019418fb8f789cf96b Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Fri, 26 Jul 2013 15:48:52 +0200 Subject: [PATCH] Defer handling netname conflicts when accepting an invitation. In case no explicit netname of configuration directory is specified when accepting an invitation, the netname specified in the invitation data is used. However, this new netname is only known after making the connection to the server. If the new netname conflicts with an existing one at the client, we ask the user for a netname that doesn't conflict. However, we should first finish accepting the invitation, so we don't run into the problem that the server times out and cancels the invitation. So, we create a random netname and store the files there, and only after we finish accepting the invitation we ask the user for a better netname, and then just rename the temporary directory to the final name. --- src/invitation.c | 42 ++++++++++++++++++++++++++++++++---------- src/tincctl.c | 3 +-- 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/src/invitation.c b/src/invitation.c index 95478a7f..e5085cea 100644 --- a/src/invitation.c +++ b/src/invitation.c @@ -490,6 +490,9 @@ static bool finalize_join(void) { if(!netname) netname = grep(data, "NetName"); + bool ask_netname = false; + char temp_netname[32]; + make_names: if(!confbasegiven) { free(confbase); @@ -508,17 +511,11 @@ make_names: fprintf(stderr, "Configuration file %s already exists!\n", tinc_conf); if(!tty || confbasegiven) return false; -ask_netname: - fprintf(stderr, "Enter a new netname: "); - if(!fgets(line, sizeof line, stdin)) { - fprintf(stderr, "Error while reading stdin: %s\n", strerror(errno)); - return false; - } - if(!*line || *line == '\n') - goto ask_netname; - line[strlen(line) - 1] = 0; - netname = line; + // Generate a random netname, ask for a better one later. + ask_netname = true; + snprintf(temp_netname, sizeof temp_netname, "join_%x", rand()); + netname = temp_netname; goto make_names; } @@ -701,6 +698,31 @@ ask_netname: shutdown(sock, SHUT_RDWR); success = true; +ask_netname: + if(ask_netname) { + fprintf(stderr, "Enter a new netname: "); + if(!fgets(line, sizeof line, stdin)) { + fprintf(stderr, "Error while reading stdin: %s\n", strerror(errno)); + return false; + } + if(!*line || *line == '\n') + goto ask_netname; + + line[strlen(line) - 1] = 0; + + char *newbase; + xasprintf(&newbase, CONFDIR SLASH "tinc" SLASH "%s", line); + if(rename(confbase, newbase)) { + fprintf(stderr, "Error trying to rename %s to %s: %s\n", confbase, newbase, strerror(errno)); + free(newbase); + goto ask_netname; + } + + free(newbase); + netname = line; + make_names(); + } + return true; } diff --git a/src/tincctl.c b/src/tincctl.c index 1c96524d..2fe4e790 100644 --- a/src/tincctl.c +++ b/src/tincctl.c @@ -1692,8 +1692,6 @@ int check_port(char *name) { fprintf(stderr, "Warning: could not bind to port 655. "); - srand(time(NULL)); - for(int i = 0; i < 100; i++) { int port = 0x1000 + (rand() & 0x7fff); if(try_bind(port)) { @@ -2376,6 +2374,7 @@ int main(int argc, char *argv[]) { return 0; } + srand(time(NULL)); crypto_init(); tty = isatty(0) && isatty(1);