summaryrefslogtreecommitdiff
path: root/channels.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2005-12-31 16:22:32 +1100
committerDamien Miller <djm@mindrot.org>2005-12-31 16:22:32 +1100
commit077b23864f567551dc7147db8ccd69559617976e (patch)
tree0544f3e7e7b1f28d627272c760eb18d8dda9b75f /channels.c
parent5eb137c6d11be7db14dc03ea12a74884bebea3e3 (diff)
- reyk@cvs.openbsd.org 2005/12/30 15:56:37
[channels.c channels.h clientloop.c] add channel output filter interface. ok djm@, suggested by markus@
Diffstat (limited to 'channels.c')
-rw-r--r--channels.c35
1 files changed, 24 insertions, 11 deletions
diff --git a/channels.c b/channels.c
index b431532a3..ed5903f6f 100644
--- a/channels.c
+++ b/channels.c
@@ -39,7 +39,7 @@
39 */ 39 */
40 40
41#include "includes.h" 41#include "includes.h"
42RCSID("$OpenBSD: channels.c,v 1.230 2005/12/28 22:46:06 stevesk Exp $"); 42RCSID("$OpenBSD: channels.c,v 1.231 2005/12/30 15:56:36 reyk Exp $");
43 43
44#include "ssh.h" 44#include "ssh.h"
45#include "ssh1.h" 45#include "ssh1.h"
@@ -58,8 +58,6 @@ RCSID("$OpenBSD: channels.c,v 1.230 2005/12/28 22:46:06 stevesk Exp $");
58 58
59/* -- channel core */ 59/* -- channel core */
60 60
61#define CHAN_RBUF 16*1024
62
63/* 61/*
64 * Pointer to an array containing all allocated channels. The array is 62 * Pointer to an array containing all allocated channels. The array is
65 * dynamically extended as needed. 63 * dynamically extended as needed.
@@ -301,6 +299,7 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd,
301 c->confirm = NULL; 299 c->confirm = NULL;
302 c->confirm_ctx = NULL; 300 c->confirm_ctx = NULL;
303 c->input_filter = NULL; 301 c->input_filter = NULL;
302 c->output_filter = NULL;
304 debug("channel %d: new [%s]", found, remote_name); 303 debug("channel %d: new [%s]", found, remote_name);
305 return c; 304 return c;
306} 305}
@@ -681,7 +680,8 @@ channel_cancel_cleanup(int id)
681 c->detach_close = 0; 680 c->detach_close = 0;
682} 681}
683void 682void
684channel_register_filter(int id, channel_filter_fn *fn) 683channel_register_filter(int id, channel_infilter_fn *ifn,
684 channel_outfilter_fn *ofn)
685{ 685{
686 Channel *c = channel_lookup(id); 686 Channel *c = channel_lookup(id);
687 687
@@ -689,7 +689,8 @@ channel_register_filter(int id, channel_filter_fn *fn)
689 logit("channel_register_filter: %d: bad id", id); 689 logit("channel_register_filter: %d: bad id", id);
690 return; 690 return;
691 } 691 }
692 c->input_filter = fn; 692 c->input_filter = ifn;
693 c->output_filter = ofn;
693} 694}
694 695
695void 696void
@@ -1454,7 +1455,7 @@ static int
1454channel_handle_wfd(Channel *c, fd_set * readset, fd_set * writeset) 1455channel_handle_wfd(Channel *c, fd_set * readset, fd_set * writeset)
1455{ 1456{
1456 struct termios tio; 1457 struct termios tio;
1457 u_char *data; 1458 u_char *data = NULL, *buf;
1458 u_int dlen; 1459 u_int dlen;
1459 int len; 1460 int len;
1460 1461
@@ -1462,11 +1463,22 @@ channel_handle_wfd(Channel *c, fd_set * readset, fd_set * writeset)
1462 if (c->wfd != -1 && 1463 if (c->wfd != -1 &&
1463 FD_ISSET(c->wfd, writeset) && 1464 FD_ISSET(c->wfd, writeset) &&
1464 buffer_len(&c->output) > 0) { 1465 buffer_len(&c->output) > 0) {
1466 if (c->output_filter != NULL) {
1467 if ((buf = c->output_filter(c, &data, &dlen)) == NULL) {
1468 debug2("channel %d: filter stops", c->self);
1469 chan_read_failed(c);
1470 }
1471 } else if (c->datagram) {
1472 buf = data = buffer_get_string(&c->output, &dlen);
1473 } else {
1474 buf = data = buffer_ptr(&c->output);
1475 dlen = buffer_len(&c->output);
1476 }
1477
1465 if (c->datagram) { 1478 if (c->datagram) {
1466 data = buffer_get_string(&c->output, &dlen);
1467 /* ignore truncated writes, datagrams might get lost */ 1479 /* ignore truncated writes, datagrams might get lost */
1468 c->local_consumed += dlen + 4; 1480 c->local_consumed += dlen + 4;
1469 len = write(c->wfd, data, dlen); 1481 len = write(c->wfd, buf, dlen);
1470 xfree(data); 1482 xfree(data);
1471 if (len < 0 && (errno == EINTR || errno == EAGAIN)) 1483 if (len < 0 && (errno == EINTR || errno == EAGAIN))
1472 return 1; 1484 return 1;
@@ -1486,7 +1498,8 @@ channel_handle_wfd(Channel *c, fd_set * readset, fd_set * writeset)
1486 if (compat20 && c->wfd_isatty) 1498 if (compat20 && c->wfd_isatty)
1487 dlen = MIN(dlen, 8*1024); 1499 dlen = MIN(dlen, 8*1024);
1488#endif 1500#endif
1489 len = write(c->wfd, data, dlen); 1501
1502 len = write(c->wfd, buf, dlen);
1490 if (len < 0 && (errno == EINTR || errno == EAGAIN)) 1503 if (len < 0 && (errno == EINTR || errno == EAGAIN))
1491 return 1; 1504 return 1;
1492 if (len <= 0) { 1505 if (len <= 0) {
@@ -1503,14 +1516,14 @@ channel_handle_wfd(Channel *c, fd_set * readset, fd_set * writeset)
1503 } 1516 }
1504 return -1; 1517 return -1;
1505 } 1518 }
1506 if (compat20 && c->isatty && dlen >= 1 && data[0] != '\r') { 1519 if (compat20 && c->isatty && dlen >= 1 && buf[0] != '\r') {
1507 if (tcgetattr(c->wfd, &tio) == 0 && 1520 if (tcgetattr(c->wfd, &tio) == 0 &&
1508 !(tio.c_lflag & ECHO) && (tio.c_lflag & ICANON)) { 1521 !(tio.c_lflag & ECHO) && (tio.c_lflag & ICANON)) {
1509 /* 1522 /*
1510 * Simulate echo to reduce the impact of 1523 * Simulate echo to reduce the impact of
1511 * traffic analysis. We need to match the 1524 * traffic analysis. We need to match the
1512 * size of a SSH2_MSG_CHANNEL_DATA message 1525 * size of a SSH2_MSG_CHANNEL_DATA message
1513 * (4 byte channel id + data) 1526 * (4 byte channel id + buf)
1514 */ 1527 */
1515 packet_send_ignore(4 + len); 1528 packet_send_ignore(4 + len);
1516 packet_send(); 1529 packet_send();