Mercurial > dropbear
comparison common-channel.c @ 1052:e40d1b63b6a6 coverity
merge
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Sat, 28 Feb 2015 23:25:16 +0800 |
parents | 01eea88963f3 |
children | c71df09bc610 |
comparison
equal
deleted
inserted
replaced
1046:b8f4b7027191 | 1052:e40d1b63b6a6 |
---|---|
33 #include "dbutil.h" | 33 #include "dbutil.h" |
34 #include "channel.h" | 34 #include "channel.h" |
35 #include "ssh.h" | 35 #include "ssh.h" |
36 #include "listener.h" | 36 #include "listener.h" |
37 #include "runopts.h" | 37 #include "runopts.h" |
38 #include "netio.h" | |
38 | 39 |
39 static void send_msg_channel_open_failure(unsigned int remotechan, int reason, | 40 static void send_msg_channel_open_failure(unsigned int remotechan, int reason, |
40 const unsigned char *text, const unsigned char *lang); | 41 const unsigned char *text, const unsigned char *lang); |
41 static void send_msg_channel_open_confirmation(struct Channel* channel, | 42 static void send_msg_channel_open_confirmation(struct Channel* channel, |
42 unsigned int recvwindow, | 43 unsigned int recvwindow, |
46 unsigned int incr); | 47 unsigned int incr); |
47 static void send_msg_channel_data(struct Channel *channel, int isextended); | 48 static void send_msg_channel_data(struct Channel *channel, int isextended); |
48 static void send_msg_channel_eof(struct Channel *channel); | 49 static void send_msg_channel_eof(struct Channel *channel); |
49 static void send_msg_channel_close(struct Channel *channel); | 50 static void send_msg_channel_close(struct Channel *channel); |
50 static void remove_channel(struct Channel *channel); | 51 static void remove_channel(struct Channel *channel); |
51 static void check_in_progress(struct Channel *channel); | |
52 static unsigned int write_pending(struct Channel * channel); | 52 static unsigned int write_pending(struct Channel * channel); |
53 static void check_close(struct Channel *channel); | 53 static void check_close(struct Channel *channel); |
54 static void close_chan_fd(struct Channel *channel, int fd, int how); | 54 static void close_chan_fd(struct Channel *channel, int fd, int how); |
55 | 55 |
56 #define FD_UNINIT (-2) | 56 #define FD_UNINIT (-2) |
161 | 161 |
162 newchan->typedata = NULL; | 162 newchan->typedata = NULL; |
163 newchan->writefd = FD_UNINIT; | 163 newchan->writefd = FD_UNINIT; |
164 newchan->readfd = FD_UNINIT; | 164 newchan->readfd = FD_UNINIT; |
165 newchan->errfd = FD_CLOSED; /* this isn't always set to start with */ | 165 newchan->errfd = FD_CLOSED; /* this isn't always set to start with */ |
166 newchan->initconn = 0; | |
167 newchan->await_open = 0; | 166 newchan->await_open = 0; |
168 newchan->flushing = 0; | 167 newchan->flushing = 0; |
169 | 168 |
170 newchan->writebuf = cbuf_new(0); /* resized later by chan_initwritebuf */ | 169 newchan->writebuf = cbuf_new(0); /* resized later by chan_initwritebuf */ |
171 newchan->recvwindow = 0; | 170 newchan->recvwindow = 0; |
240 do_check_close = 1; | 239 do_check_close = 1; |
241 } | 240 } |
242 | 241 |
243 /* write to program/pipe stdin */ | 242 /* write to program/pipe stdin */ |
244 if (channel->writefd >= 0 && FD_ISSET(channel->writefd, writefds)) { | 243 if (channel->writefd >= 0 && FD_ISSET(channel->writefd, writefds)) { |
245 if (channel->initconn) { | |
246 /* XXX should this go somewhere cleaner? */ | |
247 check_in_progress(channel); | |
248 continue; /* Important not to use the channel after | |
249 check_in_progress(), as it may be NULL */ | |
250 } | |
251 writechannel(channel, channel->writefd, channel->writebuf); | 244 writechannel(channel, channel->writefd, channel->writebuf); |
252 do_check_close = 1; | 245 do_check_close = 1; |
253 } | 246 } |
254 | 247 |
255 /* stderr for client mode */ | 248 /* stderr for client mode */ |
372 | 365 |
373 /* Check whether a deferred (EINPROGRESS) connect() was successful, and | 366 /* Check whether a deferred (EINPROGRESS) connect() was successful, and |
374 * if so, set up the channel properly. Otherwise, the channel is cleaned up, so | 367 * if so, set up the channel properly. Otherwise, the channel is cleaned up, so |
375 * it is important that the channel reference isn't used after a call to this | 368 * it is important that the channel reference isn't used after a call to this |
376 * function */ | 369 * function */ |
377 static void check_in_progress(struct Channel *channel) { | 370 void channel_connect_done(int result, int sock, void* user_data, const char* UNUSED(errstring)) { |
378 | 371 |
379 int val; | 372 struct Channel *channel = user_data; |
380 socklen_t vallen = sizeof(val); | 373 |
381 | 374 TRACE(("enter channel_connect_done")) |
382 TRACE(("enter check_in_progress")) | 375 |
383 | 376 if (result == DROPBEAR_SUCCESS) |
384 if (getsockopt(channel->writefd, SOL_SOCKET, SO_ERROR, &val, &vallen) | 377 { |
385 || val != 0) { | 378 channel->readfd = channel->writefd = sock; |
386 send_msg_channel_open_failure(channel->remotechan, | 379 channel->conn_pending = NULL; |
387 SSH_OPEN_CONNECT_FAILED, "", ""); | |
388 close(channel->writefd); | |
389 remove_channel(channel); | |
390 TRACE(("leave check_in_progress: fail")) | |
391 } else { | |
392 chan_initwritebuf(channel); | 380 chan_initwritebuf(channel); |
393 send_msg_channel_open_confirmation(channel, channel->recvwindow, | 381 send_msg_channel_open_confirmation(channel, channel->recvwindow, |
394 channel->recvmaxpacket); | 382 channel->recvmaxpacket); |
395 channel->readfd = channel->writefd; | 383 TRACE(("leave channel_connect_done: success")) |
396 channel->initconn = 0; | 384 } |
397 TRACE(("leave check_in_progress: success")) | 385 else |
386 { | |
387 send_msg_channel_open_failure(channel->remotechan, | |
388 SSH_OPEN_CONNECT_FAILED, "", ""); | |
389 remove_channel(channel); | |
390 TRACE(("leave check_in_progress: fail")) | |
398 } | 391 } |
399 } | 392 } |
400 | 393 |
401 | 394 |
402 /* Send the close message and set the channel as closed */ | 395 /* Send the close message and set the channel as closed */ |
512 FD_SET(channel->errfd, readfds); | 505 FD_SET(channel->errfd, readfds); |
513 } | 506 } |
514 } | 507 } |
515 | 508 |
516 /* Stuff from the wire */ | 509 /* Stuff from the wire */ |
517 if (channel->initconn | 510 if (channel->writefd >= 0 && cbuf_getused(channel->writebuf) > 0) { |
518 ||(channel->writefd >= 0 && cbuf_getused(channel->writebuf) > 0)) { | |
519 FD_SET(channel->writefd, writefds); | 511 FD_SET(channel->writefd, writefds); |
520 } | 512 } |
521 | 513 |
522 if (ERRFD_IS_WRITE(channel) && channel->errfd >= 0 | 514 if (ERRFD_IS_WRITE(channel) && channel->errfd >= 0 |
523 && cbuf_getused(channel->extrabuf) > 0) { | 515 && cbuf_getused(channel->extrabuf) > 0) { |
597 && channel->type->closehandler) { | 589 && channel->type->closehandler) { |
598 channel->type->closehandler(channel); | 590 channel->type->closehandler(channel); |
599 channel->close_handler_done = 1; | 591 channel->close_handler_done = 1; |
600 } | 592 } |
601 | 593 |
594 if (channel->conn_pending) { | |
595 cancel_connect(channel->conn_pending); | |
596 } | |
597 | |
602 ses.channels[channel->index] = NULL; | 598 ses.channels[channel->index] = NULL; |
603 m_free(channel); | 599 m_free(channel); |
604 ses.chancount--; | 600 ses.chancount--; |
605 | 601 |
606 update_channel_prio(); | 602 update_channel_prio(); |
1147 } | 1143 } |
1148 for (i = 0; i < ses.chansize; i++) { | 1144 for (i = 0; i < ses.chansize; i++) { |
1149 struct Channel *chan = ses.channels[i]; | 1145 struct Channel *chan = ses.channels[i]; |
1150 if (chan | 1146 if (chan |
1151 && !(chan->sent_eof || chan->recv_eof) | 1147 && !(chan->sent_eof || chan->recv_eof) |
1152 && !(chan->await_open || chan->initconn)) { | 1148 && !(chan->await_open)) { |
1153 return chan; | 1149 return chan; |
1154 } | 1150 } |
1155 } | 1151 } |
1156 return NULL; | 1152 return NULL; |
1157 } | 1153 } |