Bugzilla – Attachment 1605 Details for
Bug 1330
ControlPersist: fork and leave ControlMaster behind as a daemon
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Updated patch for 5.1p1
openssh-5.1p1-ControlPersist.patch (text/plain), 9.47 KB, created by
Martin Ling
on 2009-02-22 13:51:25 AEDT
(
hide
)
Description:
Updated patch for 5.1p1
Filename:
MIME Type:
Creator:
Martin Ling
Created:
2009-02-22 13:51:25 AEDT
Size:
9.47 KB
patch
obsolete
>diff -ur openssh-5.1p1/clientloop.c openssh-5.1p1-cp/clientloop.c >--- openssh-5.1p1/clientloop.c 2008-07-16 13:40:52.000000000 +0100 >+++ openssh-5.1p1-cp/clientloop.c 2009-02-22 02:06:42.000000000 +0000 >@@ -142,6 +142,9 @@ > /* Flag indicating whether the user's terminal is in non-blocking mode. */ > static int in_non_blocking_mode = 0; > >+/* Time when backgrounded control master using ControlPersist should exit */ >+static time_t control_persist_exit_time = 0; >+ > /* Common data for the client loop code. */ > static volatile sig_atomic_t quit_pending; /* Set non-zero to quit the loop. */ > static int escape_char1; /* Escape character. (proto1 only) */ >@@ -246,6 +249,32 @@ > return (double) tv.tv_sec + (double) tv.tv_usec / 1000000.0; > } > >+/* >+ * Sets control_persist_exit_time to the absolute time when the >+ * backgrounded control master should exit due to expiry of the >+ * ControlPersist timeout. Sets it to 0 if we are not a backgrounded >+ * control master process, or if there is no ControlPersist timeout. >+ */ >+static void >+set_control_persist_exit_time(void) >+{ >+ if (muxserver_sock == -1 || !options.control_persist >+ || options.control_persist_timeout == 0) >+ /* not using a ControlPersist timeout */ >+ control_persist_exit_time = 0; >+ else if (channel_still_open()) >+ /* some client connections are still open */ >+ control_persist_exit_time = 0; >+ else if (control_persist_exit_time <= 0) { >+ /* a client connection has recently closed */ >+ time_t now = time(NULL); >+ >+ control_persist_exit_time = now + >+ (time_t)options.control_persist_timeout; >+ } >+ /* else we are already counting down to the timeout */ >+} >+ > #define SSH_X11_PROTO "MIT-MAGIC-COOKIE-1" > void > client_x11_get_proto(const char *display, const char *xauth_path, >@@ -519,6 +548,8 @@ > int *maxfdp, u_int *nallocp, int rekeying) > { > struct timeval tv, *tvp; >+ time_t now; >+ int timeout_secs; > int ret; > > /* Add any selections by the channel mechanism. */ >@@ -565,13 +596,25 @@ > /* > * Wait for something to happen. This will suspend the process until > * some selected descriptor can be read, written, or has some other >- * event pending. >+ * event pending, or a timeout expires. > */ > >- if (options.server_alive_interval == 0 || !compat20) >+ now = time(NULL); >+ timeout_secs = INT_MAX; /* we use INT_MAX to mean no timeout */ >+ if (options.server_alive_interval > 0 && compat20) >+ timeout_secs = MIN(timeout_secs, >+ options.server_alive_interval); >+ set_control_persist_exit_time(); >+ if (control_persist_exit_time > 0) { >+ timeout_secs = MIN(timeout_secs, >+ control_persist_exit_time - now); >+ if (timeout_secs < 0) >+ timeout_secs = 0; >+ } >+ if (timeout_secs == INT_MAX) > tvp = NULL; > else { >- tv.tv_sec = options.server_alive_interval; >+ tv.tv_sec = timeout_secs; > tv.tv_usec = 0; > tvp = &tv; > } >@@ -1459,6 +1502,23 @@ > */ > if (FD_ISSET(connection_out, writeset)) > packet_write_poll(); >+ >+ /* >+ * If we are a backgrounded control master, and the >+ * timeout has expired without any active client >+ * connections, then quit. >+ */ >+ if (muxserver_sock != -1 && options.control_persist >+ && options.control_persist_timeout > 0 >+ && control_persist_exit_time > 0) >+ { >+ time_t now = time(NULL); >+ >+ if (now >= control_persist_exit_time) { >+ debug("ControlPersist timeout expired"); >+ break; >+ } >+ } > } > if (readset) > xfree(readset); >diff -ur openssh-5.1p1/readconf.c openssh-5.1p1-cp/readconf.c >--- openssh-5.1p1/readconf.c 2008-06-29 15:04:03.000000000 +0100 >+++ openssh-5.1p1-cp/readconf.c 2009-02-22 01:52:15.000000000 +0000 >@@ -128,7 +128,8 @@ > oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, > oAddressFamily, oGssAuthentication, oGssDelegateCreds, > oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, >- oSendEnv, oControlPath, oControlMaster, oHashKnownHosts, >+ oSendEnv, oControlPath, oControlMaster, oControlPersist, >+ oHashKnownHosts, > oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand, > oVisualHostKey, > oDeprecated, oUnsupported >@@ -222,6 +223,7 @@ > { "sendenv", oSendEnv }, > { "controlpath", oControlPath }, > { "controlmaster", oControlMaster }, >+ { "controlpersist", oControlPersist }, > { "hashknownhosts", oHashKnownHosts }, > { "tunnel", oTunnel }, > { "tunneldevice", oTunnelDevice }, >@@ -870,6 +872,30 @@ > *intptr = value; > break; > >+ case oControlPersist: >+ /* no/false/yes/true, or a time spec */ >+ intptr = &options->control_persist; >+ arg = strdelim(&s); >+ if (!arg || *arg == '\0') >+ fatal("%.200s line %d: Missing ControlPersist" >+ " argument.", filename, linenum); >+ value = 0; /* To avoid compiler warning... */ >+ value2 = 0; /* timeout */ >+ if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0) >+ value = 0; >+ else if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0) >+ value = 1; >+ else if ((value2 = convtime(arg)) > 0) >+ value = 1; >+ else >+ fatal("%.200s line %d: Bad ControlPersist argument.", >+ filename, linenum); >+ if (*activep && *intptr == -1) { >+ *intptr = value; >+ options->control_persist_timeout = value2; >+ } >+ break; >+ > case oHashKnownHosts: > intptr = &options->hash_known_hosts; > goto parse_flag; >@@ -1065,6 +1091,8 @@ > options->num_send_env = 0; > options->control_path = NULL; > options->control_master = -1; >+ options->control_persist = -1; >+ options->control_persist_timeout = 0; > options->hash_known_hosts = -1; > options->tun_open = -1; > options->tun_local = -1; >@@ -1196,6 +1224,10 @@ > options->server_alive_count_max = 3; > if (options->control_master == -1) > options->control_master = 0; >+ if (options->control_persist == -1) { >+ options->control_persist = 0; >+ options->control_persist_timeout = 0; >+ } > if (options->hash_known_hosts == -1) > options->hash_known_hosts = 0; > if (options->tun_open == -1) >diff -ur openssh-5.1p1/readconf.h openssh-5.1p1-cp/readconf.h >--- openssh-5.1p1/readconf.h 2008-06-29 15:04:03.000000000 +0100 >+++ openssh-5.1p1-cp/readconf.h 2009-02-22 01:52:15.000000000 +0000 >@@ -111,6 +111,8 @@ > > char *control_path; > int control_master; >+ int control_persist; /* ControlPersist flag */ >+ int control_persist_timeout; /* ControlPersist timeout (seconds) */ > > int hash_known_hosts; > >diff -ur openssh-5.1p1/ssh.c openssh-5.1p1-cp/ssh.c >--- openssh-5.1p1/ssh.c 2008-07-04 03:53:50.000000000 +0100 >+++ openssh-5.1p1-cp/ssh.c 2009-02-22 01:55:11.000000000 +0000 >@@ -707,6 +707,8 @@ > fatal("No ControlPath specified for \"-O\" command"); > if (options.control_path != NULL) > muxclient(options.control_path); >+ /* If muxclient() can connect to a master socket, >+ * then it doesn't return. */ > > timeout_ms = options.connection_timeout * 1000; > >@@ -1196,6 +1198,46 @@ > /* XXX should be pre-session */ > ssh_init_forwarding(); > >+ /* Start listening for multiplex clients */ >+ muxserver_listen(); >+ >+ /* >+ * If we are the control master, and if control_persist is set, >+ * then move the master into the background, and make the >+ * foreground process a client of the backgrounded master. >+ */ >+ if (options.control_persist && muxserver_sock != -1) { >+ pid_t childpid; >+ >+ childpid = fork(); >+ if (childpid < 0) { >+ fatal("fork() failed"); >+ } else if (childpid == 0) { >+ /* >+ * This is the child. Set some variables to let >+ * it continue continue operating as the control >+ * master in the background. >+ */ >+ debug("backgrounding control master"); >+ fork_after_authentication_flag = 1; >+ stdin_null_flag = 1; >+ no_shell_flag = 1; >+ no_tty_flag = 1; >+ tty_flag = 0; >+ } else { >+ /* >+ * This is the foreground process. Make it a >+ * client of the newly-backgrounded control >+ * master. muxclient() doesn't return >+ * unless it fails. >+ */ >+ close(muxserver_sock); >+ muxserver_sock = -1; >+ muxclient(options.control_path); >+ fatal("Failed to connect to new control master"); >+ } >+ } >+ > if (!no_shell_flag || (datafellows & SSH_BUG_DUMMYCHAN)) > id = ssh_session2_open(); > >@@ -1213,9 +1255,6 @@ > options.permit_local_command) > ssh_local_cmd(options.local_command); > >- /* Start listening for multiplex clients */ >- muxserver_listen(); >- > /* If requested, let ssh continue in the background. */ > if (fork_after_authentication_flag) { > fork_after_authentication_flag = 0; >diff -ur openssh-5.1p1/ssh_config.5 openssh-5.1p1-cp/ssh_config.5 >--- openssh-5.1p1/ssh_config.5 2008-06-29 15:04:03.000000000 +0100 >+++ openssh-5.1p1-cp/ssh_config.5 2009-02-22 01:52:15.000000000 +0000 >@@ -319,6 +319,28 @@ > used for opportunistic connection sharing include > at least %h, %p, and %r. > This ensures that shared connections are uniquely identified. >+.It Cm ControlPersist >+When used in conjunction with >+.Cm ControlMaster , >+specifies that the master connection should remain open >+in the background (waiting for future client connections) >+after the initial client connection has been closed. >+If set to >+.Dq no , >+then the master connection will not be placed into the background, >+and will close as soon as the initial client connection is closed. >+If set to >+.Dq yes , >+then the master connection will remain in the background indefinitely >+(until killed or closed via a mechanism such as the >+.Xr ssh 1 >+.Dq Fl O No exit >+option). >+If set to a time in seconds, or a time in any of the formats documented in >+.Xr sshd_config 5 , >+then the backgrounded master connection will automatically terminate >+after it has remained idle (with no client connections) for the >+specified time. > .It Cm DynamicForward > Specifies that a TCP port on the local machine be forwarded > over the secure channel, and the application
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 1330
:
1319
|
1322
|
1331
|
1338
|
1605
|
1858
|
1897