[PATCH/RFC 1/6] attach the forwarding type to struct Forward

Bert Wesarg bert.wesarg at googlemail.com
Thu May 3 21:33:47 EST 2012


---
 clientloop.c |   21 +++++++++---------
 mux.c        |   65 ++++++++++++++++++++++++++++-----------------------------
 readconf.c   |   19 ++++++++++------
 readconf.h   |    8 ++++++-
 ssh.c        |    8 +++---
 5 files changed, 66 insertions(+), 55 deletions(-)

diff --git a/clientloop.c b/clientloop.c
index 58357cf..6c62bb7 100644
--- a/clientloop.c
+++ b/clientloop.c
@@ -863,7 +863,8 @@ process_cmdline(void)
 {
 	void (*handler)(int);
 	char *s, *cmd, *cancel_host;
-	int delete = 0, local = 0, remote = 0, dynamic = 0;
+	int delete = 0, i;
+	u_int fwdtype;
 	int cancel_port, ok;
 	Forward fwd;
 
@@ -914,11 +915,11 @@ process_cmdline(void)
 		s++;
 	}
 	if (*s == 'L')
-		local = 1;
+		fwdtype = SSH_FWD_LOCAL;
 	else if (*s == 'R')
-		remote = 1;
+		fwdtype = SSH_FWD_REMOTE;
 	else if (*s == 'D')
-		dynamic = 1;
+		fwdtype = SSH_FWD_DYNAMIC;
 	else {
 		logit("Invalid command.");
 		goto out;
@@ -947,14 +948,14 @@ process_cmdline(void)
 			logit("Bad forwarding close port");
 			goto out;
 		}
-		if (remote)
+		if (fwdtype == SSH_FWD_REMOTE)
 			ok = channel_request_rforward_cancel(cancel_host,
 			    cancel_port) == 0;
