Ejemplo n.º 1
0
static void
jsonrpc_cleanup(struct jsonrpc *rpc)
{
    stream_close(rpc->stream);
    rpc->stream = NULL;

    json_parser_abort(rpc->parser);
    rpc->parser = NULL;

    jsonrpc_msg_destroy(rpc->received);
    rpc->received = NULL;

    ofpbuf_list_delete(&rpc->output);
    rpc->backlog = 0;
}
Ejemplo n.º 2
0
static struct ovsdb_schema *
fetch_schema(struct jsonrpc *rpc, const char *database)
{
    struct jsonrpc_msg *request, *reply;
    struct ovsdb_schema *schema;

    request = jsonrpc_create_request("get_schema",
                                     json_array_create_1(
                                         json_string_create(database)),
                                     NULL);
    check_txn(jsonrpc_transact_block(rpc, request, &reply), &reply);
    check_ovsdb_error(ovsdb_schema_from_json(reply->result, &schema));
    jsonrpc_msg_destroy(reply);

    return schema;
}
Ejemplo n.º 3
0
/* Schedules 'msg' to be sent on 'rpc' and returns 'rpc''s status (as with
 * jsonrpc_get_status()).
 *
 * If 'msg' cannot be sent immediately, it is appended to a buffer.  The caller
 * is responsible for ensuring that the amount of buffered data is somehow
 * limited.  (jsonrpc_get_backlog() returns the amount of data currently
 * buffered in 'rpc'.)
 *
 * Always takes ownership of 'msg', regardless of success. */
int
jsonrpc_send(struct jsonrpc *rpc, struct jsonrpc_msg *msg)
{
    struct ofpbuf *buf;
    struct json *json;
    size_t length;
    char *s;

    if (rpc->status) {
        jsonrpc_msg_destroy(msg);
        return rpc->status;
    }

    jsonrpc_log_msg(rpc, "send", msg);

    json = jsonrpc_msg_to_json(msg);
    s = json_to_string(json, 0);
    length = strlen(s);
    json_destroy(json);

    buf = xmalloc(sizeof *buf);
    ofpbuf_use(buf, s, length);
    buf->size = length;
    list_push_back(&rpc->output, &buf->list_node);
    rpc->output_count++;
    rpc->backlog += length;

    if (rpc->output_count >= 50) {
        VLOG_INFO_RL(&rl, "excessive sending backlog, jsonrpc: %s, num of"
                     " msgs: %"PRIuSIZE", backlog: %"PRIuSIZE".", rpc->name,
                     rpc->output_count, rpc->backlog);
    }

    if (rpc->backlog == length) {
        jsonrpc_run(rpc);
    }
    return rpc->status;
}
Ejemplo n.º 4
0
struct jsonrpc_msg *
jsonrpc_session_recv(struct jsonrpc_session *s)
{
    if (s->rpc) {
        unsigned int received_bytes;
        struct jsonrpc_msg *msg;

        received_bytes = jsonrpc_get_received_bytes(s->rpc);
        jsonrpc_recv(s->rpc, &msg);
        if (received_bytes != jsonrpc_get_received_bytes(s->rpc)) {
            /* Data was successfully received.
             *
             * Previously we only counted receiving a full message as activity,
             * but with large messages or a slow connection that policy could
             * time out the session mid-message. */
            reconnect_activity(s->reconnect, time_msec());
        }

        if (msg) {
            if (msg->type == JSONRPC_REQUEST && !strcmp(msg->method, "echo")) {
                /* Echo request.  Send reply. */
                struct jsonrpc_msg *reply;

                reply = jsonrpc_create_reply(json_clone(msg->params), msg->id);
                jsonrpc_session_send(s, reply);
            } else if (msg->type == JSONRPC_REPLY
                       && msg->id && msg->id->type == JSON_STRING
                       && !strcmp(msg->id->u.string, "echo")) {
                /* It's a reply to our echo request.  Suppress it. */
            } else {
                return msg;
            }
            jsonrpc_msg_destroy(msg);
        }
    }
    return NULL;
}
Ejemplo n.º 5
0
static void
do_listen(struct ovs_cmdl_context *ctx)
{
    struct pstream *pstream;
    struct jsonrpc **rpcs;
    size_t n_rpcs, allocated_rpcs;
    bool done;
    int error;

    error = jsonrpc_pstream_open(ctx->argv[1], &pstream, DSCP_DEFAULT);
    if (error) {
        ovs_fatal(error, "could not listen on \"%s\"", ctx->argv[1]);
    }

    daemonize();

    rpcs = NULL;
    n_rpcs = allocated_rpcs = 0;
    done = false;
    for (;;) {
        struct stream *stream;
        size_t i;

        /* Accept new connections. */
        error = pstream_accept(pstream, &stream);
        if (!error) {
            if (n_rpcs >= allocated_rpcs) {
                rpcs = x2nrealloc(rpcs, &allocated_rpcs, sizeof *rpcs);
            }
            rpcs[n_rpcs++] = jsonrpc_open(stream);
        } else if (error != EAGAIN) {
            ovs_fatal(error, "pstream_accept failed");
        }

        /* Service existing connections. */
        for (i = 0; i < n_rpcs; ) {
            struct jsonrpc *rpc = rpcs[i];
            struct jsonrpc_msg *msg;

            jsonrpc_run(rpc);
            if (!jsonrpc_get_backlog(rpc)) {
                error = jsonrpc_recv(rpc, &msg);
                if (!error) {
                    error = handle_rpc(rpc, msg, &done);
                    jsonrpc_msg_destroy(msg);
                } else if (error == EAGAIN) {
                    error = 0;
                }
            }

            if (!error) {
                error = jsonrpc_get_status(rpc);
            }
            if (error) {
                jsonrpc_close(rpc);
                ovs_error(error, "connection closed");
                memmove(&rpcs[i], &rpcs[i + 1],
                        (n_rpcs - i - 1) * sizeof *rpcs);
                n_rpcs--;
            } else {
                i++;
            }
        }

        /* Wait for something to do. */
        if (done && !n_rpcs) {
            break;
        }
        pstream_wait(pstream);
        for (i = 0; i < n_rpcs; i++) {
            struct jsonrpc *rpc = rpcs[i];

            jsonrpc_wait(rpc);
            if (!jsonrpc_get_backlog(rpc)) {
                jsonrpc_recv_wait(rpc);
            }
        }
        poll_block();
    }
    free(rpcs);
    pstream_close(pstream);
}