tmate-io_tmate-ssh-server/tmate-ssh-daemon.c
2016-02-28 13:47:05 -05:00

91 lines
2.3 KiB
C

#include "tmate.h"
#include <errno.h>
static void on_latency_callback(void *userdata, int latency_ms)
{
struct tmate_session *session = userdata;
tmate_notify_latency(session, NULL, latency_ms);
}
static void on_daemon_decoder_read(void *userdata, struct tmate_unpacker *uk)
{
struct tmate_session *session = userdata;
tmate_send_proxy_daemon_msg(session, uk);
tmate_dispatch_daemon_message(session, uk);
}
static int on_ssh_channel_read(__unused ssh_session _session,
__unused ssh_channel channel,
void *_data, uint32_t total_len,
__unused int is_stderr, void *userdata)
{
struct tmate_session *session = userdata;
char *data = _data;
size_t written = 0;
char *buf;
size_t len;
while (total_len) {
tmate_decoder_get_buffer(&session->daemon_decoder, &buf, &len);
if (len == 0)
tmate_fatal("No more room in client decoder. Message too big?");
if (len > total_len)
len = total_len;
memcpy(buf, data, len);
tmate_decoder_commit(&session->daemon_decoder, len);
total_len -= len;
written += len;
data += len;
}
return written;
}
static void on_daemon_encoder_write(void *userdata, struct evbuffer *buffer)
{
struct tmate_session *session = userdata;
ssize_t len, written;
unsigned char *buf;
for(;;) {
len = evbuffer_get_length(buffer);
if (!len)
break;
buf = evbuffer_pullup(buffer, -1);
written = ssh_channel_write(session->ssh_client.channel, buf, len);
if (written < 0) {
tmate_warn("Error writing to channel: %s",
ssh_get_error(session->ssh_client.session));
request_server_termination();
break;
}
evbuffer_drain(buffer, written);
}
}
void tmate_daemon_init(struct tmate_session *session)
{
struct tmate_ssh_client *client = &session->ssh_client;
memset(&client->channel_cb, 0, sizeof(client->channel_cb));
ssh_callbacks_init(&client->channel_cb);
client->channel_cb.userdata = session;
client->channel_cb.channel_data_function = on_ssh_channel_read,
ssh_set_channel_callbacks(client->channel, &client->channel_cb);
tmate_encoder_init(&session->daemon_encoder, on_daemon_encoder_write, session);
tmate_decoder_init(&session->daemon_decoder, on_daemon_decoder_read, session);
tmate_init_proxy(session, NULL);
tmate_add_ssh_latency_callback(client, on_latency_callback, session);
}