Mercurial > dropbear
comparison common-channel.c @ 359:78518751cb82 channel-fix
just shuffle some variables names about, a brief comment
about the "bad writefd" problem
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Sun, 01 Oct 2006 16:35:13 +0000 |
parents | 6f90e5fd42cc |
children | 1c7bf9cec6c8 |
comparison
equal
deleted
inserted
replaced
358:e81d3bc1dc78 | 359:78518751cb82 |
---|---|
45 unsigned int incr); | 45 unsigned int incr); |
46 static void send_msg_channel_data(struct Channel *channel, int isextended, | 46 static void send_msg_channel_data(struct Channel *channel, int isextended, |
47 unsigned int exttype); | 47 unsigned int exttype); |
48 static void send_msg_channel_eof(struct Channel *channel); | 48 static void send_msg_channel_eof(struct Channel *channel); |
49 static void send_msg_channel_close(struct Channel *channel); | 49 static void send_msg_channel_close(struct Channel *channel); |
50 static void removechannel(struct Channel *channel); | 50 static void remove_channel(struct Channel *channel); |
51 static void deletechannel(struct Channel *channel); | 51 static void delete_channel(struct Channel *channel); |
52 static void checkinitdone(struct Channel *channel); | 52 static void check_in_progress(struct Channel *channel); |
53 static void checkclose(struct Channel *channel); | 53 static void check_close(struct Channel *channel); |
54 | 54 |
55 static void closewritefd(struct Channel * channel); | 55 static void close_write_fd(struct Channel * channel); |
56 static void closereadfd(struct Channel * channel, int fd); | 56 static void close_read_fd(struct Channel * channel, int fd); |
57 static void closechanfd(struct Channel *channel, int fd, int how); | 57 static void close_chan_fd(struct Channel *channel, int fd, int how); |
58 | 58 |
59 #define FD_UNINIT (-2) | 59 #define FD_UNINIT (-2) |
60 #define FD_CLOSED (-1) | 60 #define FD_CLOSED (-1) |
61 | 61 |
62 /* Initialise all the channels */ | 62 /* Initialise all the channels */ |
83 | 83 |
84 TRACE(("enter chancleanup")) | 84 TRACE(("enter chancleanup")) |
85 for (i = 0; i < ses.chansize; i++) { | 85 for (i = 0; i < ses.chansize; i++) { |
86 if (ses.channels[i] != NULL) { | 86 if (ses.channels[i] != NULL) { |
87 TRACE(("channel %d closing", i)) | 87 TRACE(("channel %d closing", i)) |
88 removechannel(ses.channels[i]); | 88 remove_channel(ses.channels[i]); |
89 } | 89 } |
90 } | 90 } |
91 m_free(ses.channels); | 91 m_free(ses.channels); |
92 TRACE(("leave chancleanup")) | 92 TRACE(("leave chancleanup")) |
93 } | 93 } |
133 } | 133 } |
134 | 134 |
135 newchan = (struct Channel*)m_malloc(sizeof(struct Channel)); | 135 newchan = (struct Channel*)m_malloc(sizeof(struct Channel)); |
136 newchan->type = type; | 136 newchan->type = type; |
137 newchan->index = i; | 137 newchan->index = i; |
138 newchan->sentclosed = newchan->recvclosed = 0; | 138 newchan->sent_close = newchan->recv_close = 0; |
139 newchan->senteof = newchan->recveof = 0; | 139 newchan->sent_eof = newchan->recv_eof = 0; |
140 | 140 |
141 newchan->remotechan = remotechan; | 141 newchan->remotechan = remotechan; |
142 newchan->transwindow = transwindow; | 142 newchan->transwindow = transwindow; |
143 newchan->transmaxpacket = transmaxpacket; | 143 newchan->transmaxpacket = transmaxpacket; |
144 | 144 |
201 if (channel->extrabuf == NULL && | 201 if (channel->extrabuf == NULL && |
202 channel->errfd >= 0 && FD_ISSET(channel->errfd, readfds)) { | 202 channel->errfd >= 0 && FD_ISSET(channel->errfd, readfds)) { |
203 send_msg_channel_data(channel, 1, SSH_EXTENDED_DATA_STDERR); | 203 send_msg_channel_data(channel, 1, SSH_EXTENDED_DATA_STDERR); |
204 } | 204 } |
205 | 205 |
206 /* if we can read from the writefd, it might be closed, so we try to | 206 #if 0 |
207 * see if it has errors */ | 207 /* XXX where is this required? */ |
208 if (IS_DROPBEAR_SERVER && channel->writefd >= 0 | |
209 && channel->writefd != channel->readfd | |
210 && FD_ISSET(channel->writefd, readfds)) { | |
211 if (channel->initconn) { | 208 if (channel->initconn) { |
212 /* Handling for "in progress" connection - this is needed | 209 /* Handling for "in progress" connection - this is needed |
213 * to avoid spinning 100% CPU when we connect to a server | 210 * to avoid spinning 100% CPU when we connect to a server |
214 * which doesn't send anything (tcpfwding) */ | 211 * which doesn't send anything (tcpfwding) */ |
215 checkinitdone(channel); | 212 check_in_progress(channel); |
216 continue; /* Important not to use the channel after | 213 continue; /* Important not to use the channel after |
217 checkinitdone(), as it may be NULL */ | 214 check_in_progress(), as it may be NULL */ |
218 } | 215 } |
219 ret = write(channel->writefd, NULL, 0); /* Fake write */ | 216 #endif |
220 if (ret < 0 && errno != EINTR && errno != EAGAIN) { | |
221 closewritefd(channel); | |
222 } | |
223 } | |
224 | 217 |
225 /* write to program/pipe stdin */ | 218 /* write to program/pipe stdin */ |
226 if (channel->writefd >= 0 && FD_ISSET(channel->writefd, writefds)) { | 219 if (channel->writefd >= 0 && FD_ISSET(channel->writefd, writefds)) { |
227 if (channel->initconn) { | 220 if (channel->initconn) { |
228 checkinitdone(channel); | 221 check_in_progress(channel); |
229 continue; /* Important not to use the channel after | 222 continue; /* Important not to use the channel after |
230 checkinitdone(), as it may be NULL */ | 223 check_in_progress(), as it may be NULL */ |
231 } | 224 } |
232 writechannel(channel, channel->writefd, channel->writebuf); | 225 writechannel(channel, channel->writefd, channel->writebuf); |
233 } | 226 } |
234 | 227 |
235 /* stderr for client mode */ | 228 /* stderr for client mode */ |
237 && channel->errfd >= 0 && FD_ISSET(channel->errfd, writefds)) { | 230 && channel->errfd >= 0 && FD_ISSET(channel->errfd, writefds)) { |
238 writechannel(channel, channel->errfd, channel->extrabuf); | 231 writechannel(channel, channel->errfd, channel->extrabuf); |
239 } | 232 } |
240 | 233 |
241 /* now handle any of the channel-closing type stuff */ | 234 /* now handle any of the channel-closing type stuff */ |
242 checkclose(channel); | 235 check_close(channel); |
243 | 236 |
244 } /* foreach channel */ | 237 } /* foreach channel */ |
245 | 238 |
246 /* Listeners such as TCP, X11, agent-auth */ | 239 /* Listeners such as TCP, X11, agent-auth */ |
247 #ifdef USING_LISTENERS | 240 #ifdef USING_LISTENERS |
248 handle_listeners(readfds); | 241 handle_listeners(readfds); |
249 #endif | 242 #endif |
250 } | 243 } |
251 | 244 |
252 | 245 |
253 /* do all the EOF/close type stuff checking for a channel */ | 246 /* EOF/close handling */ |
254 static void checkclose(struct Channel *channel) { | 247 static void check_close(struct Channel *channel) { |
255 | 248 |
256 TRACE(("checkclose: writefd %d, readfd %d, errfd %d, sentclosed %d, recvclosed %d", | 249 TRACE(("check_close: writefd %d, readfd %d, errfd %d, sent_close %d, recv_close %d", |
257 channel->writefd, channel->readfd, | 250 channel->writefd, channel->readfd, |
258 channel->errfd, channel->sentclosed, channel->recvclosed)) | 251 channel->errfd, channel->sent_close, channel->recv_close)) |
259 TRACE(("writebuf size %d extrabuf ptr 0x%x extrabuf size %d", | 252 TRACE(("writebuf size %d extrabuf ptr 0x%x extrabuf size %d", |
260 cbuf_getused(channel->writebuf), | 253 cbuf_getused(channel->writebuf), |
261 channel->writebuf, | 254 channel->writebuf, |
262 channel->writebuf ? 0 : cbuf_getused(channel->extrabuf))) | 255 channel->writebuf ? 0 : cbuf_getused(channel->extrabuf))) |
263 | 256 |
264 /* server chansession channels are special, since readfd mightn't | 257 /* server chansession channels are special, since readfd mightn't |
265 * close in the case of "sleep 4 & echo blah" until the sleep is up */ | 258 * close in the case of "sleep 4 & echo blah" until the sleep is up */ |
266 if (channel->type->checkclose) { | 259 if (channel->type->check_close) { |
267 if (channel->type->checkclose(channel)) { | 260 if (channel->type->check_close(channel)) { |
268 closewritefd(channel); | 261 close_write_fd(channel); |
269 closereadfd(channel, channel->readfd); | 262 close_read_fd(channel, channel->readfd); |
270 closereadfd(channel, channel->errfd); | 263 close_read_fd(channel, channel->errfd); |
271 } | 264 } |
272 } | 265 } |
273 | 266 |
274 if (!channel->senteof | 267 if (!channel->sent_eof |
275 && channel->readfd == FD_CLOSED | 268 && channel->readfd == FD_CLOSED |
276 && (channel->extrabuf != NULL || channel->errfd == FD_CLOSED)) { | 269 && (channel->extrabuf != NULL || channel->errfd == FD_CLOSED)) { |
277 send_msg_channel_eof(channel); | 270 send_msg_channel_eof(channel); |
278 } | 271 } |
279 | 272 |
280 if (!channel->sentclosed | 273 if (!channel->sent_close |
281 && channel->writefd == FD_CLOSED | 274 && channel->writefd == FD_CLOSED |
282 && channel->readfd == FD_CLOSED | 275 && channel->readfd == FD_CLOSED |
283 && (channel->extrabuf != NULL || channel->errfd == FD_CLOSED)) { | 276 && (channel->extrabuf != NULL || channel->errfd == FD_CLOSED)) { |
284 send_msg_channel_close(channel); | 277 send_msg_channel_close(channel); |
285 } | 278 } |
292 * the party may then reuse the channel number. A party MAY send | 285 * the party may then reuse the channel number. A party MAY send |
293 * SSH_MSG_CHANNEL_CLOSE without having sent or received | 286 * SSH_MSG_CHANNEL_CLOSE without having sent or received |
294 * SSH_MSG_CHANNEL_EOF. | 287 * SSH_MSG_CHANNEL_EOF. |
295 * (from draft-ietf-secsh-connect) | 288 * (from draft-ietf-secsh-connect) |
296 */ | 289 */ |
297 if (channel->recvclosed) { | 290 if (channel->recv_close) { |
298 if (! channel->sentclosed) { | 291 if (! channel->sent_close) { |
299 TRACE(("Sending MSG_CHANNEL_CLOSE in response to same.")) | 292 TRACE(("Sending MSG_CHANNEL_CLOSE in response to same.")) |
300 send_msg_channel_close(channel); | 293 send_msg_channel_close(channel); |
301 } | 294 } |
302 removechannel(channel); | 295 remove_channel(channel); |
303 } | 296 } |
304 } | 297 } |
305 | 298 |
306 | 299 |
307 /* Check whether a deferred (EINPROGRESS) connect() was successful, and | 300 /* Check whether a deferred (EINPROGRESS) connect() was successful, and |
308 * if so, set up the channel properly. Otherwise, the channel is cleaned up, so | 301 * if so, set up the channel properly. Otherwise, the channel is cleaned up, so |
309 * it is important that the channel reference isn't used after a call to this | 302 * it is important that the channel reference isn't used after a call to this |
310 * function */ | 303 * function */ |
311 static void checkinitdone(struct Channel *channel) { | 304 static void check_in_progress(struct Channel *channel) { |
312 | 305 |
313 int val; | 306 int val; |
314 socklen_t vallen = sizeof(val); | 307 socklen_t vallen = sizeof(val); |
315 | 308 |
316 TRACE(("enter checkinitdone")) | 309 TRACE(("enter check_in_progress")) |
317 | 310 |
318 if (getsockopt(channel->writefd, SOL_SOCKET, SO_ERROR, &val, &vallen) | 311 if (getsockopt(channel->writefd, SOL_SOCKET, SO_ERROR, &val, &vallen) |
319 || val != 0) { | 312 || val != 0) { |
320 send_msg_channel_open_failure(channel->remotechan, | 313 send_msg_channel_open_failure(channel->remotechan, |
321 SSH_OPEN_CONNECT_FAILED, "", ""); | 314 SSH_OPEN_CONNECT_FAILED, "", ""); |
322 close(channel->writefd); | 315 close(channel->writefd); |
323 deletechannel(channel); | 316 delete_channel(channel); |
324 TRACE(("leave checkinitdone: fail")) | 317 TRACE(("leave check_in_progress: fail")) |
325 } else { | 318 } else { |
326 send_msg_channel_open_confirmation(channel, channel->recvwindow, | 319 send_msg_channel_open_confirmation(channel, channel->recvwindow, |
327 channel->recvmaxpacket); | 320 channel->recvmaxpacket); |
328 channel->readfd = channel->writefd; | 321 channel->readfd = channel->writefd; |
329 channel->initconn = 0; | 322 channel->initconn = 0; |
330 TRACE(("leave checkinitdone: success")) | 323 TRACE(("leave check_in_progress: success")) |
331 } | 324 } |
332 } | 325 } |
333 | 326 |
334 | 327 |
335 | 328 |
336 /* Send the close message and set the channel as closed */ | 329 /* Send the close message and set the channel as closed */ |
337 static void send_msg_channel_close(struct Channel *channel) { | 330 static void send_msg_channel_close(struct Channel *channel) { |
338 | 331 |
339 TRACE(("enter send_msg_channel_close")) | 332 TRACE(("enter send_msg_channel_close")) |
340 /* XXX server */ | |
341 if (channel->type->closehandler) { | 333 if (channel->type->closehandler) { |
342 channel->type->closehandler(channel); | 334 channel->type->closehandler(channel); |
343 } | 335 } |
344 | 336 |
345 CHECKCLEARTOWRITE(); | 337 CHECKCLEARTOWRITE(); |
347 buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_CLOSE); | 339 buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_CLOSE); |
348 buf_putint(ses.writepayload, channel->remotechan); | 340 buf_putint(ses.writepayload, channel->remotechan); |
349 | 341 |
350 encrypt_packet(); | 342 encrypt_packet(); |
351 | 343 |
352 channel->senteof = 1; | 344 channel->sent_eof = 1; |
353 channel->sentclosed = 1; | 345 channel->sent_close = 1; |
354 TRACE(("leave send_msg_channel_close")) | 346 TRACE(("leave send_msg_channel_close")) |
355 } | 347 } |
356 | 348 |
357 /* call this when trans/eof channels are closed */ | 349 /* call this when trans/eof channels are closed */ |
358 static void send_msg_channel_eof(struct Channel *channel) { | 350 static void send_msg_channel_eof(struct Channel *channel) { |
363 buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_EOF); | 355 buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_EOF); |
364 buf_putint(ses.writepayload, channel->remotechan); | 356 buf_putint(ses.writepayload, channel->remotechan); |
365 | 357 |
366 encrypt_packet(); | 358 encrypt_packet(); |
367 | 359 |
368 channel->senteof = 1; | 360 channel->sent_eof = 1; |
369 | 361 |
370 TRACE(("leave send_msg_channel_eof")) | 362 TRACE(("leave send_msg_channel_eof")) |
371 } | 363 } |
372 | 364 |
373 /* Called to write data out to the local side of the channel. | 365 /* Called to write data out to the local side of the channel. |
385 len = write(fd, cbuf_readptr(cbuf, maxlen), maxlen); | 377 len = write(fd, cbuf_readptr(cbuf, maxlen), maxlen); |
386 if (len <= 0) { | 378 if (len <= 0) { |
387 if (len < 0 && errno != EINTR) { | 379 if (len < 0 && errno != EINTR) { |
388 /* no more to write - we close it even if the fd was stderr, since | 380 /* no more to write - we close it even if the fd was stderr, since |
389 * that's a nasty failure too */ | 381 * that's a nasty failure too */ |
390 closewritefd(channel); | 382 close_write_fd(channel); |
391 } | 383 } |
392 TRACE(("leave writechannel: len <= 0")) | 384 TRACE(("leave writechannel: len <= 0")) |
393 return; | 385 return; |
394 } | 386 } |
395 | 387 |
396 cbuf_incrread(cbuf, len); | 388 cbuf_incrread(cbuf, len); |
397 channel->recvdonelen += len; | 389 channel->recvdonelen += len; |
398 | 390 |
399 if (fd == channel->writefd && cbuf_getused(cbuf) == 0 && channel->recveof) { | 391 if (fd == channel->writefd && cbuf_getused(cbuf) == 0 && channel->recv_eof) { |
400 /* Check if we're closing up */ | 392 /* Check if we're closing up */ |
401 closewritefd(channel); | 393 close_write_fd(channel); |
402 TRACE(("leave writechannel: recveof set")) | 394 TRACE(("leave writechannel: recv_eof set")) |
403 return; | 395 return; |
404 } | 396 } |
405 | 397 |
406 /* Window adjust handling */ | 398 /* Window adjust handling */ |
407 if (channel->recvdonelen >= RECV_WINDOWEXTEND) { | 399 if (channel->recvdonelen >= RECV_WINDOWEXTEND) { |
444 if (channel->extrabuf == NULL && channel->errfd >= 0) { | 436 if (channel->extrabuf == NULL && channel->errfd >= 0) { |
445 FD_SET(channel->errfd, readfds); | 437 FD_SET(channel->errfd, readfds); |
446 } | 438 } |
447 } | 439 } |
448 | 440 |
449 TRACE(("writefd = %d, readfd %d, errfd %d, bufused %d", | |
450 channel->writefd, channel->readfd, | |
451 channel->errfd, | |
452 cbuf_getused(channel->writebuf) )) | |
453 | |
454 /* For checking FD status (ie closure etc) - we don't actually | |
455 * read data from writefd. We don't want to do this for the client, | |
456 * since redirection to /dev/null will make it spin in the select */ | |
457 if (IS_DROPBEAR_SERVER && channel->writefd >= 0 | |
458 && channel->writefd != channel->readfd) { | |
459 FD_SET(channel->writefd, readfds); | |
460 } | |
461 | |
462 /* Stuff from the wire */ | 441 /* Stuff from the wire */ |
463 if ((channel->writefd >= 0 && cbuf_getused(channel->writebuf) > 0 ) | 442 if ((channel->writefd >= 0 && cbuf_getused(channel->writebuf) > 0 ) |
464 || channel->initconn) { | 443 || channel->initconn) { |
465 FD_SET(channel->writefd, writefds); | 444 FD_SET(channel->writefd, writefds); |
466 } | 445 } |
490 channel = getchannel(); | 469 channel = getchannel(); |
491 if (channel == NULL) { | 470 if (channel == NULL) { |
492 dropbear_exit("EOF for unknown channel"); | 471 dropbear_exit("EOF for unknown channel"); |
493 } | 472 } |
494 | 473 |
495 channel->recveof = 1; | 474 channel->recv_eof = 1; |
496 if (cbuf_getused(channel->writebuf) == 0 | 475 if (cbuf_getused(channel->writebuf) == 0 |
497 && (channel->extrabuf == NULL | 476 && (channel->extrabuf == NULL |
498 || cbuf_getused(channel->extrabuf) == 0)) { | 477 || cbuf_getused(channel->extrabuf) == 0)) { |
499 closewritefd(channel); | 478 close_write_fd(channel); |
500 } | 479 } |
501 | 480 |
502 TRACE(("leave recv_msg_channel_eof")) | 481 TRACE(("leave recv_msg_channel_eof")) |
503 } | 482 } |
504 | 483 |
514 if (channel == NULL) { | 493 if (channel == NULL) { |
515 /* disconnect ? */ | 494 /* disconnect ? */ |
516 dropbear_exit("Close for unknown channel"); | 495 dropbear_exit("Close for unknown channel"); |
517 } | 496 } |
518 | 497 |
519 channel->recveof = 1; | 498 channel->recv_eof = 1; |
520 channel->recvclosed = 1; | 499 channel->recv_close = 1; |
521 | 500 |
522 if (channel->sentclosed) { | 501 if (channel->sent_close) { |
523 removechannel(channel); | 502 remove_channel(channel); |
524 } | 503 } |
525 | 504 |
526 TRACE(("leave recv_msg_channel_close")) | 505 TRACE(("leave recv_msg_channel_close")) |
527 } | 506 } |
528 | 507 |
529 /* Remove a channel entry, this is only executed after both sides have sent | 508 /* Remove a channel entry, this is only executed after both sides have sent |
530 * channel close */ | 509 * channel close */ |
531 static void removechannel(struct Channel * channel) { | 510 static void remove_channel(struct Channel * channel) { |
532 | 511 |
533 TRACE(("enter removechannel")) | 512 TRACE(("enter remove_channel")) |
534 TRACE(("channel index is %d", channel->index)) | 513 TRACE(("channel index is %d", channel->index)) |
535 | 514 |
536 cbuf_free(channel->writebuf); | 515 cbuf_free(channel->writebuf); |
537 channel->writebuf = NULL; | 516 channel->writebuf = NULL; |
538 | 517 |
548 close(channel->readfd); | 527 close(channel->readfd); |
549 close(channel->errfd); | 528 close(channel->errfd); |
550 | 529 |
551 channel->typedata = NULL; | 530 channel->typedata = NULL; |
552 | 531 |
553 deletechannel(channel); | 532 delete_channel(channel); |
554 | 533 |
555 TRACE(("leave removechannel")) | 534 TRACE(("leave remove_channel")) |
556 } | 535 } |
557 | 536 |
558 /* Remove a channel entry */ | 537 /* Remove a channel entry */ |
559 static void deletechannel(struct Channel *channel) { | 538 static void delete_channel(struct Channel *channel) { |
560 | 539 |
561 ses.channels[channel->index] = NULL; | 540 ses.channels[channel->index] = NULL; |
562 m_free(channel); | 541 m_free(channel); |
563 ses.chancount--; | 542 ses.chancount--; |
564 | 543 |
605 /* TRACE(("enter send_msg_channel_data")) | 584 /* TRACE(("enter send_msg_channel_data")) |
606 TRACE(("extended = %d type = %d", isextended, exttype))*/ | 585 TRACE(("extended = %d type = %d", isextended, exttype))*/ |
607 | 586 |
608 CHECKCLEARTOWRITE(); | 587 CHECKCLEARTOWRITE(); |
609 | 588 |
610 dropbear_assert(!channel->sentclosed); | 589 dropbear_assert(!channel->sent_close); |
611 | 590 |
612 if (isextended) { | 591 if (isextended) { |
613 fd = channel->errfd; | 592 fd = channel->errfd; |
614 } else { | 593 } else { |
615 fd = channel->readfd; | 594 fd = channel->readfd; |
632 TRACE(("buf pos %d data %x", buf->pos, buf->data)) | 611 TRACE(("buf pos %d data %x", buf->pos, buf->data)) |
633 len = read(fd, buf_getwriteptr(buf, maxlen), maxlen); | 612 len = read(fd, buf_getwriteptr(buf, maxlen), maxlen); |
634 if (len <= 0) { | 613 if (len <= 0) { |
635 /* on error/eof, send eof */ | 614 /* on error/eof, send eof */ |
636 if (len == 0 || errno != EINTR) { | 615 if (len == 0 || errno != EINTR) { |
637 closereadfd(channel, fd); | 616 close_read_fd(channel, fd); |
638 } | 617 } |
639 buf_free(buf); | 618 buf_free(buf); |
640 buf = NULL; | 619 buf = NULL; |
641 TRACE(("leave send_msg_channel_data: read err or EOF for fd %d", | 620 TRACE(("leave send_msg_channel_data: read err or EOF for fd %d", |
642 channel->index)); | 621 channel->index)); |
685 unsigned int buflen; | 664 unsigned int buflen; |
686 unsigned int len; | 665 unsigned int len; |
687 | 666 |
688 TRACE(("enter recv_msg_channel_data")) | 667 TRACE(("enter recv_msg_channel_data")) |
689 | 668 |
690 if (channel->recveof) { | 669 if (channel->recv_eof) { |
691 dropbear_exit("received data after eof"); | 670 dropbear_exit("received data after eof"); |
692 } | 671 } |
693 | 672 |
673 /* XXX this is getting hit by people - maybe should be | |
674 * made less fatal (or just fixed). | |
675 * | |
676 * The most likely explanation is that the socket is being closed (due to | |
677 * write failure etc) but the far end doesn't know yet, so keeps sending | |
678 * packets. We already know that the channel number that was given was | |
679 * valid, so probably should skip out here. Maybe | |
680 * assert(channel->sent_close), thuogh only if the close-on-failure code is | |
681 * doing that */ | |
694 if (fd < 0) { | 682 if (fd < 0) { |
695 dropbear_exit("received data with bad writefd"); | 683 dropbear_exit("received data with bad writefd"); |
696 } | 684 } |
697 | 685 |
698 datalen = buf_getint(ses.payload); | 686 datalen = buf_getint(ses.payload); |
765 | 753 |
766 encrypt_packet(); | 754 encrypt_packet(); |
767 } | 755 } |
768 | 756 |
769 /* Handle a new channel request, performing any channel-type-specific setup */ | 757 /* Handle a new channel request, performing any channel-type-specific setup */ |
770 /* XXX server */ | |
771 void recv_msg_channel_open() { | 758 void recv_msg_channel_open() { |
772 | 759 |
773 unsigned char *type; | 760 unsigned char *type; |
774 unsigned int typelen; | 761 unsigned int typelen; |
775 unsigned int remotechan, transwindow, transmaxpacket; | 762 unsigned int remotechan, transwindow, transmaxpacket; |
828 if (ret == SSH_OPEN_IN_PROGRESS) { | 815 if (ret == SSH_OPEN_IN_PROGRESS) { |
829 /* We'll send the confirmation later */ | 816 /* We'll send the confirmation later */ |
830 goto cleanup; | 817 goto cleanup; |
831 } | 818 } |
832 errtype = ret; | 819 errtype = ret; |
833 deletechannel(channel); | 820 delete_channel(channel); |
834 TRACE(("inithandler returned failure %d", ret)) | 821 TRACE(("inithandler returned failure %d", ret)) |
835 goto failure; | 822 goto failure; |
836 } | 823 } |
837 } | 824 } |
838 | 825 |
980 | 967 |
981 /* Run the inithandler callback */ | 968 /* Run the inithandler callback */ |
982 if (channel->type->inithandler) { | 969 if (channel->type->inithandler) { |
983 ret = channel->type->inithandler(channel); | 970 ret = channel->type->inithandler(channel); |
984 if (ret > 0) { | 971 if (ret > 0) { |
985 removechannel(channel); | 972 remove_channel(channel); |
986 TRACE(("inithandler returned failure %d", ret)) | 973 TRACE(("inithandler returned failure %d", ret)) |
987 } | 974 } |
988 } | 975 } |
989 | 976 |
990 | 977 |
1004 if (!channel->await_open) { | 991 if (!channel->await_open) { |
1005 dropbear_exit("unexpected channel reply"); | 992 dropbear_exit("unexpected channel reply"); |
1006 } | 993 } |
1007 channel->await_open = 0; | 994 channel->await_open = 0; |
1008 | 995 |
1009 removechannel(channel); | 996 remove_channel(channel); |
1010 } | 997 } |
1011 #endif /* USING_LISTENERS */ | 998 #endif /* USING_LISTENERS */ |
1012 | 999 |
1013 /* close a stdout/stderr fd */ | 1000 /* close a stdout/stderr fd */ |
1014 static void closereadfd(struct Channel * channel, int fd) { | 1001 static void close_read_fd(struct Channel * channel, int fd) { |
1015 | 1002 |
1016 /* don't close it if it is the same as writefd, | 1003 /* don't close it if it is the same as writefd, |
1017 * unless writefd is already set -1 */ | 1004 * unless writefd is already set -1 */ |
1018 TRACE(("enter closereadfd")) | 1005 TRACE(("enter close_read_fd")) |
1019 closechanfd(channel, fd, 0); | 1006 close_chan_fd(channel, fd, 0); |
1020 TRACE(("leave closereadfd")) | 1007 TRACE(("leave close_read_fd")) |
1021 } | 1008 } |
1022 | 1009 |
1023 /* close a stdin fd */ | 1010 /* close a stdin fd */ |
1024 static void closewritefd(struct Channel * channel) { | 1011 static void close_write_fd(struct Channel * channel) { |
1025 | 1012 |
1026 TRACE(("enter closewritefd")) | 1013 TRACE(("enter close_write_fd")) |
1027 closechanfd(channel, channel->writefd, 1); | 1014 close_chan_fd(channel, channel->writefd, 1); |
1028 TRACE(("leave closewritefd")) | 1015 TRACE(("leave close_write_fd")) |
1029 } | 1016 } |
1030 | 1017 |
1031 /* close a fd, how is 0 for stdout/stderr, 1 for stdin */ | 1018 /* close a fd, how is 0 for stdout/stderr, 1 for stdin */ |
1032 static void closechanfd(struct Channel *channel, int fd, int how) { | 1019 static void close_chan_fd(struct Channel *channel, int fd, int how) { |
1033 | 1020 |
1034 int closein = 0, closeout = 0; | 1021 int closein = 0, closeout = 0; |
1035 | 1022 |
1036 /* XXX server */ | |
1037 if (channel->type->sepfds) { | 1023 if (channel->type->sepfds) { |
1038 TRACE(("shutdown((%d), %d)", fd, how)) | 1024 TRACE(("shutdown((%d), %d)", fd, how)) |
1039 shutdown(fd, how); | 1025 shutdown(fd, how); |
1040 if (how == 0) { | 1026 if (how == 0) { |
1041 closeout = 1; | 1027 closeout = 1; |