提交 8f569f71 authored 作者: Shane Bryldt's avatar Shane Bryldt 提交者: Mike Jerris

FS-9952: Big commit, first registered jsonrpc echo call successful, lots of cleanup remaining

上级 fd49aebb
......@@ -11,23 +11,20 @@ libunqlite_la_CFLAGS = -DUNQLITE_ENABLE_THREADS
libunqlite_la_LIBADD = -lpthread
lib_LTLIBRARIES = libblade.la
libblade_la_SOURCES = src/blade.c src/blade_stack.c src/bpcp.c src/blade_datastore.c
libblade_la_SOURCES += src/blade_rpcproto.c
libblade_la_SOURCES += src/blade_identity.c src/blade_module.c src/blade_connection.c src/blade_module_wss.c
libblade_la_SOURCES += src/blade_session.c src/blade_protocol.c
libblade_la_SOURCES = src/blade.c src/blade_stack.c
libblade_la_SOURCES += src/blade_datastore.c
libblade_la_SOURCES += src/blade_identity.c src/blade_module.c src/blade_connection.c
libblade_la_SOURCES += src/blade_session.c src/blade_protocol.c src/blade_space.c src/blade_method.c
libblade_la_SOURCES += src/blade_module_wss.c
libblade_la_CFLAGS = $(AM_CFLAGS) $(AM_CPPFLAGS)
libblade_la_LDFLAGS = -version-info 0:1:0 -lncurses -lpthread -lm -lconfig $(AM_LDFLAGS)
libblade_la_LIBADD = libunqlite.la
library_includedir = $(prefix)/include
library_include_HEADERS = src/include/blade.h src/include/blade_types.h src/include/blade_stack.h
library_include_HEADERS += src/include/bpcp.h src/include/blade_datastore.h src/include/blade_rpcproto.h
library_include_HEADERS += src/include/blade_identity.h src/include/blade_module.h src/include/blade_connection.h
library_include_HEADERS += src/include/blade_session.h src/include/blade_protocol.h
library_include_HEADERS += src/include/blade_datastore.h
library_include_HEADERS += src/include/blade_identity.h src/include/blade_module.h src/include/blade_connection.h
library_include_HEADERS += src/include/blade_session.h src/include/blade_protocol.h src/include/blade_space.h src/include/blade_method.h
library_include_HEADERS += src/include/unqlite.h test/tap.h
tests: libblade.la
$(MAKE) -C test tests
......@@ -495,6 +495,7 @@ ks_status_t blade_connection_state_on_ready(blade_connection_t *bc)
blade_transport_state_callback_t callback = NULL;
blade_connection_state_hook_t hook = BLADE_CONNECTION_STATE_HOOK_SUCCESS;
cJSON *json = NULL;
blade_session_t *bs = NULL;
ks_bool_t done = KS_FALSE;
ks_assert(bc);
......@@ -514,14 +515,18 @@ ks_status_t blade_connection_state_on_ready(blade_connection_t *bc)
blade_connection_disconnect(bc);
break;
}
if (!(done = (json == NULL))) {
blade_session_t *bs = blade_handle_sessions_get(bc->handle, bc->session);
ks_assert(bs);
if (!bs) {
bs = blade_handle_sessions_get(bc->handle, bc->session);
ks_assert(bs);
}
blade_session_receiving_push(bs, json);
cJSON_Delete(json);
json = NULL;
}
}
if (bs) blade_session_read_unlock(bs);
callback = blade_connection_state_callback_lookup(bc, BLADE_CONNECTION_STATE_READY);
if (callback) hook = callback(bc, BLADE_CONNECTION_STATE_CONDITION_POST);
......
/*
* Copyright (c) 2007-2014, Anthony Minessale II
* Copyright (c) 2017, Shane Bryldt
* All rights reserved.
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
......@@ -33,69 +33,79 @@
#include "blade.h"
struct blade_method_s {
blade_handle_t *handle;
ks_pool_t *pool;
/*
blade_space_t *space;
const char *name;
Find bootstrap addr.
Make a WSS connection to get validated and get group keys.
Broadcast/Announce existence.
blade_request_callback_t callback;
// @todo more fun descriptive information about the call for remote registrations
};
HEADER
KS_DECLARE(ks_status_t) blade_method_create(blade_method_t **bmP, blade_space_t *bs, const char *name, blade_request_callback_t callback)
{
blade_handle_t *bh = NULL;
blade_method_t *bm = NULL;
ks_pool_t *pool = NULL;
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Ver |r|R|U|U| Channel no | Packet Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| SEQ |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| PAYLOAD ...... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
ks_assert(bmP);
ks_assert(bs);
ks_assert(name);
r = IS Response
R = IS Retransmission
U = Unused
bh = blade_space_handle_get(bs);
ks_assert(bh);
PAYLOAD
pool = blade_handle_pool_get(bh);
ks_assert(pool);
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Instruction | Datatype | Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| PAYLOAD ..... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
bm = ks_pool_alloc(pool, sizeof(blade_method_t));
bm->handle = bh;
bm->pool = pool;
bm->space = bs;
bm->name = name; // @todo dup and keep copy? should mostly be literals
bm->callback = callback;
*bmP = bm;
*/
ks_log(KS_LOG_DEBUG, "Method Created: %s.%s\n", blade_space_path_get(bs), name);
return KS_STATUS_SUCCESS;
}
typedef struct bpcp_header_s {
uint32_t header;
uint64_t seq;
} bpcp_header_t;
KS_DECLARE(ks_status_t) blade_method_destroy(blade_method_t **bmP)
{
blade_method_t *bm = NULL;
typedef struct bpcp_channel_nfo_s {
char *channel_name;
unsigned char key[crypto_generichash_BYTES];
uint32_t ttl;
} bpcp_channel_nfo_t;
ks_assert(bmP);
ks_assert(*bmP);
typedef struct bpcp_handle_s {
ks_socket_t sock;
ks_sockaddr_t local_addr;
ks_sockaddr_t bootstrap_addr;
ks_hash_t *channel_nfo_hash;
} bpcp_handle_t;
bm = *bmP;
ks_log(KS_LOG_DEBUG, "Method Destroyed: %s.%s\n", blade_space_path_get(bm->space), bm->name);
ks_pool_free(bm->pool, bmP);
KS_DECLARE(ks_status_t) bpcp_create(bpcp_handle_t **handle,
const char *local_addr, ks_port_t local_port,
const char *bootstrap_addr, ks_port_t bootstrap_port)
{
return KS_STATUS_SUCCESS;
}
KS_DECLARE(const char *) blade_method_name_get(blade_method_t *bm)
{
ks_assert(bm);
return bm->name;
}
KS_DECLARE(blade_request_callback_t) blade_method_callback_get(blade_method_t *bm)
{
ks_assert(bm);
return bm->callback;
}
/* For Emacs:
* Local Variables:
* mode:c
......
......@@ -33,7 +33,11 @@
#include "blade.h"
KS_DECLARE(ks_status_t) blade_request_create(blade_request_t **breqP, blade_handle_t *bh, const char *session_id, cJSON *json)
KS_DECLARE(ks_status_t) blade_request_create(blade_request_t **breqP,
blade_handle_t *bh,
const char *session_id,
cJSON *json,
blade_response_callback_t callback)
{
blade_request_t *breq = NULL;
ks_pool_t *pool = NULL;
......@@ -50,8 +54,9 @@ KS_DECLARE(ks_status_t) blade_request_create(blade_request_t **breqP, blade_hand
breq->handle = bh;
breq->pool = pool;
breq->session_id = ks_pstrdup(pool, session_id);
breq->message = json;
breq->message = cJSON_Duplicate(json, 1);
breq->message_id = cJSON_GetObjectCstr(json, "id");
breq->callback = callback;
*breqP = breq;
......@@ -95,7 +100,7 @@ KS_DECLARE(ks_status_t) blade_response_create(blade_response_t **bresP, blade_ha
bres->pool = pool;
bres->session_id = ks_pstrdup(pool, session_id);
bres->request = breq;
bres->message = json;
bres->message = cJSON_Duplicate(json, 1);
*bresP = bres;
......@@ -120,6 +125,88 @@ KS_DECLARE(ks_status_t) blade_response_destroy(blade_response_t **bresP)
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_rpc_request_create(ks_pool_t *pool, cJSON **json, cJSON **params, const char **id, const char *method)
{
cJSON *root = NULL;
cJSON *p = NULL;
uuid_t msgid;
const char *mid = NULL;
ks_assert(pool);
ks_assert(json);
ks_assert(method);
root = cJSON_CreateObject();
cJSON_AddStringToObject(root, "jsonrpc", "2.0");
ks_uuid(&msgid);
mid = ks_uuid_str(pool, &msgid);
cJSON_AddStringToObject(root, "id", mid);
ks_pool_free(pool, &mid);
cJSON_AddStringToObject(root, "method", method);
p = cJSON_CreateObject();
cJSON_AddItemToObject(root, "params", p);
*json = root;
if (params) *params = p;
if (id) *id = cJSON_GetObjectCstr(root, "id");
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_rpc_response_create(ks_pool_t *pool, cJSON **json, cJSON **result, const char *id)
{
cJSON *root = NULL;
cJSON *r = NULL;
ks_assert(pool);
ks_assert(json);
ks_assert(id);
root = cJSON_CreateObject();
cJSON_AddStringToObject(root, "jsonrpc", "2.0");
cJSON_AddStringToObject(root, "id", id);
r = cJSON_CreateObject();
cJSON_AddItemToObject(root, "result", r);
*json = root;
if (result) *result = r;
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_rpc_error_create(ks_pool_t *pool, cJSON **json, cJSON **error, const char *id, int32_t code, const char *message)
{
cJSON *root = NULL;
cJSON *e = NULL;
ks_assert(pool);
ks_assert(json);
ks_assert(id);
ks_assert(message);
root = cJSON_CreateObject();
cJSON_AddStringToObject(root, "jsonrpc", "2.0");
cJSON_AddStringToObject(root, "id", id);
e = cJSON_CreateObject();
cJSON_AddNumberToObject(e, "code", code);
cJSON_AddStringToObject(e, "message", message);
cJSON_AddItemToObject(root, "error", e);
*json = root;
if (error) *error = e;
return KS_STATUS_SUCCESS;
}
/* For Emacs:
* Local Variables:
......
差异被折叠。
......@@ -430,6 +430,7 @@ ks_status_t blade_session_state_on_destroy(blade_session_t *bs)
ks_assert(bs);
ks_log(KS_LOG_DEBUG, "Session (%s) state destroy\n", bs->id);
blade_handle_sessions_remove(bs);
blade_session_destroy(&bs);
......@@ -483,21 +484,31 @@ ks_status_t blade_session_state_on_ready(blade_session_t *bs)
}
KS_DECLARE(ks_status_t) blade_session_send(blade_session_t *bs, cJSON *json)
KS_DECLARE(ks_status_t) blade_session_send(blade_session_t *bs, cJSON *json, blade_response_callback_t callback)
{
blade_request_t *request = NULL;
const char *method = NULL;
const char *id = NULL;
ks_assert(bs);
ks_assert(json);
method = cJSON_GetObjectCstr(json, "method");
id = cJSON_GetObjectCstr(json, "id");
if (method) {
blade_request_create(&request, bs->handle, bs->id, json);
// @note This is scenario 1
// 1) Sending a request (client: method caller or consumer)
ks_log(KS_LOG_DEBUG, "Session (%s) sending request (%s) for %s\n", bs->id, id, method);
blade_request_create(&request, bs->handle, bs->id, json, callback);
ks_assert(request);
// @todo set request TTL and figure out when requests are checked for expiration (separate thread in the handle?)
blade_handle_requests_add(request);
} else {
// @note This is scenario 3
// 3) Sending a response or error (server: method callee or provider)
ks_log(KS_LOG_DEBUG, "Session (%s) sending response (%s)\n", bs->id, id);
}
if (list_empty(&bs->connections)) {
......@@ -516,20 +527,18 @@ KS_DECLARE(ks_status_t) blade_session_send(blade_session_t *bs, cJSON *json)
ks_status_t blade_session_process(blade_session_t *bs, cJSON *json)
{
ks_status_t ret = KS_STATUS_SUCCESS;
blade_request_t *breq = NULL;
blade_response_t *bres = NULL;
const char *jsonrpc = NULL;
const char *id = NULL;
const char *method = NULL;
ks_bool_t disconnect = KS_FALSE;
ks_assert(bs);
ks_assert(json);
ks_log(KS_LOG_DEBUG, "Session (%s) processing\n", bs->id);
// @todo teardown the message, convert into a blade_request_t or blade_response_t
// @todo validate the jsonrpc fields
jsonrpc = cJSON_GetObjectCstr(json, "jsonrpc");
if (!jsonrpc || strcmp(jsonrpc, "2.0")) {
......@@ -549,13 +558,50 @@ ks_status_t blade_session_process(blade_session_t *bs, cJSON *json)
method = cJSON_GetObjectCstr(json, "method");
if (method) {
// @todo use method to find RPC callbacks
// @note This is scenario 2
// 2) Receiving a request (server: method callee or provider)
blade_space_t *tmp_space = NULL;
blade_method_t *tmp_method = NULL;
blade_request_callback_t callback = NULL;
char *space_name = ks_pstrdup(bs->pool, method);
char *method_name = strrchr(space_name, '.');
ks_log(KS_LOG_DEBUG, "Session (%s) receiving request (%s) for %s\n", bs->id, id, method);
if (!method_name || method_name == space_name) {
ks_pool_free(bs->pool, (void **)&space_name);
// @todo send error response, code = -32601 (method not found)
// @todo hangup session entirely?
return KS_STATUS_FAIL;
}
*method_name = '\0';
method_name++; // @todo check if can be postfixed safely on previous assignment, can't recall
tmp_space = blade_handle_space_lookup(bs->handle, space_name);
if (tmp_space) tmp_method = blade_space_methods_get(tmp_space, method_name);
ks_pool_free(bs->pool, (void **)&space_name);
blade_request_create(&breq, bs->handle, bs->id, json);
if (!tmp_method) {
// @todo send error response, code = -32601 (method not found)
// @todo hangup session entirely?
return KS_STATUS_FAIL;
}
callback = blade_method_callback_get(tmp_method);
ks_assert(callback);
blade_request_create(&breq, bs->handle, bs->id, json, NULL);
ks_assert(breq);
// @todo call request callback handler
disconnect = callback(breq);
blade_request_destroy(&breq);
} else {
// @note This is scenario 4
// 4) Receiving a response or error (client: method caller or consumer)
ks_log(KS_LOG_DEBUG, "Session (%s) receiving response (%s)\n", bs->id, id);
breq = blade_handle_requests_get(bs->handle, id);
if (!breq) {
// @todo hangup session entirely?
......@@ -563,18 +609,20 @@ ks_status_t blade_session_process(blade_session_t *bs, cJSON *json)
}
blade_handle_requests_remove(breq);
method = cJSON_GetObjectCstr(breq->message, "method");
ks_assert(method);
// @todo use method to find RPC callbacks
blade_response_create(&bres, bs->handle, bs->id, breq, json);
ks_assert(bres);
// @todo call response callback handler
disconnect = breq->callback(bres);
blade_response_destroy(&bres);
}
return ret;
if (disconnect) {
// @todo hangup session entirely?
return KS_STATUS_FAIL;
}
return KS_STATUS_SUCCESS;
}
/* For Emacs:
......
/*
* Copyright (c) 2017, Shane Bryldt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "blade.h"
struct blade_space_s {
blade_handle_t *handle;
ks_pool_t *pool;
const char *path;
ks_hash_t *methods;
};
KS_DECLARE(ks_status_t) blade_space_create(blade_space_t **bsP, blade_handle_t *bh, const char *path)
{
blade_space_t *bs = NULL;
ks_pool_t *pool = NULL;
ks_assert(bsP);
ks_assert(bh);
ks_assert(path);
pool = blade_handle_pool_get(bh);
bs = ks_pool_alloc(pool, sizeof(blade_space_t));
bs->handle = bh;
bs->pool = pool;
bs->path = path; // @todo dup and keep copy? should mostly be literals
ks_hash_create(&bs->methods, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_NOLOCK | KS_HASH_FLAG_DUP_CHECK, bs->pool);
ks_assert(bs);
*bsP = bs;
ks_log(KS_LOG_DEBUG, "Space Created: %s\n", path);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_space_destroy(blade_space_t **bsP)
{
blade_space_t *bs = NULL;
ks_hash_iterator_t *it = NULL;
ks_assert(bsP);
ks_assert(*bsP);
bs = *bsP;
for (it = ks_hash_first(bs->methods, KS_UNLOCKED); it; it = ks_hash_next(&it)) {
void *key = NULL;
blade_method_t *value = NULL;
ks_hash_this(it, (const void **)&key, NULL, (void **)&value);
blade_method_destroy(&value);
}
ks_hash_destroy(&bs->methods);
ks_log(KS_LOG_DEBUG, "Space Destroyed: %s\n", bs->path);
ks_pool_free(bs->pool, bsP);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(blade_handle_t *) blade_space_handle_get(blade_space_t *bs)
{
ks_assert(bs);
return bs->handle;
}
KS_DECLARE(const char *) blade_space_path_get(blade_space_t *bs)
{
ks_assert(bs);
return bs->path;
}
KS_DECLARE(ks_status_t) blade_space_methods_add(blade_space_t *bs, blade_method_t *bm)
{
ks_status_t ret = KS_STATUS_SUCCESS;
const char *name = NULL;
blade_method_t *bm_old = NULL;
ks_assert(bs);
ks_assert(bm);
name = blade_method_name_get(bm);
ks_assert(name);
ks_hash_write_lock(bs->methods);
bm_old = ks_hash_search(bs->methods, (void *)name, KS_UNLOCKED);
if (bm_old) ks_hash_remove(bs->methods, (void *)name);
ret = ks_hash_insert(bs->methods, (void *)name, (void *)bm);
ks_hash_write_unlock(bs->methods);
if (bm_old) blade_method_destroy(&bm_old);
return ret;
}
KS_DECLARE(ks_status_t) blade_space_methods_remove(blade_space_t *bs, blade_method_t *bm)
{
ks_status_t ret = KS_STATUS_SUCCESS;
const char *name = NULL;
ks_assert(bs);
ks_assert(bm);
name = blade_method_name_get(bm);
ks_assert(name);
ks_hash_write_lock(bs->methods);
ks_hash_remove(bs->methods, (void *)name);
ks_hash_write_unlock(bs->methods);
return ret;
}
KS_DECLARE(blade_method_t *) blade_space_methods_get(blade_space_t *bs, const char *name)
{
blade_method_t *bm = NULL;
ks_assert(bs);
ks_assert(name);
ks_hash_read_lock(bs->methods);
bm = ks_hash_search(bs->methods, (void *)name, KS_UNLOCKED);
ks_hash_read_unlock(bs->methods);
return bm;
}
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/
......@@ -48,6 +48,7 @@ struct blade_handle_s {
config_setting_t *config_datastore;
ks_hash_t *transports; // registered transports exposed by modules, NOT active connections
ks_hash_t *spaces; // registered method spaces exposed by modules
//blade_identity_t *identity;
blade_datastore_t *datastore;
......@@ -69,6 +70,7 @@ struct blade_handle_transport_registration_s {
blade_transport_callbacks_t *callbacks;
};
KS_DECLARE(ks_status_t) blade_handle_transport_registration_create(blade_handle_transport_registration_t **bhtrP,
ks_pool_t *pool,
blade_module_t *module,
......@@ -133,6 +135,8 @@ KS_DECLARE(ks_status_t) blade_handle_create(blade_handle_t **bhP, ks_pool_t *poo
ks_hash_create(&bh->transports, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_NOLOCK | KS_HASH_FLAG_DUP_CHECK, bh->pool);
ks_assert(bh->transports);
ks_hash_create(&bh->spaces, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_NOLOCK | KS_HASH_FLAG_DUP_CHECK, bh->pool);
ks_assert(bh->spaces);
ks_hash_create(&bh->connections, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_NOLOCK | KS_HASH_FLAG_DUP_CHECK, bh->pool);
ks_assert(bh->connections);
......@@ -144,6 +148,8 @@ KS_DECLARE(ks_status_t) blade_handle_create(blade_handle_t **bhP, ks_pool_t *poo
*bhP = bh;
ks_log(KS_LOG_DEBUG, "Created\n");
return KS_STATUS_SUCCESS;
}
......@@ -168,10 +174,13 @@ KS_DECLARE(ks_status_t) blade_handle_destroy(blade_handle_t **bhP)
ks_hash_destroy(&bh->requests);
ks_hash_destroy(&bh->sessions);
ks_hash_destroy(&bh->connections);
ks_hash_destroy(&bh->spaces);
ks_hash_destroy(&bh->transports);
if (bh->tpool && (flags & BH_MYTPOOL)) ks_thread_pool_destroy(&bh->tpool);
ks_log(KS_LOG_DEBUG, "Destroyed\n");
ks_pool_free(bh->pool, &bh);
if (pool && (flags & BH_MYPOOL)) {
......@@ -249,13 +258,22 @@ KS_DECLARE(ks_status_t) blade_handle_shutdown(blade_handle_t *bh)
blade_session_t *value = NULL;
ks_hash_this(it, (const void **)&key, NULL, (void **)&value);
ks_hash_remove(bh->requests, key);
//ks_hash_remove(bh->sessions, key);
blade_session_hangup(value);
}
while (ks_hash_count(bh->sessions) > 0) ks_sleep_ms(100);
// @todo call onshutdown and onunload callbacks for modules from DSOs, which will unregister transports and disconnect remaining unattached connections
// @todo call onshutdown and onunload callbacks for modules from DSOs, which will unregister transports and spaces, and will disconnect remaining
// unattached connections
for (it = ks_hash_first(bh->spaces, KS_UNLOCKED); it; it = ks_hash_next(&it)) {
void *key = NULL;
blade_space_t *value = NULL;
ks_hash_this(it, (const void **)&key, NULL, (void **)&value);
blade_handle_space_unregister(value);
}
// @todo unload DSOs
......@@ -316,11 +334,81 @@ KS_DECLARE(ks_status_t) blade_handle_transport_unregister(blade_handle_t *bh, co
if (bhtr) ks_hash_remove(bh->transports, (void *)name);
ks_hash_write_unlock(bh->transports);
if (bhtr) blade_handle_transport_registration_destroy(&bhtr);
if (bhtr) {
blade_handle_transport_registration_destroy(&bhtr);
ks_log(KS_LOG_DEBUG, "Transport Unregistered: %s\n", name);
}
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_handle_space_register(blade_space_t *bs)
{
blade_handle_t *bh = NULL;
const char *path = NULL;
blade_space_t *bs_old = NULL;
ks_assert(bs);
bh = blade_space_handle_get(bs);
ks_assert(bh);
path = blade_space_path_get(bs);
ks_assert(path);
ks_hash_write_lock(bh->spaces);
bs_old = ks_hash_search(bh->spaces, (void *)path, KS_UNLOCKED);
if (bs_old) ks_hash_remove(bh->spaces, (void *)path);
ks_hash_insert(bh->spaces, (void *)path, bs);
ks_hash_write_unlock(bh->spaces);
if (bs_old) blade_space_destroy(&bs_old);
ks_log(KS_LOG_DEBUG, "Space Registered: %s\n", path);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_handle_space_unregister(blade_space_t *bs)
{
blade_handle_t *bh = NULL;
const char *path = NULL;
ks_assert(bs);
bh = blade_space_handle_get(bs);
ks_assert(bh);
path = blade_space_path_get(bs);
ks_assert(path);
ks_hash_write_lock(bh->spaces);
bs = ks_hash_search(bh->spaces, (void *)path, KS_UNLOCKED);
if (bs) ks_hash_remove(bh->spaces, (void *)path);
ks_hash_write_unlock(bh->spaces);
if (bs) {
blade_space_destroy(&bs);
ks_log(KS_LOG_DEBUG, "Space Unregistered: %s\n", path);
}
return KS_STATUS_SUCCESS;
}
KS_DECLARE(blade_space_t *) blade_handle_space_lookup(blade_handle_t *bh, const char *path)
{
blade_space_t *bs = NULL;
ks_assert(bh);
ks_assert(path);
ks_hash_read_lock(bh->spaces);
bs = ks_hash_search(bh->spaces, (void *)path, KS_UNLOCKED);
ks_hash_read_unlock(bh->spaces);
return bs;
}
KS_DECLARE(ks_status_t) blade_handle_connect(blade_handle_t *bh, blade_connection_t **bcP, blade_identity_t *target, const char *session_id)
{
ks_status_t ret = KS_STATUS_SUCCESS;
......
/*
* Copyright (c) 2007-2014, Anthony Minessale II
* All rights reserved.
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
......@@ -46,7 +46,8 @@
#include "blade_session.h"
#include "blade_protocol.h"
#include "blade_datastore.h"
#include "bpcp.h"
#include "blade_space.h"
#include "blade_method.h"
KS_BEGIN_EXTERN_C
......
/*
* Copyright (c) 2007-2014, Anthony Minessale II
* Copyright (c) 2017, Shane Bryldt
* All rights reserved.
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
......@@ -31,12 +31,15 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _BPCP_H_
#define _BPCP_H_
#ifndef _BLADE_METHOD_H_
#define _BLADE_METHOD_H_
#include <blade.h>
KS_BEGIN_EXTERN_C
KS_DECLARE(ks_status_t) blade_method_create(blade_method_t **bmP, blade_space_t *bs, const char *name, blade_request_callback_t callback);
KS_DECLARE(ks_status_t) blade_method_destroy(blade_method_t **bmP);
KS_DECLARE(const char *) blade_method_name_get(blade_method_t *bm);
KS_DECLARE(blade_request_callback_t) blade_method_callback_get(blade_method_t *bm);
KS_END_EXTERN_C
#endif
......
......@@ -36,10 +36,17 @@
#include <blade.h>
KS_BEGIN_EXTERN_C
KS_DECLARE(ks_status_t) blade_request_create(blade_request_t **breqP, blade_handle_t *bh, const char *session_id, cJSON *json);
KS_DECLARE(ks_status_t) blade_request_create(blade_request_t **breqP,
blade_handle_t *bh,
const char *session_id,
cJSON *json,
blade_response_callback_t callback);
KS_DECLARE(ks_status_t) blade_request_destroy(blade_request_t **breqP);
KS_DECLARE(ks_status_t) blade_response_create(blade_response_t **bresP, blade_handle_t *bh, const char *session_id, blade_request_t *breq, cJSON *json);
KS_DECLARE(ks_status_t) blade_response_destroy(blade_response_t **bresP);
KS_DECLARE(ks_status_t) blade_rpc_request_create(ks_pool_t *pool, cJSON **json, cJSON **params, const char **id, const char *method);
KS_DECLARE(ks_status_t) blade_rpc_response_create(ks_pool_t *pool, cJSON **json, cJSON **result, const char *id);
KS_DECLARE(ks_status_t) blade_rpc_error_create(ks_pool_t *pool, cJSON **json, cJSON **error, const char *id, int32_t code, const char *message);
KS_END_EXTERN_C
#endif
......
/*
* Copyright (c) 2017, FreeSWITCH LLC
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _BLADE_RPCPROTO_H_
#define _BLADE_RPCPROTO_H_
#include <ks_rpcmessage.h>
#include <blade_types.h>
// temp typedefs to get compile going
//typedef struct blade_peer_s blade_peer_t;
//typedef struct blade_event_s blade_event_t;
#define KS_RPCMESSAGE_NAMESPACE_LENGTH 16
#define KS_RPCMESSAGE_COMMAND_LENGTH 238
#define KS_RPCMESSAGE_FQCOMMAND_LENGTH (KS_RPCMESSAGE_NAMESPACE_LENGTH+KS_RPCMESSAGE_COMMAND_LENGTH+1)
#define KS_RPCMESSAGE_VERSION_LENGTH 9
/*
* contents to add to the "blade" field in rpc
*/
typedef struct blade_rpc_fields_s {
const char *to;
const char *from;
const char *token;
} blade_rpc_fields_t;
enum jrpc_status_t {
JRPC_PASS = (1 << 0),
JRPC_SEND = (1 << 1),
JRPC_EXIT = (1 << 2),
JRPC_SEND_EXIT = JRPC_SEND + JRPC_EXIT,
JRPC_ERROR = (1 << 3)
};
typedef enum jrpc_status_t (*jrpc_func_t) (cJSON *request, cJSON **replyP);
/*
* setup
* -----
*/
KS_DECLARE(ks_status_t) blade_rpc_init(ks_pool_t *pool);
/*
* namespace and call back registration
* ------------------------------------
*/
KS_DECLARE(ks_status_t) blade_rpc_declare_namespace(char* namespace, const char* version);
KS_DECLARE(ks_status_t) blade_rpc_register_function(char* namespace,
char *command,
jrpc_func_t func,
jrpc_func_t respfunc);
KS_DECLARE(ks_status_t) blade_rpc_register_custom_request_function(char* namespace,
char *command,
jrpc_func_t prefix_func,
jrpc_func_t postfix_func);
KS_DECLARE(ks_status_t) blade_rpc_register_custom_response_function(char *namespace,
char *command,
jrpc_func_t prefix_func,
jrpc_func_t postfix_func);
KS_DECLARE(void) blade_rpc_remove_namespace(char* namespace);
/*
* template registration and inheritance
* -------------------------------------
*/
KS_DECLARE(ks_status_t) blade_rpc_declare_template(char* templatename, const char* version);
KS_DECLARE(ks_status_t)blade_rpc_register_template_function(char *name,
char *command,
jrpc_func_t func,
jrpc_func_t respfunc);
KS_DECLARE(ks_status_t)blade_rpc_inherit_template(char *namespace, char* template);
/*
* create a request message
*/
KS_DECLARE(ks_rpcmessageid_t) blade_rpc_create_request(char *namespace,
char *method,
blade_rpc_fields_t* fields,
cJSON **paramsP,
cJSON **requestP);
KS_DECLARE(ks_rpcmessageid_t) blade_rpc_create_response(cJSON *request,
cJSON **reply,
cJSON **response);
KS_DECLARE(ks_rpcmessageid_t) blade_rpc_create_errorresponse(cJSON *request,
cJSON **reply,
cJSON **response);
KS_DECLARE(ks_status_t) blade_rpc_parse_message(cJSON *message,
char **namespace,
char **method,
char **version,
uint32_t *idP,
blade_rpc_fields_t **fieldsP);
/*
* peer create/destroy
* -------------------
*/
//KS_DECLARE(ks_status_t) blade_rpc_onconnect(ks_pool_t *pool, blade_peer_t* peer);
//KS_DECLARE(ks_status_t) blade_rpc_disconnect(blade_peer_t* peer);
/*
* send message
* ------------
*/
KS_DECLARE(ks_status_t) blade_rpc_write(char *sessionid, char* data, uint32_t size); //uuid_t ?
KS_DECLARE(ks_status_t) blade_rpc_write_json(cJSON* json);
/*
* process inbound message
* -----------------------
*/
KS_DECLARE(ks_status_t) blade_rpc_process_data(const uint8_t *data, ks_size_t size);
KS_DECLARE(ks_status_t) blade_rpc_process_jsonmessage(cJSON *request);
#endif
/*
* Copyright (c) 2017, Shane Bryldt
* All rights reserved.
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
......@@ -52,7 +52,7 @@ KS_DECLARE(void) blade_session_hangup(blade_session_t *bs);
KS_DECLARE(ks_bool_t) blade_session_terminating(blade_session_t *bs);
KS_DECLARE(ks_status_t) blade_session_connections_add(blade_session_t *bs, const char *id);
KS_DECLARE(ks_status_t) blade_session_connections_remove(blade_session_t *bs, const char *id);
KS_DECLARE(ks_status_t) blade_session_send(blade_session_t *bs, cJSON *json);
KS_DECLARE(ks_status_t) blade_session_send(blade_session_t *bs, cJSON *json, blade_response_callback_t callback);
KS_DECLARE(ks_status_t) blade_session_sending_push(blade_session_t *bs, cJSON *json);
KS_DECLARE(ks_status_t) blade_session_sending_pop(blade_session_t *bs, cJSON **json);
KS_DECLARE(ks_status_t) blade_session_receiving_push(blade_session_t *bs, cJSON *json);
......
/*
* Copyright (c) 2017, FreeSWITCH Solutions LLC
* Copyright (c) 2017, Shane Bryldt
* All rights reserved.
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
......@@ -31,56 +31,21 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _KS_RPCMESSAGE_H_
#define _KS_RPCMESSAGE_H_
#include "ks.h"
#ifndef _BLADE_SPACE_H_
#define _BLADE_SPACE_H_
#include <blade.h>
KS_BEGIN_EXTERN_C
#define KS_RPCMESSAGE_NAMESPACE_LENGTH 16
#define KS_RPCMESSAGE_COMMAND_LENGTH 238
#define KS_RPCMESSAGE_FQCOMMAND_LENGTH (KS_RPCMESSAGE_NAMESPACE_LENGTH+KS_RPCMESSAGE_COMMAND_LENGTH+1)
#define KS_RPCMESSAGE_VERSION_LENGTH 9
typedef uint32_t ks_rpcmessageid_t;
KS_DECLARE(void) ks_rpcmessage_init(ks_pool_t *pool);
KS_DECLARE(void*) ks_json_pool_alloc(ks_size_t size);
KS_DECLARE(void) ks_json_pool_free(void *ptr);
KS_DECLARE(ks_rpcmessageid_t) ks_rpcmessage_create_request(char *namespace,
char *method,
cJSON **paramsP,
cJSON **requestP);
KS_DECLARE(ks_size_t) ks_rpc_create_buffer(char *namespace,
char *method,
cJSON **paramsP,
ks_buffer_t *buffer);
KS_DECLARE(ks_rpcmessageid_t) ks_rpcmessage_create_response(
const cJSON *request,
cJSON **resultP,
cJSON **responseP);
KS_DECLARE(ks_rpcmessageid_t) ks_rpcmessage_create_errorresponse(
const cJSON *request,
cJSON **errorP,
cJSON **responseP);
KS_DECLARE(ks_bool_t) ks_rpcmessage_isrequest(cJSON *msg);
KS_DECLARE(ks_bool_t) ks_rpcmessage_isrpc(cJSON *msg);
KS_DECLARE(ks_status_t) blade_space_create(blade_space_t **bsP, blade_handle_t *bh, const char *path);
KS_DECLARE(ks_status_t) blade_space_destroy(blade_space_t **bsP);
KS_DECLARE(blade_handle_t *) blade_space_handle_get(blade_space_t *bs);
KS_DECLARE(const char *) blade_space_path_get(blade_space_t *bs);
KS_DECLARE(ks_status_t) blade_space_methods_add(blade_space_t *bs, blade_method_t *bm);
KS_DECLARE(ks_status_t) blade_space_methods_remove(blade_space_t *bs, blade_method_t *bm);
KS_DECLARE(blade_method_t *) blade_space_methods_get(blade_space_t *bs, const char *name);
KS_END_EXTERN_C
#endif /* defined(_KS_RPCMESSAGE_H_) */
#endif
/* For Emacs:
* Local Variables:
......
......@@ -50,6 +50,11 @@ KS_DECLARE(ks_thread_pool_t *) blade_handle_tpool_get(blade_handle_t *bh);
KS_DECLARE(ks_status_t) blade_handle_transport_register(blade_handle_t *bh, blade_module_t *bm, const char *name, blade_transport_callbacks_t *callbacks);
KS_DECLARE(ks_status_t) blade_handle_transport_unregister(blade_handle_t *bh, const char *name);
KS_DECLARE(ks_status_t) blade_handle_space_register(blade_space_t *bs);
KS_DECLARE(ks_status_t) blade_handle_space_unregister(blade_space_t *bs);
KS_DECLARE(blade_space_t *) blade_handle_space_lookup(blade_handle_t *bh, const char *path);
KS_DECLARE(ks_status_t) blade_handle_connect(blade_handle_t *bh, blade_connection_t **bcP, blade_identity_t *target, const char *session_id);
KS_DECLARE(blade_connection_t *) blade_handle_connections_get(blade_handle_t *bh, const char *cid);
......
......@@ -47,6 +47,12 @@ typedef struct blade_connection_s blade_connection_t;
typedef struct blade_session_s blade_session_t;
typedef struct blade_request_s blade_request_t;
typedef struct blade_response_s blade_response_t;
typedef struct blade_space_s blade_space_t;
typedef struct blade_method_s blade_method_t;
typedef ks_bool_t (*blade_request_callback_t)(blade_request_t *breq);
typedef ks_bool_t (*blade_response_callback_t)(blade_response_t *bres);
typedef struct blade_datastore_s blade_datastore_t;
......@@ -147,6 +153,7 @@ struct blade_request_s {
cJSON *message;
const char *message_id; // pulled from message for easier keying
blade_response_callback_t callback;
// @todo ttl to wait for response before injecting an error response locally
// @todo rpc response callback
};
......
AM_CFLAGS += -I$(abs_top_srcdir)/src/include -g -ggdb -O0
AM_CFLAGS += -I$(abs_top_srcdir)/src/include -g -ggdb -O0
TEST_LDADD = $(abs_top_builddir)/libblade.la -lconfig -lm -lpthread
check_PROGRAMS =
check_PROGRAMS += testrpcproto
testrpcproto_SOURCES = testrpcproto.c tap.c
testrpcproto_CFLAGS = $(AM_CFLAGS)
testrpcproto_LDADD = $(TEST_LDADD)
check_PROGRAMS += testbuild
testbuild_SOURCES = testbuild.c tap.c
testbuild_CFLAGS = $(AM_CFLAGS)
......
差异被折叠。
......@@ -10,13 +10,13 @@ lib_LTLIBRARIES = libks.la
libks_la_SOURCES = src/ks.c src/ks_string.c src/ks_json.c src/cJSON.c src/cJSON_Utils.c src/ks_thread.c src/ks_thread_pool.c src/ks_mutex.c src/ks_config.c
libks_la_SOURCES += src/ks_log.c src/ks_socket.c src/ks_buffer.c src/ks_pool.c src/simclist.c
libks_la_SOURCES += src/ks_time.c src/ks_printf.c src/ks_hash.c src/ks_q.c src/ks_dso.c # src/ks_dht.c
libks_la_SOURCES += src/ks_ssl.c src/kws.c src/ks_rng.c src/ks_rpcmessage.c src/ks_base64.c
libks_la_SOURCES += src/ks_ssl.c src/kws.c src/ks_rng.c src/ks_base64.c
libks_la_SOURCES += src/utp/utp_api.cpp src/utp/utp_callbacks.cpp src/utp/utp_hash.cpp src/utp/utp_internal.cpp
libks_la_SOURCES += src/utp/utp_packedsockaddr.cpp src/utp/utp_utils.cpp src/ks_bencode.c
libks_la_SOURCES += src/dht/ks_dht.c src/dht/ks_dht_datagram.c src/dht/ks_dht_endpoint.c src/dht/ks_dht_message.c src/dht/ks_dht_transaction.c
libks_la_SOURCES += src/dht/ks_dht_job.c src/dht/ks_dht_search.c src/dht/ks_dht_publish.c src/dht/ks_dht_distribute.c src/dht/ks_dht_storageitem.c
libks_la_SOURCES += src/dht/ks_dht_bucket.c
libks_la_SOURCES += crypt/aeskey.c crypt/aestab.c crypt/sha2.c crypt/twofish.c crypt/aes_modes.c crypt/aescrypt.c crypt/twofish_cfb.c
libks_la_SOURCES += crypt/aeskey.c crypt/aestab.c crypt/sha2.c crypt/twofish.c crypt/aes_modes.c crypt/aescrypt.c crypt/twofish_cfb.c
#aes.h aescpp.h brg_endian.h aesopt.h aestab.h brg_types.h sha2.h twofish.h
libks_la_SOURCES += src/ks_acl.c
......@@ -29,14 +29,10 @@ library_include_HEADERS = src/include/ks_config.h src/include/ks.h src/include/k
library_include_HEADERS += src/include/ks_thread_pool.h src/include/ks_cJSON.h src/include/ks_cJSON_Utils.h
library_include_HEADERS += src/include/ks_pool.h src/include/simclist.h src/include/ks_time.h src/include/ks_q.h src/include/ks_socket.h
library_include_HEADERS += src/include/ks_dso.h src/include/ks_platform.h src/include/ks_types.h # src/include/ks_rng.h src/include/ks_dht.h
library_include_HEADERS += src/include/ks_printf.h src/include/ks_hash.h src/include/ks_ssl.h src/include/kws.h
library_include_HEADERS += src/include/ks_rpcmessage.h src/include/ks_base64.h
library_include_HEADERS += src/include/ks_printf.h src/include/ks_hash.h src/include/ks_ssl.h src/include/kws.h
library_include_HEADERS += src/include/ks_base64.h
library_include_HEADERS += src/utp/utp_internal.h src/utp/utp.h src/utp/utp_types.h src/utp/utp_callbacks.h src/utp/utp_templates.h
library_include_HEADERS += src/utp/utp_hash.h src/utp/utp_packedsockaddr.h src/utp/utp_utils.h src/include/ks_utp.h src/include/ks_acl.h
tests: libks.la
$(MAKE) -C test tests
/*
* Copyright (c) 2007-2014, Anthony Minessale II
* All rights reserved.
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
......@@ -137,7 +137,6 @@ KS_DECLARE(void) ks_random_string(char *buf, uint16_t len, char *set);
#include "ks_bencode.h"
#include "ks_rng.h"
#include "ks_acl.h"
#include "ks_rpcmessage.h"
#include "ks_base64.h"
KS_END_EXTERN_C
......
/*
* Copyright (c) 2017 FreeSWITCH Solutions LLC
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma GCC optimize ("O0")
#include <ks.h>
#include <ks_rpcmessage.h>
#include <ks_buffer.h>
struct
{
ks_mutex_t *id_mutex;
uint32_t message_id;
ks_pool_t *pool;
} handle = {NULL, 0, NULL};
const char PROTOCOL[] = "jsonrpc";
const char PROTOCOL_VERSION[] = "2.0";
const char ID[] = "id";
const char METHOD[] = "method";
const char PARAMS[] = "params";
const char ERROR[] = "error";
const char RESULT[] = "result";
KS_DECLARE(void*) ks_json_pool_alloc(ks_size_t size)
{
return ks_pool_alloc(handle.pool, size);
}
KS_DECLARE(void) ks_json_pool_free(void *ptr)
{
ks_pool_free(handle.pool, &ptr);
}
KS_DECLARE(void) ks_rpcmessage_init(ks_pool_t* pool)
{
if (!handle.id_mutex) {
ks_mutex_create(&handle.id_mutex, KS_MUTEX_FLAG_DEFAULT, pool);
handle.pool = pool;
cJSON_Hooks hooks;
hooks.malloc_fn = ks_json_pool_alloc;
hooks.free_fn = ks_json_pool_free;
cJSON_InitHooks(&hooks);
}
return;
}
static uint32_t ks_rpcmessage_next_id()
{
uint32_t message_id;
ks_mutex_lock(handle.id_mutex);
++handle.message_id;
if (!handle.message_id) {
++handle.message_id;
}
message_id = handle.message_id;
ks_mutex_unlock(handle.id_mutex);
return message_id;
}
static cJSON *ks_rpcmessage_new(uint32_t id)
{
cJSON *obj = cJSON_CreateObject();
cJSON_AddItemToObject(obj, PROTOCOL, cJSON_CreateString(PROTOCOL_VERSION));
if (id) {
cJSON_AddItemToObject(obj, ID, cJSON_CreateNumber(id));
}
return obj;
}
static cJSON *ks_rpcmessage_dup(cJSON *msgid)
{
cJSON *obj = cJSON_CreateObject();
cJSON_AddItemToObject(obj, PROTOCOL, cJSON_CreateString(PROTOCOL_VERSION));
if (msgid) {
cJSON_AddItemToObject(obj, ID, cJSON_Duplicate(msgid, 0));
}
return obj;
}
KS_DECLARE(ks_bool_t) ks_rpcmessage_isrequest(cJSON *msg)
{
cJSON *result = cJSON_GetObjectItem(msg, RESULT);
cJSON *error = cJSON_GetObjectItem(msg, ERROR);
if (result || error) {
return KS_FALSE;
}
return KS_TRUE;
}
KS_DECLARE(ks_bool_t) ks_rpcmessage_isrpc(cJSON *msg)
{
cJSON *rpc = cJSON_GetObjectItem(msg, PROTOCOL);
if (rpc) {
return KS_FALSE;
}
return KS_TRUE;
}
KS_DECLARE(ks_rpcmessageid_t) ks_rpcmessage_create_request(char *namespace,
char *command,
cJSON **paramsP,
cJSON **requestP)
{
cJSON *msg, *params = NULL;
*requestP = NULL;
ks_rpcmessageid_t msgid = ks_rpcmessage_next_id();
msg = ks_rpcmessage_new(msgid);
if (paramsP) {
if (*paramsP) { /* parameters have been passed */
params = *paramsP;
}
else {
params = cJSON_CreateObject();
*paramsP = params;
}
cJSON_AddItemToObject(msg, PARAMS, params);
}
char fqcommand[KS_RPCMESSAGE_FQCOMMAND_LENGTH];
memset(fqcommand, 0, sizeof(fqcommand));
sprintf(fqcommand, "%s.%s", namespace, command);
cJSON_AddItemToObject(msg, METHOD, cJSON_CreateString(fqcommand));
*requestP = msg;
return msgid;
}
KS_DECLARE(ks_size_t) ks_rpc_create_buffer(char *namespace,
char *method,
cJSON **params,
ks_buffer_t *buffer)
{
cJSON *message;
ks_rpcmessageid_t msgid = ks_rpcmessage_create_request(namespace, method, params, &message);
if (!msgid) {
return 0;
}
if ( (*params)->child == NULL) {
cJSON_AddNullToObject(*params, "bladenull");
}
const char* b = cJSON_PrintUnformatted(message);
ks_size_t size = strlen(b);
ks_buffer_write(buffer, b, size);
cJSON_Delete(message);
return size;
}
static ks_rpcmessageid_t ks_rpcmessage_get_messageid(const cJSON *msg, cJSON **cmsgidP)
{
ks_rpcmessageid_t msgid = 0;
cJSON *cmsgid = cJSON_GetObjectItem(msg, ID);
if (cmsgid->type == cJSON_Number) {
msgid = (ks_rpcmessageid_t) cmsgid->valueint;
}
*cmsgidP = cmsgid;
return msgid;
}
static ks_rpcmessageid_t ks_rpcmessage_new_response(
const cJSON *request,
cJSON **result,
cJSON **pmsg)
{
cJSON *respmsg = NULL;
cJSON *cmsgid = NULL;
cJSON *command = cJSON_GetObjectItem(request, METHOD);
ks_rpcmessageid_t msgid = ks_rpcmessage_get_messageid(request, &cmsgid );
if (!msgid || !command) {
return 0;
}
*pmsg = respmsg = ks_rpcmessage_dup(cmsgid);
cJSON_AddItemToObject(respmsg, METHOD, cJSON_Duplicate(command, 0));
if (result && *result) {
cJSON_AddItemToObject(respmsg, RESULT, *result);
}
return msgid;
}
KS_DECLARE(ks_rpcmessageid_t) ks_rpcmessage_create_response(
const cJSON *request,
cJSON **resultP,
cJSON **responseP)
{
ks_rpcmessageid_t msgid = ks_rpcmessage_new_response(request, resultP, responseP);
cJSON *respmsg = *responseP;
if (msgid) {
if (resultP && *resultP == NULL) {
cJSON *result = cJSON_CreateObject();
*resultP = result;
cJSON_AddItemToObject(respmsg, RESULT, result);
}
}
return msgid;
}
KS_DECLARE(ks_rpcmessageid_t) ks_rpcmessage_create_errorresponse(
const cJSON *request,
cJSON **errorP,
cJSON **responseP)
{
ks_rpcmessageid_t msgid = ks_rpcmessage_new_response(request, NULL, responseP);
cJSON *respmsg = *responseP;
if (msgid) {
if (errorP && *errorP == NULL) {
cJSON *error = cJSON_CreateObject();
*errorP = error;
cJSON_AddItemToObject(respmsg, ERROR, error);
}
else if (errorP && *errorP) {
cJSON_AddItemToObject(*responseP, ERROR, *errorP);
}
}
return msgid;
}
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/
AM_CFLAGS += -I$(abs_top_srcdir)/src/include -g -ggdb -O0 $(openssl_CFLAGS)
TEST_LDADD = $(abs_top_builddir)/libks.la $(openssl_LIBS)
check_PROGRAMS =
check_PROGRAMS =
EXTRA_DIST = tap.h
check_PROGRAMS += testmessages
testmessages_SOURCES = testmessages.c tap.c
testmessages_CFLAGS = $(AM_CFLAGS)
testmessages_LDADD = $(TEST_LDADD)
check_PROGRAMS += testbuckets
testbuckets_SOURCES = testbuckets.c tap.c
testbuckets_CFLAGS = $(AM_CFLAGS)
......@@ -96,7 +91,7 @@ nodeidgen_LDADD = $(TEST_LDADD)
#check_PROGRAMS += libtorrent_example
#libtorrent_example_SOURCES = libtorrent-example.c
#libtorrent_example_CFLAGS = $(AM_CFLAGS)
#libtorrent_example_CFLAGS = $(AM_CFLAGS)
#libtorrent_example_LDADD = $(abs_top_builddir)/libks.la $(abs_top_builddir)/test/libtorrent.so /usr/lib/x86_64-linux-gnu/libboost_system.a $(openssl_LIBS) -ledit -lpthread -ltorrent-rasterbar -lstdc++
TESTS=$(check_PROGRAMS)
......@@ -108,4 +103,3 @@ $(abs_top_builddir)/test/libtorrent.so: $(abs_top_builddir)/test/libtorrent.o
$(abs_top_builddir)/test/libtorrent.o: $(abs_top_builddir)/test/libtorrent.cpp
g++ -c -fPIC -o $(abs_top_builddir)/test/libtorrent.o -I$(abs_top_builddir)/test/ $(abs_top_builddir)/test/libtorrent.cpp
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
#pragma GCC diagnostic ignored "-Wunused-variable"
#pragma GCC diagnostic ignored "-Wunused-function"
#include "../src/include/ks_rpcmessage.h"
#pragma GCC optimize ("O0")
ks_pool_t *pool;
void test01()
{
printf("**** testrpcmessages - test01 start\n\n"); fflush(stdout);
cJSON* request1 = NULL;
cJSON* parms1 = NULL;
cJSON* response1 = NULL;
/*namespace, method, params, **request */
ks_rpcmessageid_t msgid = ks_rpcmessage_create_request("app1", "func1", &parms1, &request1);
if (msgid == 0) {
printf("message create failed %d\n", msgid);
}
cJSON_AddStringToObject(parms1, "hello", "cruel world");
char* data = cJSON_PrintUnformatted(request1);
printf("test01 request1: %d\n%s\n\n", msgid, data);
ks_json_pool_free(data);
/* convert to buffer */
cJSON* parms2 = NULL;
ks_buffer_t *buffer;
ks_buffer_create(&buffer, 256, 256, 1024);
ks_size_t n = ks_rpc_create_buffer("app2", "func2", &parms2, buffer);
ks_size_t size = ks_buffer_len(buffer);
char *b = (char *)ks_pool_alloc(pool, size+1);
ks_buffer_read(buffer, b, size);
printf("test01 request2: %zd %zd from ks_buffer\n%s\n\n\n", n, size, b);
/* create message 3 */
cJSON *parms3 = cJSON_CreateNumber(1);
cJSON *request3 = NULL;
msgid = ks_rpcmessage_create_request("app1", "badbunny", &parms3, &request3);
data = cJSON_PrintUnformatted(request3);
printf("\ntest01i request: %d\n%s\n\n", msgid, data);
cJSON *response3 = NULL;
ks_rpcmessage_create_response(request3, NULL, &response3);
data = cJSON_PrintUnformatted(response3);
printf("\ntest01 response3: %d\n%s\n\n", msgid, data);
ks_json_pool_free(data);
cJSON_Delete(request3);
cJSON_Delete(response3);
printf("**** testrpcmessages - test01 complete\n\n\n"); fflush(stdout);
}
void test02()
{
printf("**** testmessages - test02 start\n"); fflush(stdout);
printf("**** testmessages - test02 finished\n"); fflush(stdout);
return;
}
int main(int argc, char *argv[]) {
printf("testmessages - start\n");
int tests[100];
if (argc == 1) {
tests[0] = 1;
}
else {
for(int tix=1; tix<100 && tix<argc; ++tix) {
long i = strtol(argv[tix], NULL, 0);
tests[tix] = i;
}
}
ks_init();
ks_global_set_default_logger(7);
ks_status_t status;
status = ks_pool_open(&pool);
for (int tix=0; tix<argc; ++tix) {
if (tests[tix] == 1) {
ks_rpcmessage_init(pool);
test01();
continue;
}
if (tests[tix] == 2) {
ks_rpcmessage_init(pool);
test02();
continue;
}
}
return 0;
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论