Skip to content

Commit fe992bf

Browse files
committed
Split ChanType closehandler() and cleanup() so that dbclient doesn't
lose exit status messages
1 parent ffde4a5 commit fe992bf

File tree

10 files changed

+58
-31
lines changed

10 files changed

+58
-31
lines changed

channel.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,6 @@ struct Channel {
6969
int sent_close, recv_close;
7070
int recv_eof, sent_eof;
7171

72-
/* Set after running the ChanType-specific close hander
73-
* to ensure we don't run it twice (nor type->checkclose()). */
74-
int close_handler_done;
75-
7672
struct dropbear_progress_connection *conn_pending;
7773
int initconn; /* used for TCP forwarding, whether the channel has been
7874
fully initialised */
@@ -95,10 +91,17 @@ struct ChanType {
9591

9692
int sepfds; /* Whether this channel has separate pipes for in/out or not */
9793
const char *name;
94+
/* Sets up the channel */
9895
int (*inithandler)(struct Channel*);
96+
/* Called to check whether a channel should close, separately from the FD being closed.
97+
Used for noticing process exiting */
9998
int (*check_close)(const struct Channel*);
99+
/* Handler for ssh_msg_channel_request */
100100
void (*reqhandler)(struct Channel*);
101+
/* Called prior to sending ssh_msg_channel_close, used for sending exit status */
101102
void (*closehandler)(const struct Channel*);
103+
/* Frees resources, called just prior to channel being removed */
104+
void (*cleanup)(const struct Channel*);
102105
};
103106

104107
/* Callback for connect_remote */

cli-agentfwd.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ const struct ChanType cli_chan_agent = {
5252
new_agent_chan,
5353
NULL,
5454
NULL,
55+
NULL,
5556
NULL
5657
};
5758

cli-chansession.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
#include "chansession.h"
3636
#include "agentfwd.h"
3737

38-
static void cli_closechansess(const struct Channel *channel);
38+
static void cli_cleanupchansess(const struct Channel *channel);
3939
static int cli_initchansess(struct Channel *channel);
4040
static void cli_chansessreq(struct Channel *channel);
4141
static void send_chansess_pty_req(const struct Channel *channel);
@@ -51,7 +51,8 @@ const struct ChanType clichansess = {
5151
cli_initchansess, /* inithandler */
5252
NULL, /* checkclosehandler */
5353
cli_chansessreq, /* reqhandler */
54-
cli_closechansess, /* closehandler */
54+
NULL, /* closehandler */
55+
cli_cleanupchansess, /* cleanup */
5556
};
5657

5758
static void cli_chansessreq(struct Channel *channel) {
@@ -83,7 +84,7 @@ static void cli_chansessreq(struct Channel *channel) {
8384

8485

8586
/* If the main session goes, we close it up */
86-
static void cli_closechansess(const struct Channel *UNUSED(channel)) {
87+
static void cli_cleanupchansess(const struct Channel *UNUSED(channel)) {
8788
cli_tty_cleanup(); /* Restore tty modes etc */
8889

8990
/* This channel hasn't gone yet, so we have > 1 */
@@ -387,7 +388,8 @@ static const struct ChanType cli_chan_netcat = {
387388
cli_init_netcat, /* inithandler */
388389
NULL,
389390
NULL,
390-
cli_closechansess
391+
NULL,
392+
cli_cleanupchansess
391393
};
392394

393395
void cli_send_netcat_request() {

cli-session.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,7 @@ static void cli_session_cleanup(void) {
356356
}
357357

358358
static void cli_finished() {
359+
TRACE(("cli_finised()"))
359360

360361
session_cleanup();
361362
fprintf(stderr, "Connection to %s@%s:%s closed.\n", cli_opts.username,

cli-tcpfwd.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ const struct ChanType cli_chan_tcpremote = {
4040
newtcpforwarded,
4141
NULL,
4242
NULL,
43+
NULL,
4344
NULL
4445
};
4546
#endif
@@ -55,6 +56,7 @@ static const struct ChanType cli_chan_tcplocal = {
5556
tcp_prio_inithandler,
5657
NULL,
5758
NULL,
59+
NULL,
5860
NULL
5961
};
6062
#endif

common-channel.c

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,6 @@ static struct Channel* newchannel(unsigned int remotechan,
144144
newchan->index = i;
145145
newchan->sent_close = newchan->recv_close = 0;
146146
newchan->sent_eof = newchan->recv_eof = 0;
147-
newchan->close_handler_done = 0;
148147

149148
newchan->remotechan = remotechan;
150149
newchan->transwindow = transwindow;
@@ -286,7 +285,7 @@ static void check_close(struct Channel *channel) {
286285
channel->extrabuf ? cbuf_getused(channel->extrabuf) : 0))
287286

288287
if (!channel->flushing
289-
&& !channel->close_handler_done
288+
&& !channel->sent_close
290289
&& channel->type->check_close
291290
&& channel->type->check_close(channel))
292291
{
@@ -298,7 +297,7 @@ static void check_close(struct Channel *channel) {
298297
channel, to ensure that the shell has exited (and the exit status
299298
retrieved) before we close things up. */
300299
if (!channel->type->check_close
301-
|| channel->close_handler_done
300+
|| channel->sent_close
302301
|| channel->type->check_close(channel)) {
303302
close_allowed = 1;
304303
}
@@ -385,10 +384,8 @@ void channel_connect_done(int result, int sock, void* user_data, const char* UNU
385384
static void send_msg_channel_close(struct Channel *channel) {
386385

387386
TRACE(("enter send_msg_channel_close %p", (void*)channel))
388-
if (channel->type->closehandler
389-
&& !channel->close_handler_done) {
387+
if (channel->type->closehandler) {
390388
channel->type->closehandler(channel);
391-
channel->close_handler_done = 1;
392389
}
393390

394391
CHECKCLEARTOWRITE();
@@ -661,10 +658,8 @@ static void remove_channel(struct Channel * channel) {
661658
m_close(channel->errfd);
662659
}
663660

664-
if (!channel->close_handler_done
665-
&& channel->type->closehandler) {
666-
channel->type->closehandler(channel);
667-
channel->close_handler_done = 1;
661+
if (channel->type->cleanup) {
662+
channel->type->cleanup(channel);
668663
}
669664

670665
if (channel->conn_pending) {
@@ -690,13 +685,7 @@ void recv_msg_channel_request() {
690685

691686
TRACE(("enter recv_msg_channel_request %p", (void*)channel))
692687

693-
if (channel->sent_close) {
694-
TRACE(("leave recv_msg_channel_request: already closed channel"))
695-
return;
696-
}
697-
698-
if (channel->type->reqhandler
699-
&& !channel->close_handler_done) {
688+
if (channel->type->reqhandler) {
700689
channel->type->reqhandler(channel);
701690
} else {
702691
int wantreply;
@@ -1011,6 +1000,11 @@ void recv_msg_channel_open() {
10111000
void send_msg_channel_failure(const struct Channel *channel) {
10121001

10131002
TRACE(("enter send_msg_channel_failure"))
1003+
1004+
if (channel->sent_close) {
1005+
TRACE(("Skipping sending msg_channel_failure for closed channel"))
1006+
return;
1007+
}
10141008
CHECKCLEARTOWRITE();
10151009

10161010
buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_FAILURE);
@@ -1024,6 +1018,10 @@ void send_msg_channel_failure(const struct Channel *channel) {
10241018
void send_msg_channel_success(const struct Channel *channel) {
10251019

10261020
TRACE(("enter send_msg_channel_success"))
1021+
if (channel->sent_close) {
1022+
TRACE(("Skipping sending msg_channel_success for closed channel"))
1023+
return;
1024+
}
10271025
CHECKCLEARTOWRITE();
10281026

10291027
buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_SUCCESS);

svr-agentfwd.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ static const struct ChanType chan_svr_agent = {
187187
NULL,
188188
NULL,
189189
NULL,
190+
NULL,
190191
NULL
191192
};
192193

svr-chansession.c

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ static void execchild(const void *user_data_chansess);
5151
static void addchildpid(struct ChanSess *chansess, pid_t pid);
5252
static void sesssigchild_handler(int val);
5353
static void closechansess(const struct Channel *channel);
54+
static void cleanupchansess(const struct Channel *channel);
5455
static int newchansess(struct Channel *channel);
5556
static void chansessionrequest(struct Channel *channel);
5657
static int sesscheckclose(const struct Channel *channel);
@@ -69,6 +70,7 @@ const struct ChanType svrchansess = {
6970
sesscheckclose, /* checkclosehandler */
7071
chansessionrequest, /* reqhandler */
7172
closechansess, /* closehandler */
73+
cleanupchansess /* cleanup */
7274
};
7375

7476
/* required to clear environment */
@@ -91,7 +93,7 @@ void svr_chansess_checksignal(void) {
9193
while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
9294
unsigned int i;
9395
struct exitinfo *ex = NULL;
94-
TRACE(("sigchld handler: pid %d", pid))
96+
TRACE(("svr_chansess_checksignal : pid %d", pid))
9597

9698
ex = NULL;
9799
/* find the corresponding chansess */
@@ -285,8 +287,25 @@ chansess_login_alloc(const struct ChanSess *chansess) {
285287
return li;
286288
}
287289

288-
/* clean a session channel */
290+
/* send exit status message before the channel is closed */
289291
static void closechansess(const struct Channel *channel) {
292+
struct ChanSess *chansess;
293+
294+
TRACE(("enter closechansess"))
295+
296+
chansess = (struct ChanSess*)channel->typedata;
297+
298+
if (chansess == NULL) {
299+
TRACE(("leave closechansess: chansess == NULL"))
300+
return;
301+
}
302+
303+
send_exitsignalstatus(channel);
304+
TRACE(("leave closechansess"))
305+
}
306+
307+
/* clean a session channel */
308+
static void cleanupchansess(const struct Channel *channel) {
290309

291310
struct ChanSess *chansess;
292311
unsigned int i;
@@ -301,8 +320,6 @@ static void closechansess(const struct Channel *channel) {
301320
return;
302321
}
303322

304-
send_exitsignalstatus(channel);
305-
306323
m_free(chansess->cmd);
307324
m_free(chansess->term);
308325

svr-tcpfwd.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,8 @@ const struct ChanType svr_chan_tcpdirect = {
238238
newtcpdirect, /* init */
239239
NULL, /* checkclose */
240240
NULL, /* reqhandler */
241-
NULL /* closehandler */
241+
NULL, /* closehandler */
242+
NULL /* cleanup */
242243
};
243244

244245
/* Called upon creating a new direct tcp channel (ie we connect out to an

svr-x11fwd.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,8 @@ static const struct ChanType chan_x11 = {
216216
x11_inithandler, /* inithandler */
217217
NULL, /* checkclose */
218218
NULL, /* reqhandler */
219-
NULL /* closehandler */
219+
NULL, /* closehandler */
220+
NULL /* cleanup */
220221
};
221222

222223

0 commit comments

Comments
 (0)