Add timeouts to 'tinc join'
[tinc] / src / invitation.c
index a95a324..46891a3 100644 (file)
@@ -36,6 +36,7 @@
 #include "xalloc.h"
 #include "random.h"
 #include "pidfile.h"
+#include "fs.h"
 
 #include "ed25519/sha512.h"
 
@@ -384,13 +385,12 @@ int cmd_invite(int argc, char *argv[]) {
                }
        }
 
-       snprintf(filename, sizeof(filename), "%s" SLASH "invitations", confbase);
-
-       if(mkdir(filename, 0700) && errno != EEXIST) {
-               fprintf(stderr, "Could not create directory %s: %s\n", filename, strerror(errno));
-               return 1;
+       if(!makedirs(DIR_INVITATIONS)) {
+               return false;
        }
 
+       snprintf(filename, sizeof(filename), "%s" SLASH "invitations", confbase);
+
        // Count the number of valid invitations, clean up old ones
        DIR *dir = opendir(filename);
 
@@ -779,13 +779,7 @@ make_names:
                goto make_names;
        }
 
-       if(mkdir(confbase, 0777) && errno != EEXIST) {
-               fprintf(stderr, "Could not create directory %s: %s\n", confbase, strerror(errno));
-               return false;
-       }
-
-       if(mkdir(hosts_dir, 0777) && errno != EEXIST) {
-               fprintf(stderr, "Could not create directory %s: %s\n", hosts_dir, strerror(errno));
+       if(!makedirs(DIR_HOSTS | DIR_CONFBASE | DIR_CACHE)) {
                return false;
        }
 
@@ -1202,6 +1196,21 @@ static bool invitation_receive(void *handle, uint8_t type, const void *msg, uint
        return true;
 }
 
+bool wait_socket_recv(int fd) {
+       fd_set fds;
+       FD_ZERO(&fds);
+       FD_SET(fd, &fds);
+
+       struct timeval tv = {.tv_sec = 5};
+
+       if(select(fd + 1, &fds, NULL, NULL, &tv) != 1) {
+               fprintf(stderr, "Timed out waiting for the server to reply.\n");
+               return false;
+       }
+
+       return true;
+}
+
 int cmd_join(int argc, char *argv[]) {
        free(data);
        data = NULL;
@@ -1213,14 +1222,8 @@ int cmd_join(int argc, char *argv[]) {
        }
 
        // Make sure confbase exists and is accessible.
-       if(!confbase_given && mkdir(confdir, 0755) && errno != EEXIST) {
-               fprintf(stderr, "Could not create directory %s: %s\n", confdir, strerror(errno));
-               return 1;
-       }
-
-       if(mkdir(confbase, 0777) && errno != EEXIST) {
-               fprintf(stderr, "Could not create directory %s: %s\n", confbase, strerror(errno));
-               return 1;
+       if(!makedirs(DIR_CONFDIR | DIR_CONFBASE)) {
+               return false;
        }
 
        if(access(confbase, R_OK | W_OK | X_OK)) {
@@ -1332,6 +1335,7 @@ next:
                        freeaddrinfo(ai);
                        free(b64_pubkey);
                        ecdsa_free(key);
+                       fprintf(stderr, "Could not connect to inviter. Please make sure the URL you entered is valid.\n");
                        return 1;
                }
        }
@@ -1395,7 +1399,7 @@ next:
        }
 
        if(memcmp(hishash, hash, 18)) {
-               fprintf(stderr, "Peer has an invalid key!\n%s\n", line + 2);
+               fprintf(stderr, "Peer has an invalid key. Please make sure you're using the correct URL.\n%s\n", line + 2);
                ecdsa_free(key);
                return 1;
 
@@ -1421,7 +1425,7 @@ next:
                goto exit;
        }
 
-       while((len = recv(sock, line, sizeof(line), 0))) {
+       while(wait_socket_recv(sock) && (len = recv(sock, line, sizeof(line), 0))) {
                if(len < 0) {
                        if(sockwouldblock(sockerrno)) {
                                continue;
@@ -1464,7 +1468,7 @@ exit:
        closesocket(sock);
 
        if(!success) {
-               fprintf(stderr, "Invitation cancelled.\n");
+               fprintf(stderr, "Invitation cancelled. Please try again and contact the inviter for assistance if this error persists.\n");
                return 1;
        }