'ControlMaster auto'

David Woodhouse dwmw2 at infradead.org
Sun Jun 12 23:18:11 EST 2005


On Sun, 2005-06-12 at 09:59 +0100, David Woodhouse wrote:
> This allows me to set 'ControlPath ~/.ssh/sockets/%h.%p.%u' for example.

... and this one complements it by adding 'ControlMaster auto'. I should
probably use #defines for the ControlMaster settings now that they're
more complicated than just 0, 1 or 2, -- but I'll do that in the next
patch, which will add 'persist' and 'autopersist' to the available
options.

--- openssh-4.1p1/readconf.c	2005-03-14 12:08:12.000000000 +0000
+++ openssh-4.1p1-auto/readconf.c	2005-06-12 11:18:05.000000000 +0100
@@ -793,7 +793,26 @@ parse_int:
 
 	case oControlMaster:
 		intptr = &options->control_master;
-		goto parse_yesnoask;
+		arg = strdelim(&s);
+		if (!arg || *arg == '\0')
+			fatal("%.200s line %d: Missing ControlMaster argument.",
+			    filename, linenum);
+		value = 0;	/* To avoid compiler warning... */
+		if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
+			value = 1;
+		else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
+			value = 0;
+		else if (strcmp(arg, "ask") == 0)
+			value = 2;
+		else if (strcmp(arg, "auto") == 0)
+			value = 3;
+		else if (strcmp(arg, "autoask") == 0)
+			value = 4;
+		else
+			fatal("%.200s line %d: Bad ControlMaster argument.", filename, linenum);
+		if (*activep && *intptr == -1)
+			*intptr = value;
+		break;
 
 	case oHashKnownHosts:
 		intptr = &options->hash_known_hosts;
--- openssh-4.1p1/ssh.c	2005-06-12 13:56:53.000000000 +0100
+++ openssh-4.1p1-auto/ssh.c	2005-06-12 13:55:32.000000000 +0100
@@ -659,8 +659,13 @@ again:
 			options.control_path = xstrdup(buffer_ptr(&path));
 		}
 	}
-	if (options.control_path != NULL && options.control_master == 0)
-		control_client(options.control_path); /* This doesn't return */
+	if (options.control_path != NULL && 
+	    (options.control_master == 0 || options.control_master == 3 ||
+	     options.control_master == 4)) {
+		/* This only returns in the 'ask' cases, if we should
+		   become a master */
+		control_client(options.control_path);
+	}
 
 	/* Open a connection to the remote host. */
 	if (ssh_connect(host, &hostaddr, options.port,
@@ -1337,15 +1342,6 @@ control_client(const char *path)
 	extern char **environ;
 	u_int  flags;
 
-	if (stdin_null_flag) {
-		if ((fd = open(_PATH_DEVNULL, O_RDONLY)) == -1)
-			fatal("open(/dev/null): %s", strerror(errno));
-		if (dup2(fd, STDIN_FILENO) == -1)
-			fatal("dup2: %s", strerror(errno));
-		if (fd > STDERR_FILENO)
-			close(fd);
-	}
-
 	memset(&addr, '\0', sizeof(addr));
 	addr.sun_family = AF_UNIX;
 	addr_len = offsetof(struct sockaddr_un, sun_path) +
@@ -1358,8 +1354,25 @@ control_client(const char *path)
 	if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
 		fatal("%s socket(): %s", __func__, strerror(errno));
 
-	if (connect(sock, (struct sockaddr*)&addr, addr_len) == -1)
+	if (connect(sock, (struct sockaddr*)&addr, addr_len) == -1) {
+		if (options.control_master >= 2) {
+			debug("Couldn't connect to %s: %s", path, strerror(errno));
+			/* Automatic mode; return and become a master */
+			options.control_master -= 2;
+			close(sock);
+			return;
+		}
 		fatal("Couldn't connect to %s: %s", path, strerror(errno));
+	}
+
+	if (stdin_null_flag) {
+		if ((fd = open(_PATH_DEVNULL, O_RDONLY)) == -1)
+			fatal("open(/dev/null): %s", strerror(errno));
+		if (dup2(fd, STDIN_FILENO) == -1)
+			fatal("dup2: %s", strerror(errno));
+		if (fd > STDERR_FILENO)
+			close(fd);
+	}
 
 	if ((term = getenv("TERM")) == NULL)
 		term = "";

-- 
dwmw2




More information about the openssh-unix-dev mailing list