*/
#include "includes.h"
-RCSID("$OpenBSD: channels.c,v 1.180 2002/07/04 08:12:15 deraadt Exp $");
+RCSID("$OpenBSD: channels.c,v 1.187 2003/03/05 22:33:43 markus Exp $");
#include "ssh.h"
#include "ssh1.h"
Channel *c;
if (id < 0 || id >= channels_alloc) {
- log("channel_lookup: %d: bad id", id);
+ logit("channel_lookup: %d: bad id", id);
return NULL;
}
c = channels[id];
if (c == NULL) {
- log("channel_lookup: %d: bad id: channel free", id);
+ logit("channel_lookup: %d: bad id: channel free", id);
return NULL;
}
return c;
} else {
c->isatty = 0;
}
+ c->wfd_isatty = isatty(c->wfd);
/* enable nonblocking mode */
if (nonblock) {
#if 0
if (!compat20 &&
buffer_len(&c->input) > packet_get_maxsize()) {
- debug("channel %d: big input buffer %d",
+ debug2("channel %d: big input buffer %d",
c->self, buffer_len(&c->input));
return 0;
}
#endif
if (buffer_len(&c->output) > packet_get_maxsize()) {
- debug("channel %d: big output buffer %d > %d",
+ debug2("channel %d: big output buffer %d > %d",
c->self, buffer_len(&c->output),
packet_get_maxsize());
return 0;
Channel *c = channel_lookup(id);
if (c == NULL) {
- log("channel_send_open: %d: bad id", id);
+ logit("channel_send_open: %d: bad id", id);
return;
}
- debug("send channel open %d", id);
+ debug2("channel %d: send open", id);
packet_start(SSH2_MSG_CHANNEL_OPEN);
packet_put_cstring(c->ctype);
packet_put_int(c->self);
}
void
-channel_request_start(int local_id, char *service, int wantconfirm)
+channel_request_start(int id, char *service, int wantconfirm)
{
- Channel *c = channel_lookup(local_id);
+ Channel *c = channel_lookup(id);
if (c == NULL) {
- log("channel_request_start: %d: unknown channel id", local_id);
+ logit("channel_request_start: %d: unknown channel id", id);
return;
}
- debug("channel request %d: %s", local_id, service) ;
+ debug("channel %d: request %s", id, service) ;
packet_start(SSH2_MSG_CHANNEL_REQUEST);
packet_put_int(c->remote_id);
packet_put_cstring(service);
Channel *c = channel_lookup(id);
if (c == NULL) {
- log("channel_register_comfirm: %d: bad id", id);
+ logit("channel_register_comfirm: %d: bad id", id);
return;
}
c->confirm = fn;
Channel *c = channel_lookup(id);
if (c == NULL) {
- log("channel_register_cleanup: %d: bad id", id);
+ logit("channel_register_cleanup: %d: bad id", id);
return;
}
c->detach_user = fn;
Channel *c = channel_lookup(id);
if (c == NULL) {
- log("channel_cancel_cleanup: %d: bad id", id);
+ logit("channel_cancel_cleanup: %d: bad id", id);
return;
}
c->detach_user = NULL;
Channel *c = channel_lookup(id);
if (c == NULL) {
- log("channel_register_filter: %d: bad id", id);
+ logit("channel_register_filter: %d: bad id", id);
return;
}
c->input_filter = fn;
* We have received an X11 connection that has bad
* authentication information.
*/
- log("X11 connection rejected because of wrong authentication.");
+ logit("X11 connection rejected because of wrong authentication.");
buffer_clear(&c->input);
buffer_clear(&c->output);
channel_close_fd(&c->sock);
c->type = SSH_CHANNEL_OPEN;
channel_pre_open(c, readset, writeset);
} else if (ret == -1) {
- log("X11 connection rejected because of wrong authentication.");
+ logit("X11 connection rejected because of wrong authentication.");
debug("X11 rejected %d i%d/o%d", c->self, c->istate, c->ostate);
chan_read_failed(c);
buffer_clear(&c->input);
static int
channel_decode_socks4(Channel *c, fd_set * readset, fd_set * writeset)
{
- u_char *p, *host;
+ char *p, *host;
int len, have, i, found;
char username[256];
struct {
buffer_len(&c->output) > 0) {
data = buffer_ptr(&c->output);
dlen = buffer_len(&c->output);
- len = write(c->wfd, data, dlen);
#ifdef _AIX
/* XXX: Later AIX versions can't push as much data to tty */
- if (compat20 && c->isatty && dlen >= 8*1024)
+ if (compat20 && c->wfd_isatty && dlen > 8*1024)
dlen = 8*1024;
#endif
+ len = write(c->wfd, data, dlen);
if (len < 0 && (errno == EINTR || errno == EAGAIN))
return 1;
if (len <= 0) {
if (compat20) {
if (data_len > c->local_maxpacket) {
- log("channel %d: rcvd big packet %d, maxpack %d",
+ logit("channel %d: rcvd big packet %d, maxpack %d",
c->self, data_len, c->local_maxpacket);
}
if (data_len > c->local_window) {
- log("channel %d: rcvd too much data %d, win %d",
+ logit("channel %d: rcvd too much data %d, win %d",
c->self, data_len, c->local_window);
xfree(data);
return;
if (c == NULL)
packet_disconnect("Received extended_data for bad channel %d.", id);
if (c->type != SSH_CHANNEL_OPEN) {
- log("channel %d: ext data for non open", id);
+ logit("channel %d: ext data for non open", id);
return;
}
if (c->flags & CHAN_EOF_RCVD) {
if (c->efd == -1 ||
c->extended_usage != CHAN_EXTENDED_WRITE ||
tcode != SSH2_EXTENDED_DATA_STDERR) {
- log("channel %d: bad ext data", c->self);
+ logit("channel %d: bad ext data", c->self);
return;
}
data = packet_get_string(&data_len);
packet_check_eom();
if (data_len > c->local_window) {
- log("channel %d: rcvd too much extended_data %d, win %d",
+ logit("channel %d: rcvd too much extended_data %d, win %d",
c->self, data_len, c->local_window);
xfree(data);
return;
msg = packet_get_string(NULL);
lang = packet_get_string(NULL);
}
- log("channel %d: open failed: %s%s%s", id,
+ logit("channel %d: open failed: %s%s%s", id,
reason2txt(reason), msg ? ": ": "", msg ? msg : "");
if (msg != NULL)
xfree(msg);
c = channel_lookup(id);
if (c == NULL || c->type != SSH_CHANNEL_OPEN) {
- log("Received window adjust for "
+ logit("Received window adjust for "
"non-open channel %d.", id);
return;
}
c->remote_id = remote_id;
}
if (c == NULL) {
+ xfree(originator_string);
packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
packet_put_int(remote_id);
packet_send();
struct addrinfo hints, *ai, *aitop;
const char *host;
char ntop[NI_MAXHOST], strport[NI_MAXSERV];
- struct linger linger;
success = 0;
host = (type == SSH_CHANNEL_RPORT_LISTENER) ?
continue;
}
/*
- * Set socket options. We would like the socket to disappear
- * as soon as it has been closed for whatever reason.
+ * Set socket options.
+ * Allow local port reuse in TIME_WAIT.
*/
- setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
- linger.l_onoff = 1;
- linger.l_linger = 5;
- setsockopt(sock, SOL_SOCKET, SO_LINGER, &linger, sizeof(linger));
+ if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on,
+ sizeof(on)) == -1)
+ error("setsockopt SO_REUSEADDR: %s", strerror(errno));
+
debug("Local forwarding listening on %s port %s.", ntop, strport);
/* Bind the socket to the address. */
success = 1;
break;
case SSH_SMSG_FAILURE:
- log("Warning: Server denied remote port forwarding.");
+ logit("Warning: Server denied remote port forwarding.");
break;
default:
/* Unknown packet */
}
sock = socket(ai->ai_family, SOCK_STREAM, 0);
if (sock < 0) {
- error("socket: %.100s", strerror(errno));
+ if (ai->ai_next == NULL)
+ error("socket: %.100s", strerror(errno));
+ else
+ verbose("socket: %.100s", strerror(errno));
continue;
}
if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0)
}
if (!permit) {
- log("Received request to connect to host %.100s port %d, "
+ logit("Received request to connect to host %.100s port %d, "
"but the request was denied.", host, port);
return -1;
}
/* Send refusal to the remote host. */
packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
packet_put_int(remote_id);
+ xfree(remote_host);
} else {
/* Send a confirmation to the remote host. */
packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION);