/* Attempts to parse the content of 'rpc->parser' (which is complete JSON) as a * JSON-RPC message. If successful, returns the JSON-RPC message. On failure, * signals an error on 'rpc' with jsonrpc_error() and returns NULL. */ static struct jsonrpc_msg * jsonrpc_parse_received_message(struct jsonrpc *rpc) { struct jsonrpc_msg *msg; struct json *json; char *error; json = json_parser_finish(rpc->parser); rpc->parser = NULL; if (json->type == JSON_STRING) { VLOG_WARN_RL(&rl, "%s: error parsing stream: %s", rpc->name, json_string(json)); jsonrpc_error(rpc, EPROTO); json_destroy(json); return NULL; } error = jsonrpc_msg_from_json(json, &msg); if (error) { VLOG_WARN_RL(&rl, "%s: received bad JSON-RPC message: %s", rpc->name, error); free(error); jsonrpc_error(rpc, EPROTO); return NULL; } jsonrpc_log_msg(rpc, "received", msg); return msg; }
/* 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->backlog += length; if (rpc->backlog == length) { jsonrpc_run(rpc); } return rpc->status; }
/* 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; }