static void getcapabilities_cb(Channel * c, void * x, int error) {
    Trap trap;
    PortConnection * conn = (PortConnection *)x;
    PortAttribute * attr = conn->server->redir_info->attrs;
    OutputStream * out = &conn->server->channel->out;

    if (set_trap(&trap)) {
        if (!error) {
            error = read_errno(&c->inp);
            json_read_struct(&c->inp, read_getcapabilities_struct, (void *)conn);
            json_test_char(&c->inp, MARKER_EOA);
            json_test_char(&c->inp, MARKER_EOM);
        }
        clear_trap(&trap);
    }
    else {
        error = trap.error;
    }
    if (error) {
        connect_port_callback(conn, error);
    } else {
        if (conn->auto_connect_stream) {
            conn->pending = protocol_send_command(conn->server->channel, "PortForward",
                    "create", portcreate_cb, conn);
            write_stream(out, '{');
            json_write_string(out, "ID");
            write_stream(out, ':');
            json_write_string(out, conn->id);
            while (attr != NULL) {
                write_stream(out, ',');
                if (strcmp(attr->name,  "RemotePort") == 0) {
                    json_write_string(out, "Port");
                }
                else {
                    json_write_string(out, attr->name);
                }
                write_stream(out, ':');
                write_string(out, attr->value);
                attr = attr->next;
            }
            if (conn->auto_connect_stream) {
                write_stream(out, ',');
                json_write_string(out, "AutoConnect");
                write_stream(out, ':');
                json_write_boolean(out, 1);
            }
            write_stream(out, '}');
            write_stream(out, MARKER_EOA);
            write_stream(out, MARKER_EOM);
        }
        else {
            conn->pending = protocol_send_command(conn->server->channel, "Streams", "subscribe",
                    subscribe_cb, conn);
            json_write_string(out, "PortForward");
            write_stream(out, MARKER_EOA);
            write_stream(out, MARKER_EOM);
        }
    }
}
static void delete_config_done(Channel *c, void *client_data, int error) {
    PortConnection * conn = (PortConnection *) client_data;
    Trap trap;

    if (set_trap(&trap)) {
        if (!error) {
            error = read_errno(&c->inp);
            json_test_char(&c->inp, MARKER_EOM);
        }
        clear_trap(&trap);
    }
    else {
        error = trap.error;
    }
    if (!conn->auto_connect_stream) {
        protocol_send_command(conn->server->channel, "Streams", "disconnect", disconnect_stream_done, conn);
        json_write_string(&conn->server->channel->out, conn->out_stream_id);
        write_stream(&conn->server->channel->out, MARKER_EOA);
        write_stream(&conn->server->channel->out, MARKER_EOM);
    }
    else {
        loc_free(conn->out_stream_id);
        conn->out_stream_id = NULL;
        loc_free(conn->in_stream_id);
        conn->in_stream_id = NULL;
        port_unlock(conn);
        port_connection_close(conn);
    }
}
static int send_packet(PortConnection * conn, char * buffer, size_t size) {
    JsonWriteBinaryState state;

    assert (is_dispatch_thread());
    assert (conn->pending_write_request < MAX_STREAM_WRITE);
    protocol_send_command(conn->server->channel, "Streams", "write", write_stream_done,
            conn);
    json_write_string(&conn->server->channel->out, conn->out_stream_id);
    write_stream(&conn->server->channel->out, 0);
    json_write_long(&conn->server->channel->out, size);
    write_stream(&conn->server->channel->out, MARKER_EOA);
    json_write_binary_start(&state, &conn->server->channel->out, size);
    json_write_binary_data(&state, buffer, size);
    json_write_binary_end(&state);
    write_stream(&conn->server->channel->out, MARKER_EOA);
    write_stream(&conn->server->channel->out, MARKER_EOM);
    conn->pending_write_request ++;
    if (conn->pending_write_request  == MAX_STREAM_WRITE) {
        return 0;
    }
    else {
        send_packet_callback(conn, 0);
    }
    return 0;
}
static void subscribe_cb(Channel * c, void * x, int error) {
    Trap trap;
    PortConnection * conn = (PortConnection *)x;
    PortAttribute * attr = conn->server->redir_info->attrs;
    OutputStream * out = &conn->server->channel->out;

    if (set_trap(&trap)) {
        if (!error) {
            error = read_errno(&c->inp);
            json_test_char(&c->inp, MARKER_EOM);
        }
        clear_trap(&trap);
    }
    else {
        error = trap.error;
    }
    /* Ignore error for subscribe since we may already have subscribed for this channel */

    conn->pending = protocol_send_command(conn->server->channel, "PortForward",
            "create", portcreate_cb, conn);
    write_stream(out, '{');
    json_write_string(out, "ID");
    write_stream(out, ':');
    json_write_string(out, conn->id);
    write_stream(out, ',');
    while (attr != NULL) {
        json_write_string(out, attr->name);
        write_stream(out, ':');
        write_string(out, attr->value);
        attr = attr->next;
    }
    write_stream(out, '}');
    write_stream(out, MARKER_EOA);
    write_stream(out, MARKER_EOM);
}
static void disconnect_port(PortConnection * conn) {
    assert (is_dispatch_thread());
    conn->shutdown_in_progress = 1;
    port_lock(conn);
    protocol_send_command(conn->server->channel, "PortForward", "delete",
            delete_config_done, conn);
    json_write_string(&conn->server->channel->out, conn->id);
    write_stream(&conn->server->channel->out, MARKER_EOA);
    write_stream(&conn->server->channel->out, MARKER_EOM);
}
Beispiel #6
0
static void connect_port(PortConnection * conn) {
    assert(is_dispatch_thread());

    sprintf(conn->id, "%s@%" PRIu64, conn->server->id, conn->server->port_index++);
    port_lock(conn);
    conn->pending = protocol_send_command(conn->server->channel, "PortForward",
            "getCapabilities", getcapabilities_cb, conn);
    write_string(&conn->server->channel->out, "null");
    write_stream(&conn->server->channel->out, MARKER_EOA);
    write_stream(&conn->server->channel->out, MARKER_EOM);
}
Beispiel #7
0
static int lua_channel_send_command(lua_State *L)
{
    struct channel_extra *ce = NULL;
    struct command_extra *cmd;
    OutputStream *out;
    const char *s;
    size_t l;

    assert(L == luastate);
    if(lua_gettop(L) != 5 ||
       (ce = lua2channel(L, 1)) == NULL ||
       !lua_isstring(L, 2) ||
       !lua_isstring(L, 3) ||
       !lua_isstring(L, 4) ||
       !lua_isfunction(L, 5)) {
        luaL_error(L, "wrong number or type of arguments");
    }
    if(ce->c == NULL) luaL_error(L, "disconnected channel");

    /* Object to track outstanding command */
    cmd = (struct command_extra *)lua_newuserdata(L, sizeof *cmd);
    memset(cmd, 0, sizeof *cmd);
    luaL_getmetatable(L, "tcf_command");
    lua_setmetatable(L, -2);

    /* Make sure GC don't free until reply is received */
    lua_pushvalue(L, -1);
    cmd->self_refp = luaref_new(L, cmd);
    lua_pushvalue(L, 5);
    cmd->result_cbrefp = luaref_new(L, cmd);

    /* Send command header */
    cmd->replyinfo = protocol_send_command(ce->c,
                                           lua_tostring(L, 2),
                                           lua_tostring(L, 3),
                                           channel_send_command_cb, cmd);
    s = lua_tolstring(L, 4, &l);
    trace(LOG_LUA, "lua_channel_send_command %p %d %.*s", ce->c, cmd->result_cbrefp->ref, l, s);
    out = &ce->c->out;
    while(l-- > 0) {
        write_stream(out, (*s++) & 0xff);
    }
    write_stream(out, MARKER_EOM);
    return 1;
}
static int read_packet(PortConnection * conn, int idx) {
    assert (is_dispatch_thread());

    assert ((conn->pending_read_request & (1 << idx)) == 0);
    if (conn->pending_read_request & (1 << idx)) {
        errno = ERR_IS_RUNNING;
        return -1;
    }
    port_lock(conn);
    conn->pending_read_request |= (1 << idx);
    (void) protocol_send_command(conn->server->channel, "Streams", "read", read_stream_done,
            &conn->read_info[idx]);
    json_write_string(&conn->server->channel->out, conn->in_stream_id);
    write_stream(&conn->server->channel->out, 0);
    json_write_long(&conn->server->channel->out, sizeof conn->read_buffer[idx]);
    write_stream(&conn->server->channel->out, MARKER_EOA);
    write_stream(&conn->server->channel->out, MARKER_EOM);
    return 0;
}
static void portcreate_cb(Channel * c, void * x, int error) {
    Trap trap;
    PortConnection * conn = (PortConnection *)x;

    if (set_trap(&trap)) {
        if (!error) {
            error = read_errno(&c->inp);
            json_test_char(&c->inp, MARKER_EOM);
        }
        clear_trap(&trap);
    }
    else {
        error = trap.error;
    }
    if (error) {
        connect_port_callback(conn, error);
    } else {
        conn->pending = protocol_send_command(conn->server->channel, "PortForward",
                "getConfig", getconfig_cb, conn);
        json_write_string(&conn->server->channel->out, conn->id);
        write_stream(&conn->server->channel->out, MARKER_EOA);
        write_stream(&conn->server->channel->out, MARKER_EOM);
    }
}