*/
#include "includes.h"
-RCSID("$OpenBSD: channels.c,v 1.219 2005/07/04 00:58:42 djm Exp $");
+RCSID("$OpenBSD: channels.c,v 1.227 2005/10/14 02:29:37 stevesk Exp $");
#include "ssh.h"
#include "ssh1.h"
c->force_drain = 0;
c->single_connection = 0;
c->detach_user = NULL;
+ c->detach_close = 0;
c->confirm = NULL;
c->confirm_ctx = NULL;
c->input_filter = NULL;
c->confirm_ctx = ctx;
}
void
-channel_register_cleanup(int id, channel_callback_fn *fn)
+channel_register_cleanup(int id, channel_callback_fn *fn, int do_close)
{
Channel *c = channel_lookup(id);
return;
}
c->detach_user = fn;
+ c->detach_close = do_close;
}
void
channel_cancel_cleanup(int id)
return;
}
c->detach_user = NULL;
+ c->detach_close = 0;
}
void
channel_register_filter(int id, channel_filter_fn *fn)
FD_SET(c->wfd, writeset);
} else if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN) {
if (CHANNEL_EFD_OUTPUT_ACTIVE(c))
- debug2("channel %d: obuf_empty delayed efd %d/(%d)",
- c->self, c->efd, buffer_len(&c->extended));
+ debug2("channel %d: obuf_empty delayed efd %d/(%d)",
+ c->self, c->efd, buffer_len(&c->extended));
else
chan_obuf_empty(c);
}
xfree(remote_ipaddr);
}
+static void
+channel_set_reuseaddr(int fd)
+{
+ int on = 1;
+
+ /*
+ * Set socket options.
+ * Allow local port reuse in TIME_WAIT.
+ */
+ if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1)
+ error("setsockopt SO_REUSEADDR fd %d: %s", fd, strerror(errno));
+}
+
/*
* This socket is listening for connections to a forwarded TCP/IP port.
*/
if (c == NULL)
return;
if (c->detach_user != NULL) {
- if (!chan_is_dead(c, 0))
+ if (!chan_is_dead(c, c->detach_close))
return;
debug2("channel %d: gc: notify user", c->self);
c->detach_user(c->self, NULL);
* hack for extended data: delay EOF if EFD still in use.
*/
if (CHANNEL_EFD_INPUT_ACTIVE(c))
- debug2("channel %d: ibuf_empty delayed efd %d/(%d)",
- c->self, c->efd, buffer_len(&c->extended));
+ debug2("channel %d: ibuf_empty delayed efd %d/(%d)",
+ c->self, c->efd, buffer_len(&c->extended));
else
chan_ibuf_empty(c);
}
const char *host_to_connect, u_short port_to_connect, int gateway_ports)
{
Channel *c;
- int sock, r, success = 0, on = 1, wildcard = 0, is_client;
+ int sock, r, success = 0, wildcard = 0, is_client;
struct addrinfo hints, *ai, *aitop;
const char *host, *addr;
char ntop[NI_MAXHOST], strport[NI_MAXSERV];
verbose("socket: %.100s", strerror(errno));
continue;
}
- /*
- * Set socket options.
- * Allow local port reuse in TIME_WAIT.
- */
- if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on,
- sizeof(on)) == -1)
- error("setsockopt SO_REUSEADDR: %s", strerror(errno));
+
+ channel_set_reuseaddr(sock);
debug("Local forwarding listening on %s port %s.", ntop, strport);
permitted_opens[i].listen_port = 0;
permitted_opens[i].port_to_connect = 0;
- free(permitted_opens[i].host_to_connect);
+ xfree(permitted_opens[i].host_to_connect);
permitted_opens[i].host_to_connect = NULL;
}
*/
int
x11_create_display_inet(int x11_display_offset, int x11_use_localhost,
- int single_connection, u_int *display_numberp)
+ int single_connection, u_int *display_numberp, int **chanids)
{
Channel *nc = NULL;
int display_number, sock;
char strport[NI_MAXSERV];
int gaierr, n, num_socks = 0, socks[NUM_SOCKS];
+ if (chanids == NULL)
+ return -1;
+
for (display_number = x11_display_offset;
display_number < MAX_DISPLAYS;
display_number++) {
error("setsockopt IPV6_V6ONLY: %.100s", strerror(errno));
}
#endif
+ channel_set_reuseaddr(sock);
if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) {
debug2("bind port %d: %.100s", port, strerror(errno));
close(sock);
}
/* Allocate a channel for each socket. */
+ *chanids = xmalloc(sizeof(**chanids) * (num_socks + 1));
for (n = 0; n < num_socks; n++) {
sock = socks[n];
nc = channel_new("x11 listener",
CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT,
0, "X11 inet listener", 1);
nc->single_connection = single_connection;
+ (*chanids)[n] = nc->self;
}
+ (*chanids)[n] = -1;
/* Return the display number for the DISPLAY environment variable. */
*display_numberp = display_number;
const char *cp;
u_int32_t rnd = 0;
- if (x11_saved_display && strcmp(disp, x11_saved_display) != 0) {
+ if (x11_saved_display == NULL)
+ x11_saved_display = xstrdup(disp);
+ else if (strcmp(disp, x11_saved_display) != 0) {
error("x11_request_forwarding_with_spoofing: different "
"$DISPLAY already forwarded");
return;
/* Save protocol name. */
x11_saved_proto = xstrdup(proto);
/*
- * Extract real authentication data and generate fake data
+ * Extract real authentication data and generate fake data
* of the same length.
*/
x11_saved_data = xmalloc(data_len);