-		else if (dynamic)
-                	ok = channel_cancel_lport_listener(cancel_host,
+		else if (fwdtype == SSH_FWD_DYNAMIC)
+			ok = channel_cancel_lport_listener(cancel_host,
 			    cancel_port, 0, options.gateway_ports) > 0;
 		else
-                	ok = channel_cancel_lport_listener(cancel_host,
+			ok = channel_cancel_lport_listener(cancel_host,
 			    cancel_port, CHANNEL_CANCEL_PORT_STATIC,
 			    options.gateway_ports) > 0;
 		if (!ok) {
@@ -963,11 +964,11 @@ process_cmdline(void)
 		}
 		logit("Canceled forwarding.");
 	} else {
-		if (!parse_forward(&fwd, s, dynamic, remote)) {
+		if (!parse_forward(&fwd, s, fwdtype)) {
 			logit("Bad forwarding specification.");
 			goto out;
 		}
-		if (local || dynamic) {
+		if (fwdtype == SSH_FWD_LOCAL || fwdtype == SSH_FWD_DYNAMIC) {
 			if (channel_setup_local_fwd_listener(fwd.listen_host,
 			    fwd.listen_port, fwd.connect_host,
 			    fwd.connect_port, options.gateway_ports) < 0) {
diff --git a/mux.c b/mux.c
index d90605e..e7b81d1 100644
--- a/mux.c
+++ b/mux.c
@@ -156,9 +156,9 @@ struct mux_master_state {
 #define MUX_S_TTY_ALLOC_FAIL	0x80000008
 
 /* type codes for MUX_C_OPEN_FWD and MUX_C_CLOSE_FWD */
-#define MUX_FWD_LOCAL   1
-#define MUX_FWD_REMOTE  2
-#define MUX_FWD_DYNAMIC 3
+#define MUX_FWD_LOCAL   SSH_FWD_LOCAL
+#define MUX_FWD_REMOTE  SSH_FWD_REMOTE
+#define MUX_FWD_DYNAMIC SSH_FWD_DYNAMIC
 
 static void mux_session_confirm(int, int, void *);
 
@@ -511,11 +511,11 @@ process_mux_terminate(u_int rid, Channel *c, Buffer *m, Buffer *r)
 }
 
 static char *
-format_forward(u_int ftype, Forward *fwd)
+format_forward(Forward *fwd)
 {
 	char *ret;
 
-	switch (ftype) {
+	switch (fwd->type) {
 	case MUX_FWD_LOCAL:
 		xasprintf(&ret, "local forward %.200s:%d -> %.200s:%d",
 		    (fwd->listen_host == NULL) ?
@@ -537,7 +537,7 @@ format_forward(u_int ftype, Forward *fwd)
 		    fwd->connect_host, fwd->connect_port);
 		break;
 	default:
-		fatal("%s: unknown forward type %u", __func__, ftype);
+		fatal("%s: unknown forward type %u", __func__, fwd->type);
 	}
 	return ret;
 }
@@ -555,6 +555,8 @@ compare_host(const char *a, const char *b)
 static int
 compare_forward(Forward *a, Forward *b)
 {
+	if (a->type != b->type)
+		return 0;
 	if (!compare_host(a->listen_host, b->listen_host))
 		return 0;
 	if (a->listen_port != b->listen_port)
@@ -631,11 +633,10 @@ process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
 {
 	Forward fwd;
 	char *fwd_desc = NULL;
-	u_int ftype;
 	int i, ret = 0, freefwd = 1;
 
 	fwd.listen_host = fwd.connect_host = NULL;
-	if (buffer_get_int_ret(&ftype, m) != 0 ||
+	if (buffer_get_int_ret(&fwd.type, m) != 0 ||
 	    (fwd.listen_host = buffer_get_string_ret(m, NULL)) == NULL ||
 	    buffer_get_int_ret(&fwd.listen_port, m) != 0 ||
 	    (fwd.connect_host = buffer_get_string_ret(m, NULL)) == NULL ||
@@ -655,11 +656,11 @@ process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
 	}
 
 	debug2("%s: channel %d: request %s", __func__, c->self,
-	    (fwd_desc = format_forward(ftype, &fwd)));
+	    (fwd_desc = format_forward(&fwd)));
 
-	if (ftype != MUX_FWD_LOCAL && ftype != MUX_FWD_REMOTE &&
-	    ftype != MUX_FWD_DYNAMIC) {
-		logit("%s: invalid forwarding type %u", __func__, ftype);
+	if (fwd.type != MUX_FWD_LOCAL && fwd.type != MUX_FWD_REMOTE &&
+	    fwd.type != MUX_FWD_DYNAMIC) {
+		logit("%s: invalid forwarding type %u", __func__, fwd.type);
  invalid:
 		if (fwd.listen_host)
 			xfree(fwd.listen_host);
@@ -675,19 +676,19 @@ process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
 		    fwd.listen_port);
 		goto invalid;
 	}
-	if (fwd.connect_port >= 65536 || (ftype != MUX_FWD_DYNAMIC &&
-	    ftype != MUX_FWD_REMOTE && fwd.connect_port == 0)) {
+	if (fwd.connect_port >= 65536 || (fwd.type != MUX_FWD_DYNAMIC &&
+	    fwd.type != MUX_FWD_REMOTE && fwd.connect_port == 0)) {
 		logit("%s: invalid connect port %u", __func__,
 		    fwd.connect_port);
 		goto invalid;
 	}
-	if (ftype != MUX_FWD_DYNAMIC && fwd.connect_host == NULL) {
+	if (fwd.type != MUX_FWD_DYNAMIC && fwd.connect_host == NULL) {
 		logit("%s: missing connect host", __func__);
 		goto invalid;
 	}
 
 	/* Skip forwards that have already been requested */
-	switch (ftype) {
+	switch (fwd.type) {
 	case MUX_FWD_LOCAL:
 	case MUX_FWD_DYNAMIC:
 		for (i = 0; i < options.num_local_forwards; i++) {
@@ -731,7 +732,7 @@ process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
 		}
 	}
 
-	if (ftype == MUX_FWD_LOCAL || ftype == MUX_FWD_DYNAMIC) {
+	if (fwd.type == MUX_FWD_LOCAL || fwd.type == MUX_FWD_DYNAMIC) {
 		if (channel_setup_local_fwd_listener(fwd.listen_host,
 		    fwd.listen_port, fwd.connect_host, fwd.connect_port,
 		    options.gateway_ports) < 0) {
@@ -783,11 +784,10 @@ process_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
 	Forward fwd, *found_fwd;
 	char *fwd_desc = NULL;
 	const char *error_reason = NULL;
-	u_int ftype;
 	int i, listen_port, ret = 0;
 
 	fwd.listen_host = fwd.connect_host = NULL;
-	if (buffer_get_int_ret(&ftype, m) != 0 ||
+	if (buffer_get_int_ret(&fwd.type, m) != 0 ||
 	    (fwd.listen_host = buffer_get_string_ret(m, NULL)) == NULL ||
 	    buffer_get_int_ret(&fwd.listen_port, m) != 0 ||
 	    (fwd.connect_host = buffer_get_string_ret(m, NULL)) == NULL ||
@@ -807,11 +807,11 @@ process_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
 	}
 
 	debug2("%s: channel %d: request cancel %s", __func__, c->self,
-	    (fwd_desc = format_forward(ftype, &fwd)));
+	    (fwd_desc = format_forward(&fwd)));
 
 	/* make sure this has been requested */
 	found_fwd = NULL;
-	switch (ftype) {
+	switch (fwd.type) {
 	case MUX_FWD_LOCAL:
 	case MUX_FWD_DYNAMIC:
 		for (i = 0; i < options.num_local_forwards; i++) {
@@ -835,22 +835,22 @@ process_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
 
 	if (found_fwd == NULL)
 		error_reason = "port not forwarded";
-	else if (ftype == MUX_FWD_REMOTE) {
+	else if (found_fwd->type == MUX_FWD_REMOTE) {
 		/*
 		 * This shouldn't fail unless we confused the host/port
 		 * between options.remote_forwards and permitted_opens.
 		 * However, for dynamic allocated listen ports we need
 		 * to lookup the actual listen port.
 		 */
-	        listen_port = (fwd.listen_port == 0) ?
-		    found_fwd->allocated_port : fwd.listen_port;
-		if (channel_request_rforward_cancel(fwd.listen_host,
+		listen_port = (found_fwd->listen_port == 0) ?
+		    found_fwd->allocated_port : found_fwd->listen_port;
+		if (channel_request_rforward_cancel(found_fwd->listen_host,
 		    listen_port) == -1)
 			error_reason = "port not in permitted opens";
 	} else {	/* local and dynamic forwards */
 		/* Ditto */
-		if (channel_cancel_lport_listener(fwd.listen_host,
-		    fwd.listen_port, fwd.connect_port,
+		if (channel_cancel_lport_listener(found_fwd->listen_host,
+		    found_fwd->listen_port, found_fwd->connect_port,
 		    options.gateway_ports) == -1)
 			error_reason = "port not found";
 	}
@@ -859,6 +859,7 @@ process_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
 		buffer_put_int(r, MUX_S_OK);
 		buffer_put_int(r, rid);
 
+		found_fwd->type = 0;
 		if (found_fwd->listen_host != NULL)
 			xfree(found_fwd->listen_host);
 		if (found_fwd->connect_host != NULL)
@@ -1597,13 +1598,13 @@ mux_client_request_terminate(int fd)
 }
 
 static int
-mux_client_forward(int fd, int cancel_flag, u_int ftype, Forward *fwd)
+mux_client_forward(int fd, int cancel_flag, Forward *fwd)
 {
 	Buffer m;
 	char *e, *fwd_desc;
 	u_int type, rid;
 
-	fwd_desc = format_forward(ftype, fwd);
+	fwd_desc = format_forward(fwd);
 	debug("Requesting %s %s",
 	    cancel_flag ? "cancellation of" : "forwarding of", fwd_desc);
 	xfree(fwd_desc);
@@ -1611,7 +1612,7 @@ mux_client_forward(int fd, int cancel_flag, u_int ftype, Forward *fwd)
 	buffer_init(&m);
 	buffer_put_int(&m, cancel_flag ? MUX_C_CLOSE_FWD : MUX_C_OPEN_FWD);
 	buffer_put_int(&m, muxclient_request_id);
-	buffer_put_int(&m, ftype);
+	buffer_put_int(&m, fwd->type);
 	buffer_put_cstring(&m,
 	    fwd->listen_host == NULL ? "" : fwd->listen_host);
 	buffer_put_int(&m, fwd->listen_port);
@@ -1680,13 +1681,11 @@ mux_client_forwards(int fd, int cancel_flag)
 	/* XXX ExitOnForwardingFailure */
 	for (i = 0; i < options.num_local_forwards; i++) {
 		if (mux_client_forward(fd, cancel_flag,
-		    options.local_forwards[i].connect_port == 0 ?
-		    MUX_FWD_DYNAMIC : MUX_FWD_LOCAL,
 		    options.local_forwards + i) != 0)
 			ret = -1;
 	}
 	for (i = 0; i < options.num_remote_forwards; i++) {
-		if (mux_client_forward(fd, cancel_flag, MUX_FWD_REMOTE,
+		if (mux_client_forward(fd, cancel_flag,
 		    options.remote_forwards + i) != 0)
 			ret = -1;
 	}
diff --git a/readconf.c b/readconf.c
index 097bb05..29e12bd 100644
--- a/readconf.c
+++ b/readconf.c
@@ -269,6 +269,7 @@ add_local_forward(Options *options, const Forward *newfwd)
 	    sizeof(*options->local_forwards));
 	fwd = &options->local_forwards[options->num_local_forwards++];
 
+	fwd->type = newfwd->type;
 	fwd->listen_host = newfwd->listen_host;
 	fwd->listen_port = newfwd->listen_port;
 	fwd->connect_host = newfwd->connect_host;
@@ -290,6 +291,7 @@ add_remote_forward(Options *options, const Forward *newfwd)
 	    sizeof(*options->remote_forwards));
 	fwd = &options->remote_forwards[options->num_remote_forwards++];
 
+	fwd->type = newfwd->type;
 	fwd->listen_host = newfwd->listen_host;
 	fwd->listen_port = newfwd->listen_port;
 	fwd->connect_host = newfwd->connect_host;
@@ -784,8 +786,9 @@ parse_int:
 		}
 
 		if (parse_forward(&fwd, fwdarg,
-		    opcode == oDynamicForward ? 1 : 0,
-		    opcode == oRemoteForward ? 1 : 0) == 0)
+		    opcode == oDynamicForward ? SSH_FWD_DYNAMIC :
+		    opcode == oRemoteForward  ? SSH_FWD_REMOTE :
+		                                SSH_FWD_LOCAL) == 0)
 			fatal("%.200s line %d: Bad forwarding specification.",
 			    filename, linenum);
 
@@ -1378,19 +1381,20 @@ fill_default_options(Options * options)
 /*
  * parse_forward
  * parses a string containing a port forwarding specification of the form:
- *   dynamicfwd == 0
+ *   fwdtype != SSH_FWD_DYNAMIC
  *	[listenhost:]listenport:connecthost:connectport
- *   dynamicfwd == 1
+ *   fwdtype == SSH_FWD_DYNAMIC
  *	[listenhost:]listenport
  * returns number of arguments parsed or zero on error
  */
 int
-parse_forward(Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd)
+parse_forward(Forward *fwd, const char *fwdspec, u_int fwdtype)
 {
 	int i;
 	char *p, *cp, *fwdarg[4];
 
 	memset(fwd, '\0', sizeof(*fwd));
+	fwd->type = fwdtype;
 
 	cp = p = xstrdup(fwdspec);
 
@@ -1438,7 +1442,7 @@ parse_forward(Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd)
 
 	xfree(p);
 
-	if (dynamicfwd) {
+	if (fwd->type == SSH_FWD_DYNAMIC) {
 		if (!(i == 1 || i == 2))
 			goto fail_free;
 	} else {
@@ -1448,7 +1452,8 @@ parse_forward(Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd)
 			goto fail_free;
 	}
 
-	if (fwd->listen_port < 0 || (!remotefwd && fwd->listen_port == 0))
+	if (fwd->listen_port < 0 ||
+	    (fwd->type != SSH_FWD_REMOTE && fwd->listen_port == 0))
 		goto fail_free;
 
 	if (fwd->connect_host != NULL &&
diff --git a/readconf.h b/readconf.h
index be30ee0..b15d916 100644
--- a/readconf.h
+++ b/readconf.h
@@ -18,7 +18,13 @@
 
 /* Data structure for representing a forwarding request. */
 
+/* This is also part of the MUX protocol */
+#define SSH_FWD_LOCAL   1
+#define SSH_FWD_REMOTE  2
+#define SSH_FWD_DYNAMIC 3
+
 typedef struct {
+	u_int	  type;			/* Type of forwarding [1, 2, 3] */
 	char	 *listen_host;		/* Host (address) to listen on. */
 	int	  listen_port;		/* Port to forward. */
 	char	 *connect_host;		/* Host to connect. */
@@ -151,11 +157,11 @@ typedef struct {
 void     initialize_options(Options *);
 void     fill_default_options(Options *);
 int	 read_config_file(const char *, const char *, Options *, int);
-int	 parse_forward(Forward *, const char *, int, int);
 
 int
 process_config_line(Options *, const char *, char *, const char *, int, int *);
 
+int	 parse_forward(Forward *, const char *, u_int);
 void	 add_local_forward(Options *, const Forward *);
 void	 add_remote_forward(Options *, const Forward *);
 
diff --git a/ssh.c b/ssh.c
index 68e1315..a63bfab 100644
--- a/ssh.c
+++ b/ssh.c
@@ -456,7 +456,7 @@ main(int ac, char **av)
 				fatal("stdio forward already specified");
 			if (muxclient_command != 0)
 				fatal("Cannot specify stdio forward with -O");
-			if (parse_forward(&fwd, optarg, 1, 0)) {
+			if (parse_forward(&fwd, optarg, SSH_FWD_DYNAMIC)) {
 				stdio_forward_host = fwd.listen_host;
 				stdio_forward_port = fwd.listen_port;
 				xfree(fwd.connect_host);
@@ -538,7 +538,7 @@ main(int ac, char **av)
 			break;
 
 		case 'L':
-			if (parse_forward(&fwd, optarg, 0, 0))
+			if (parse_forward(&fwd, optarg, SSH_FWD_LOCAL))
 				add_local_forward(&options, &fwd);
 			else {
 				fprintf(stderr,
@@ -549,7 +549,7 @@ main(int ac, char **av)
 			break;
 
 		case 'R':
-			if (parse_forward(&fwd, optarg, 0, 1)) {
+			if (parse_forward(&fwd, optarg, SSH_FWD_REMOTE)) {
 				add_remote_forward(&options, &fwd);
 			} else {
 				fprintf(stderr,
@@ -560,7 +560,7 @@ main(int ac, char **av)
 			break;
 
 		case 'D':
-			if (parse_forward(&fwd, optarg, 1, 0)) {
+			if (parse_forward(&fwd, optarg, SSH_FWD_DYNAMIC)) {
 				add_local_forward(&options, &fwd);
 			} else {
 				fprintf(stderr,
-- 
1.7.9.rc0.542.g07ca1



More information about the openssh-unix-dev mailing list