diff --git a/CMakeLists.txt b/CMakeLists.txt index e644e875a0268e5803b7ade17c50af8b86eac13b..6ba5ba01588a009b8e19fd9dadadf27ed01d0e1b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,13 +1,8 @@ cmake_minimum_required(VERSION 2.8) project (dap_chain_global_db) -set(DAP_CHAIN_GLOBAL_DB_SRC - dap_chain_global_db.c - ) - -set(DAP_CHAIN_GLOBAL_DB_HDR - dap_chain_global_db.h - ) +file(GLOB DAP_CHAIN_GLOBAL_DB_SRC *.c) +file(GLOB DAP_CHAIN_GLOBAL_DB_HDR *.h) add_library(${PROJECT_NAME} STATIC ${DAP_CHAIN_GLOBAL_DB_SRC} ${DAP_CHAIN_GLOBAL_DB_HDR}) diff --git a/dap_chain_global_db.c b/dap_chain_global_db.c index 77823a1c8e1fd8578702d767b28e91e360d45e98..9e5f777c78d090a3daa80af180dad9e0653975a0 100644 --- a/dap_chain_global_db.c +++ b/dap_chain_global_db.c @@ -1,251 +1,55 @@ +#include "dap_chain_global_db_pvt.h" + #include <string.h> #include <stdio.h> -//#include "talloc.h" -#include "dap_chain_global_db.h" - -#define LOG_TAG "dap_global_db" -#define TDB_PREFIX_LEN 7 - -/* add single entry which is not supposed to be an array - e.g.: dap_db_add_record(&store_obj) -*/ -#define CALL2(a, b, ...) (a), (b) -#define dap_db_add_record(...) dap_db_merge(CALL2(__VA_ARGS__, 0)) - -int dap_db_init(const char *path) { - mem_ctx = talloc_new(NULL); - if (ldb_global_init() != 0) { - log_it(L_ERROR, "Couldn't initialize LDB's global information"); - return -1; - }; - if ((ldb = ldb_init(mem_ctx, NULL)) != LDB_SUCCESS) { - log_it(L_INFO, "ldb context initialized"); - char tdb_path[strlen(path) + TDB_PREFIX_LEN]; - memset(tdb_path, '\0', strlen(path) + TDB_PREFIX_LEN); - strcat(tdb_path, "tdb://"); // using tdb for simplicity, no need for separate LDAP server - strcat(tdb_path, path); - struct ldb_result *data_message; - if (ldb_connect(ldb, tdb_path, 0, NULL) != LDB_SUCCESS) { - log_it(L_ERROR, "Couldn't connect to database"); - return 1; - } - dap_db_path = strdup(tdb_path); - const char *query = "(dn=*)"; - if (ldb_search(ldb, mem_ctx, &data_message, NULL, LDB_SCOPE_DEFAULT, NULL, query) != LDB_SUCCESS) { - log_it(L_ERROR, "Database querying failed"); - return 2; - } - struct ldb_message *msg; - if (data_message->count == 0) { - // level 1: section record - msg = ldb_msg_new(ldb); - msg->dn = ldb_dn_new(mem_ctx, ldb, "dc=kelvin_nodes"); - ldb_msg_add_string(msg, "dc", "kelvin_nodes"); - ldb_msg_add_string(msg, "objectClass", "top"); - ldb_msg_add_string(msg, "objectClass", "section"); - dap_db_add_msg(msg); - talloc_free(msg->dn); - talloc_free(msg); - - // level 2: group record - msg = ldb_msg_new(ldb); - msg->dn = ldb_dn_new(mem_ctx, ldb, "ou=addrs_leased,dc=kelvin_nodes"); - ldb_msg_add_string(msg, "ou", "addrs_leased"); - ldb_msg_add_string(msg, "objectClass", "group"); - ldb_msg_add_string(msg, "description", "Whitelist of Kelvin blockchain nodes"); - dap_db_add_msg(msg); - talloc_free(msg->dn); - talloc_free(msg); - } - talloc_free(data_message); - return 0; - } - else { - log_it(L_ERROR, "Couldn't initialize LDB context"); - return -2; - } -} -int dap_db_add_msg(struct ldb_message *msg) { - if (ldb_msg_sanity_check(ldb, msg) != LDB_SUCCESS) { - log_it(L_ERROR, "LDB message is inconsistent: %s", ldb_errstring(ldb) ); - return -1; - } - ldb_transaction_start(ldb); - int status = ldb_add(ldb, msg); - if (status != LDB_SUCCESS) { - if (status == LDB_ERR_ENTRY_ALREADY_EXISTS) { - log_it(L_INFO, "Entry %s already present, skipped", ldb_dn_get_linearized(msg->dn) ); - } - else { - log_it(L_ERROR, "LDB adding error: %s", ldb_errstring(ldb) ); - } - ldb_transaction_cancel(ldb); - return -2; - } - else { - ldb_transaction_commit(ldb); - log_it(L_INFO, "Entry %s added", ldb_dn_get_linearized(msg->dn) ); - return 0; +int dap_chain_global_db_init(const char *a_storage_path) +{ + if(a_storage_path) + { + int res = dap_db_init(a_storage_path); + return res; } + return -1; } -/* path is supposed to have been obtained by smth like - dap_config_get_item_str(g_config, "resources", "dap_global_db_path"); -*/ -pdap_store_obj_t dap_db_read_data(void) { - struct ldb_result *data_message; - const char *query = "(objectClass=addr_leased)"; - if (ldb_connect(ldb, dap_db_path, LDB_FLG_RDONLY, NULL) != LDB_SUCCESS) { - log_it(L_ERROR, "Couldn't connect to database"); - return NULL; - } - if (ldb_search(ldb, NULL, &data_message, NULL, LDB_SCOPE_DEFAULT, NULL, query) != LDB_SUCCESS) { - log_it(L_ERROR, "Database querying failed"); - return NULL; - } - log_it(L_INFO, "Obtained binary data, %d entries", data_message->count); - - pdap_store_obj_t store_data =DAP_NEW_Z_SIZE(dap_store_obj_t,data_message->count * sizeof(struct dap_store_obj) ); - if (store_data != NULL) { - log_it(L_INFO, "We're about to put entries into store objects"); - } - else { - log_it(L_ERROR, "Couldn't allocate memory, store objects unobtained"); - talloc_free(data_message); - return NULL; - } - dap_store_len = data_message->count; - int q; - for (q = 0; q < dap_store_len; ++q) { - store_data[q].section = "kelvin_nodes"; - store_data[q].group = "addrs_leased"; - store_data[q].type = 1; - store_data[q].key = strdup(ldb_msg_find_attr_as_string(data_message->msgs[q], "cn", NULL)); - store_data[q].value = strdup(ldb_msg_find_attr_as_string(data_message->msgs[q], "time", NULL)); - log_it(L_INFO, "Record %s stored successfully", ldb_dn_get_linearized(data_message->msgs[q]->dn) ); - } - talloc_free(data_message); - return store_data; +void dap_chain_global_db_deinit(void) +{ + dap_db_deinit(); } -/* Get the entire content without using query expression - * This function is highly dissuaded from being used - * */ -pdap_store_obj_t dap_db_read_file_data(const char *path) { - struct ldb_ldif *ldif_msg; - FILE *fs = fopen(path, "r"); - if (!fs) { - log_it(L_ERROR, "Can't open file %s", path); - return NULL; - } - pdap_store_obj_t store_data = (pdap_store_obj_t)malloc(256 * sizeof(dap_store_obj_t)); - if (store_data != NULL) { - log_it(L_INFO, "We're about to put entries in store objects"); - } - else { - log_it(L_ERROR, "Couldn't allocate memory, store objects unobtained"); +/** + * get entry from + */ +char * dap_chain_global_db_get(const char *a_key) +{ + char *str = NULL; + int count = 0; + if(!a_key) return NULL; - } - - int q = 0; - for (ldif_msg = ldb_ldif_read_file(ldb, fs); ldif_msg; ldif_msg = ldb_ldif_read_file(ldb, fs), q++) { - if (q % 256 == 0) { - store_data = (pdap_store_obj_t)realloc(store_data, (q + 256) * sizeof(dap_store_obj_t)); - } - /* if (ldif_msg->changetype == LDB_CHANGETYPE_ADD) { - / ... / - } */ // in case we gonna use extra LDIF functionality - const char *key = ldb_msg_find_attr_as_string(ldif_msg->msg, "cn", NULL); - if (key != NULL) { - store_data[q].section = "kelvin_nodes"; - store_data[q].group = "addrs_leased"; - store_data[q].type = 1; - store_data[q].key = strdup(key); - store_data[q].value = strdup(ldb_msg_find_attr_as_string(ldif_msg->msg, "time", NULL)); - log_it(L_INFO, "Record %s stored successfully", ldb_dn_get_linearized(ldif_msg->msg->dn) ); - } - ldb_ldif_read_free(ldb, ldif_msg); - } - return store_data; + int a = strlen("(cn=key2)(objectClass=addr_leased)"); + char query[32 + strlen(a_key)]; + sprintf(query, "(cn=%s)(objectClass=addr_leased)", a_key); + pdap_store_obj_t store_data = dap_db_read_data(query, &count); //"(objectClass=addr_leased),cn=key1"); + if(count == 1 && store_data && !strcmp(store_data->key, a_key)) + str = (store_data->value) ? strdup(store_data->value) : NULL; + dab_db_free_pdap_store_obj_t(store_data); + return str; +} + +bool dap_chain_global_db_set(const char *a_key, const char *a_value) +{ + pdap_store_obj_t store_data = DAP_NEW_Z_SIZE(dap_store_obj_t, sizeof(struct dap_store_obj)); + store_data->key = (char*) a_key; + store_data->value = (char*) a_value; + int res = dap_db_merge(store_data, 1); + DAP_DELETE(store_data); + if(!res) + return true; + return false; } /* - * Add multiple entries received from remote node to local database. - * Since we don't know the size, it must be supplied too + dap_chain_global_db_load () + dap_chain_global_db_save() */ -int dap_db_merge(pdap_store_obj_t store_obj, int dap_store_size) { - if (store_obj == NULL) { - log_it(L_ERROR, "Invalid Dap store objects passed"); - return -1; - } - if (ldb_connect(ldb, dap_db_path, 0, NULL) != LDB_SUCCESS) { - log_it(L_ERROR, "Couldn't connect to database"); - return -2; - } - log_it(L_INFO, "We're about to put %d records into database", dap_store_size); - struct ldb_message *msg; - int q; - if (dap_store_size == 0) { - dap_store_size = 1; - } - for (q = 0; q < dap_store_size; q++) { - // level 3: leased address, single whitelist entity - msg = ldb_msg_new(ldb); - char dn[128]; - memset(dn, '\0', 128); - strcat(dn, "cn="); - strcat(dn, store_obj[q].key); - strcat(dn, ",ou=addrs_leased,dc=kelvin_nodes"); - msg->dn = ldb_dn_new(mem_ctx, ldb, dn); - ldb_msg_add_string(msg, "cn", store_obj[q].key); - ldb_msg_add_string(msg, "objectClass", "addr_leased"); - ldb_msg_add_string(msg, "description", "Approved Kelvin node"); - ldb_msg_add_string(msg, "time", store_obj[q].value); - dap_db_add_msg(msg); - talloc_free(msg->dn); - talloc_free(msg); - } - return 0; -} - -/* serialization */ -dap_store_obj_pkt_t *dap_store_packet_single(pdap_store_obj_t store_obj) { - dap_store_obj_pkt_t *pkt = - (dap_store_obj_pkt_t*)calloc(1, sizeof(int) + 4 + strlen(store_obj->group) + strlen(store_obj->key) + strlen(store_obj->section) + strlen(store_obj->value)); - pkt->grp_size = strlen(store_obj->group) + 1; - pkt->name_size = strlen(store_obj->key) + 1; - pkt->sec_size = strlen(store_obj->section) + 1; - pkt->type = store_obj->type; - memcpy(pkt->data, &store_obj->section, pkt->sec_size); - memcpy(pkt->data+pkt->sec_size, &store_obj->group, pkt->grp_size); - memcpy(pkt->data+pkt->sec_size+pkt->grp_size, &store_obj->key, pkt->name_size); - memcpy(pkt->data+pkt->sec_size+pkt->grp_size+pkt->name_size, &store_obj->value, strlen(store_obj->value)+1); - return pkt; -} - -dap_store_obj_pkt_t *dap_store_packet_multiple(pdap_store_obj_t store_obj) { - dap_store_obj_pkt_t *pkt = - (dap_store_obj_pkt_t*)calloc(1, sizeof(int) + 2 + strlen(store_obj->group) + dap_store_len*(1+strlen(store_obj->key)) + strlen(store_obj->section) + dap_store_len*(1+strlen(store_obj->value))); - pkt->grp_size = strlen(store_obj[0].group) + 1; - pkt->name_size = strlen(store_obj[0].key) + 1; // useless here since it can differ from one store_obj to another - pkt->sec_size = strlen(store_obj[0].section) + 1; - pkt->type = store_obj[0].type; - memcpy(pkt->data, &store_obj[0].section, pkt->sec_size); - memcpy(pkt->data+pkt->sec_size, &store_obj[0].group, pkt->grp_size); - uint64_t offset = pkt->sec_size+pkt->grp_size; - int q; - for (q = 0; q < dap_store_len; ++q) { - memcpy(pkt->data + offset, &store_obj[q].key, strlen(store_obj[q].key) + 1); - offset += strlen(store_obj[q].key) + 1; - memcpy(pkt->data + offset, &store_obj[q].value, strlen(store_obj[q].value) + 1); - offset += strlen(store_obj[q].value) + 1; - } - return pkt; -} - -void dap_db_deinit() { - talloc_free(ldb); - talloc_free(mem_ctx); - free(dap_db_path); -} diff --git a/dap_chain_global_db.h b/dap_chain_global_db.h index d8e6525fc176de63609c95456cde84fd25cf9270..af31658edaee68be539ed09ba2eb0b285a9568d7 100644 --- a/dap_chain_global_db.h +++ b/dap_chain_global_db.h @@ -1,39 +1,12 @@ #pragma once +#include <stdbool.h> -#include <stdint.h> -#include "dap_common.h" -#include "ldb.h" +int dap_chain_global_db_init(const char *a_storage_path); -typedef struct dap_store_obj { - char *section; - char *group; - char *key; - uint8_t type; - char *value; -} DAP_ALIGN_PACKED dap_store_obj_t, *pdap_store_obj_t; +void dap_chain_global_db_deinit(); -typedef struct dap_store_obj_pkt { - uint8_t type; - uint8_t sec_size; - uint8_t grp_size; - uint8_t name_size; - uint8_t data[]; -} __attribute__((packed)) dap_store_obj_pkt_t; +char* dap_chain_global_db_get(const char *a_key); +bool dap_chain_global_db_set(const char *a_key, const char *a_value); -int dap_store_len = 0; // initialized only when reading from local db - -char *dap_db_path = NULL; - -static struct ldb_context *ldb = NULL; -static TALLOC_CTX *mem_ctx = NULL; - -int dap_db_init (const char*); -void dap_db_deinit (void); - -int dap_db_add_msg(struct ldb_message *); -int dap_db_merge(pdap_store_obj_t, int); - -pdap_store_obj_t dap_db_read_data (void); -pdap_store_obj_t dap_db_read_file_data (const char *); // state of emergency only, if LDB database is inaccessible -dap_store_obj_pkt_t *dap_store_packet_single(pdap_store_obj_t); -dap_store_obj_pkt_t *dap_store_packet_multiple(pdap_store_obj_t); +char* dap_chain_global_db_load(); +bool dap_chain_global_db_save(char *data); diff --git a/dap_chain_global_db_pvt.c b/dap_chain_global_db_pvt.c new file mode 100644 index 0000000000000000000000000000000000000000..c3a691c2b16385793260934a1a0cf5a8cef25f53 --- /dev/null +++ b/dap_chain_global_db_pvt.c @@ -0,0 +1,299 @@ +#include "dap_chain_global_db_pvt.h" + +#include <string.h> +#include <stdio.h> +//#include "talloc.h" + +#define LOG_TAG "dap_global_db" +#define TDB_PREFIX_LEN 7 + +static int dap_store_len = 0; // initialized only when reading from local db +static char *dap_db_path = NULL; + +#define CALL2(a, b, ...) (a), (b) +#define dap_db_add_record(...) dap_db_merge(CALL2(__VA_ARGS__, 0)) + +int dap_db_init(const char *path) +{ + mem_ctx = talloc_new(NULL); + if(ldb_global_init() != 0) { + log_it(L_ERROR, "Couldn't initialize LDB's global information"); + return -1; + }; + if((ldb = ldb_init(mem_ctx, NULL)) != LDB_SUCCESS) { + log_it(L_INFO, "ldb context initialized"); + char tdb_path[strlen(path) + TDB_PREFIX_LEN]; + memset(tdb_path, '\0', strlen(path) + TDB_PREFIX_LEN); + strcat(tdb_path, "tdb://"); // using tdb for simplicity, no need for separate LDAP server + strcat(tdb_path, path); + struct ldb_result *data_message; + if(ldb_connect(ldb, tdb_path, 0, NULL) != LDB_SUCCESS) { + log_it(L_ERROR, "Couldn't connect to database"); + return 1; + } + dap_db_path = strdup(tdb_path); + const char *query = "(dn=*)"; + if(ldb_search(ldb, mem_ctx, &data_message, NULL, LDB_SCOPE_DEFAULT, NULL, query) != LDB_SUCCESS) { + log_it(L_ERROR, "Database querying failed"); + return 2; + } + struct ldb_message *msg; + if(data_message->count == 0) { + // level 1: section record + msg = ldb_msg_new(ldb); + msg->dn = ldb_dn_new(mem_ctx, ldb, "dc=kelvin_nodes"); + ldb_msg_add_string(msg, "dc", "kelvin_nodes"); + ldb_msg_add_string(msg, "objectClass", "top"); + ldb_msg_add_string(msg, "objectClass", "section"); + dap_db_add_msg(msg); + talloc_free(msg->dn); + talloc_free(msg); + + // level 2: group record + msg = ldb_msg_new(ldb); + msg->dn = ldb_dn_new(mem_ctx, ldb, "ou=addrs_leased,dc=kelvin_nodes"); + ldb_msg_add_string(msg, "ou", "addrs_leased"); + ldb_msg_add_string(msg, "objectClass", "group"); + ldb_msg_add_string(msg, "description", "Whitelist of Kelvin blockchain nodes"); + dap_db_add_msg(msg); + talloc_free(msg->dn); + talloc_free(msg); + } + talloc_free(data_message); + return 0; + } + else { + log_it(L_ERROR, "Couldn't initialize LDB context"); + return -2; + } +} + +int dap_db_add_msg(struct ldb_message *msg) +{ + if(ldb_msg_sanity_check(ldb, msg) != LDB_SUCCESS) { + log_it(L_ERROR, "LDB message is inconsistent: %s", ldb_errstring(ldb)); + return -1; + } + ldb_transaction_start(ldb); + int status = ldb_add(ldb, msg); + // Delete the entry if it already exist and add again + if(status == LDB_ERR_ENTRY_ALREADY_EXISTS) { + ldb_delete(ldb, msg->dn); + status = ldb_add(ldb, msg); + } + if(status != LDB_SUCCESS) { + if(status == LDB_ERR_ENTRY_ALREADY_EXISTS) { + log_it(L_INFO, "Entry %s already present, skipped", ldb_dn_get_linearized(msg->dn)); + } + else { + log_it(L_ERROR, "LDB adding error: %s", ldb_errstring(ldb)); + } + ldb_transaction_cancel(ldb); + return -2; + } + else { + ldb_transaction_commit(ldb); + log_it(L_INFO, "Entry %s added", ldb_dn_get_linearized(msg->dn)); + return 0; + } +} + +/* path is supposed to have been obtained by smth like + dap_config_get_item_str(g_config, "resources", "dap_global_db_path"); + */ +pdap_store_obj_t dap_db_read_data(const char *query, int *count) +{ + struct ldb_result *data_message; + /* + CN commonName (2.5.4.3) + L localityName (2.5.4.7) + ST stateOrProvinceName (2.5.4.8) + O organizationName (2.5.4.10) + OU organizationalUnitName (2.5.4.11) + C countryName (2.5.4.6) + STREET streetAddress (2.5.4.9) + DC domainComponent (0.9.2342.19200300.100.1.25) + UID userId (0.9.2342.19200300.100.1.1) + */ + //const char *query = "(objectClass=addr_leased)"; + if(ldb_connect(ldb, dap_db_path, LDB_FLG_RDONLY, NULL) != LDB_SUCCESS) { + log_it(L_ERROR, "Couldn't connect to database"); + return NULL; + } + if(ldb_search(ldb, NULL, &data_message, NULL, LDB_SCOPE_DEFAULT, NULL, query) != LDB_SUCCESS) { + log_it(L_ERROR, "Database querying failed"); + return NULL; + } + log_it(L_INFO, "Obtained binary data, %d entries", data_message->count); + + pdap_store_obj_t store_data = DAP_NEW_Z_SIZE(dap_store_obj_t, data_message->count * sizeof(struct dap_store_obj)); + if(store_data != NULL) { + log_it(L_INFO, "We're about to put entries into store objects"); + } + else { + log_it(L_ERROR, "Couldn't allocate memory, store objects unobtained"); + talloc_free(data_message); + return NULL; + } + dap_store_len = data_message->count; + int q; + for(q = 0; q < dap_store_len; ++q) { + store_data[q].section = "kelvin_nodes"; + store_data[q].group = "addrs_leased"; + store_data[q].type = 1; + store_data[q].key = strdup(ldb_msg_find_attr_as_string(data_message->msgs[q], "cn", NULL)); + store_data[q].value = strdup(ldb_msg_find_attr_as_string(data_message->msgs[q], "time", NULL)); + log_it(L_INFO, "Record %s stored successfully", ldb_dn_get_linearized(data_message->msgs[q]->dn)); + } + if(count) + *count = data_message->count; + talloc_free(data_message); + return store_data; +} + +/** + * clean memory + */ +void dab_db_free_pdap_store_obj_t(pdap_store_obj_t store_data) +{ + if(!store_data) + return; + free(store_data->key); + free(store_data->value); + DAP_DELETE(store_data); +} + +/* Get the entire content without using query expression + * This function is highly dissuaded from being used + * */ +pdap_store_obj_t dap_db_read_file_data(const char *path) +{ + struct ldb_ldif *ldif_msg; + FILE *fs = fopen(path, "r"); + if(!fs) { + log_it(L_ERROR, "Can't open file %s", path); + return NULL; + } + pdap_store_obj_t store_data = (pdap_store_obj_t) malloc(256 * sizeof(dap_store_obj_t)); + if(store_data != NULL) { + log_it(L_INFO, "We're about to put entries in store objects"); + } + else { + log_it(L_ERROR, "Couldn't allocate memory, store objects unobtained"); + fclose(fs); + return NULL; + } + + int q = 0; + for(ldif_msg = ldb_ldif_read_file(ldb, fs); ldif_msg; ldif_msg = ldb_ldif_read_file(ldb, fs), q++) { + if(q % 256 == 0) { + store_data = (pdap_store_obj_t) realloc(store_data, (q + 256) * sizeof(dap_store_obj_t)); + } + /* if (ldif_msg->changetype == LDB_CHANGETYPE_ADD) { + / ... / + } */ // in case we gonna use extra LDIF functionality + const char *key = ldb_msg_find_attr_as_string(ldif_msg->msg, "cn", NULL); + if(key != NULL) { + store_data[q].section = "kelvin_nodes"; + store_data[q].group = "addrs_leased"; + store_data[q].type = 1; + store_data[q].key = strdup(key); + store_data[q].value = strdup(ldb_msg_find_attr_as_string(ldif_msg->msg, "time", NULL)); + log_it(L_INFO, "Record %s stored successfully", ldb_dn_get_linearized(ldif_msg->msg->dn)); + } + ldb_ldif_read_free(ldb, ldif_msg); + } + fclose(fs); + return store_data; +} + +/* + * Add multiple entries received from remote node to local database. + * Since we don't know the size, it must be supplied too + */ +int dap_db_merge(pdap_store_obj_t store_obj, int dap_store_size) +{ + if(store_obj == NULL) { + log_it(L_ERROR, "Invalid Dap store objects passed"); + return -1; + } + if(ldb_connect(ldb, dap_db_path, 0, NULL) != LDB_SUCCESS) { + log_it(L_ERROR, "Couldn't connect to database"); + return -2; + } + log_it(L_INFO, "We're about to put %d records into database", dap_store_size); + struct ldb_message *msg; + int q; + if(dap_store_size == 0) { + dap_store_size = 1; + } + for(q = 0; q < dap_store_size; q++) { + // level 3: leased address, single whitelist entity + msg = ldb_msg_new(ldb); + char dn[128]; + memset(dn, '\0', 128); + strcat(dn, "cn="); + strcat(dn, store_obj[q].key); + strcat(dn, ",ou=addrs_leased,dc=kelvin_nodes"); + msg->dn = ldb_dn_new(mem_ctx, ldb, dn); + ldb_msg_add_string(msg, "cn", store_obj[q].key); + ldb_msg_add_string(msg, "objectClass", "addr_leased"); + ldb_msg_add_string(msg, "description", "Approved Kelvin node"); + ldb_msg_add_string(msg, "time", store_obj[q].value); + dap_db_add_msg(msg); + talloc_free(msg->dn); + talloc_free(msg); + } + return 0; +} + +/* serialization */ +dap_store_obj_pkt_t *dap_store_packet_single(pdap_store_obj_t store_obj) +{ + dap_store_obj_pkt_t *pkt = + (dap_store_obj_pkt_t*) calloc(1, + sizeof(int) + 4 + strlen(store_obj->group) + strlen(store_obj->key) + strlen(store_obj->section) + + strlen(store_obj->value)); + pkt->grp_size = strlen(store_obj->group) + 1; + pkt->name_size = strlen(store_obj->key) + 1; + pkt->sec_size = strlen(store_obj->section) + 1; + pkt->type = store_obj->type; + memcpy(pkt->data, &store_obj->section, pkt->sec_size); + memcpy(pkt->data + pkt->sec_size, &store_obj->group, pkt->grp_size); + memcpy(pkt->data + pkt->sec_size + pkt->grp_size, &store_obj->key, pkt->name_size); + memcpy(pkt->data + pkt->sec_size + pkt->grp_size + pkt->name_size, &store_obj->value, strlen(store_obj->value) + 1); + return pkt; +} + +dap_store_obj_pkt_t *dap_store_packet_multiple(pdap_store_obj_t store_obj) +{ + dap_store_obj_pkt_t *pkt = + (dap_store_obj_pkt_t*) calloc(1, + sizeof(int) + 2 + strlen(store_obj->group) + dap_store_len * (1 + strlen(store_obj->key)) + + strlen(store_obj->section) + dap_store_len * (1 + strlen(store_obj->value))); + pkt->grp_size = strlen(store_obj[0].group) + 1; + pkt->name_size = strlen(store_obj[0].key) + 1; // useless here since it can differ from one store_obj to another + pkt->sec_size = strlen(store_obj[0].section) + 1; + pkt->type = store_obj[0].type; + memcpy(pkt->data, &store_obj[0].section, pkt->sec_size); + memcpy(pkt->data + pkt->sec_size, &store_obj[0].group, pkt->grp_size); + uint64_t offset = pkt->sec_size + pkt->grp_size; + int q; + for(q = 0; q < dap_store_len; ++q) { + memcpy(pkt->data + offset, &store_obj[q].key, strlen(store_obj[q].key) + 1); + offset += strlen(store_obj[q].key) + 1; + memcpy(pkt->data + offset, &store_obj[q].value, strlen(store_obj[q].value) + 1); + offset += strlen(store_obj[q].value) + 1; + } + return pkt; +} + +void dap_db_deinit() +{ + talloc_free(ldb); + talloc_free(mem_ctx); + free(dap_db_path); + ldb = NULL; + mem_ctx = NULL; + dap_db_path = NULL; +} diff --git a/dap_chain_global_db_pvt.h b/dap_chain_global_db_pvt.h new file mode 100644 index 0000000000000000000000000000000000000000..3fbbac3ca913f63cdcc01be63483f8af252df469 --- /dev/null +++ b/dap_chain_global_db_pvt.h @@ -0,0 +1,38 @@ +#pragma once + +#include <stdint.h> +#include "dap_common.h" +#include "ldb.h" + +typedef struct dap_store_obj { + char *section; + char *group; + char *key; + uint8_t type; + char *value; +} DAP_ALIGN_PACKED dap_store_obj_t, *pdap_store_obj_t; + +typedef struct dap_store_obj_pkt { + uint8_t type; + uint8_t sec_size; + uint8_t grp_size; + uint8_t name_size; + uint8_t data[]; +} __attribute__((packed)) dap_store_obj_pkt_t; + +static struct ldb_context *ldb = NULL; +static TALLOC_CTX *mem_ctx = NULL; + +int dap_db_init (const char*); +void dap_db_deinit(void); + +int dap_db_add_msg(struct ldb_message *); +int dap_db_merge(pdap_store_obj_t, int); + +pdap_store_obj_t dap_db_read_data(const char *query, int *count); +pdap_store_obj_t dap_db_read_file_data(const char *); // state of emergency only, if LDB database is inaccessible +dap_store_obj_pkt_t *dap_store_packet_single(pdap_store_obj_t); +dap_store_obj_pkt_t *dap_store_packet_multiple(pdap_store_obj_t); + +void dab_db_free_pdap_store_obj_t(pdap_store_obj_t store_data); +