Defer handling netname conflicts when accepting an invitation.
authorGuus Sliepen <guus@tinc-vpn.org>
Fri, 26 Jul 2013 13:48:52 +0000 (15:48 +0200)
committerGuus Sliepen <guus@tinc-vpn.org>
Fri, 26 Jul 2013 13:48:52 +0000 (15:48 +0200)
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
src/tincctl.c

index 95478a7..e5085ce 100644 (file)
@@ -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;
 }
 
index 1c96524..2fe4e79 100644 (file)
@@ -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);