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 }