intégration des logiciels tier comme NanoMQ ainsi que les fichiers json de score
This commit is contained in:
@ -0,0 +1,80 @@
|
||||
#ifndef NANOLIB_ACL_CONF_H
|
||||
#define NANOLIB_ACL_CONF_H
|
||||
|
||||
#include <string.h>
|
||||
#include "nng/nng.h"
|
||||
#include "nng/supplemental/nanolib/cJSON.h"
|
||||
|
||||
typedef enum {
|
||||
ACL_ALLOW,
|
||||
ACL_DENY,
|
||||
} acl_permit;
|
||||
|
||||
typedef enum {
|
||||
ACL_USERNAME,
|
||||
ACL_CLIENTID,
|
||||
ACL_IPADDR,
|
||||
ACL_AND,
|
||||
ACL_OR,
|
||||
ACL_NONE,
|
||||
} acl_rule_type;
|
||||
|
||||
typedef enum {
|
||||
ACL_PUB,
|
||||
ACL_SUB,
|
||||
ACL_ALL,
|
||||
} acl_action_type;
|
||||
|
||||
typedef enum {
|
||||
ACL_RULE_SINGLE_STRING,
|
||||
ACL_RULE_STRING_ARRAY,
|
||||
ACL_RULE_INT_ARRAY,
|
||||
ACL_RULE_ALL,
|
||||
} acl_value_type;
|
||||
|
||||
typedef struct acl_rule_ct {
|
||||
acl_value_type type;
|
||||
size_t count;
|
||||
union {
|
||||
char * str;
|
||||
char **str_array;
|
||||
int * int_array;
|
||||
} value;
|
||||
} acl_rule_ct;
|
||||
|
||||
typedef struct {
|
||||
acl_rule_type rule_type;
|
||||
acl_rule_ct rule_ct;
|
||||
} acl_sub_rule;
|
||||
|
||||
typedef struct {
|
||||
size_t count;
|
||||
acl_sub_rule **rules;
|
||||
} acl_sub_rules_array;
|
||||
|
||||
typedef struct acl_rule {
|
||||
size_t id;
|
||||
acl_permit permit;
|
||||
acl_rule_type rule_type;
|
||||
union {
|
||||
acl_rule_ct ct;
|
||||
acl_sub_rules_array array;
|
||||
} rule_ct;
|
||||
acl_action_type action;
|
||||
size_t topic_count;
|
||||
char ** topics;
|
||||
} acl_rule;
|
||||
|
||||
typedef struct {
|
||||
bool enable;
|
||||
size_t rule_count;
|
||||
acl_rule **rules;
|
||||
} conf_acl;
|
||||
|
||||
extern void conf_acl_parse(conf_acl *acl, const char *path);
|
||||
extern void conf_acl_init(conf_acl *acl);
|
||||
extern void conf_acl_destroy(conf_acl *acl);
|
||||
extern bool acl_parse_json_rule(cJSON *obj, size_t id, acl_rule **rule);
|
||||
extern void print_acl_conf(conf_acl *acl);
|
||||
|
||||
#endif /* NANOLIB_ACL_CONF_H */
|
@ -0,0 +1,21 @@
|
||||
#ifndef BASE64_H
|
||||
#define BASE64_H
|
||||
#include "nng/nng.h"
|
||||
|
||||
#define BASE64_ENCODE_OUT_SIZE(s) ((unsigned int)((((s) + 2) / 3) * 4 + 1))
|
||||
#define BASE64_DECODE_OUT_SIZE(s) ((unsigned int)(((s) / 4) * 3))
|
||||
|
||||
/*
|
||||
* out is null-terminated encode string.
|
||||
* return values is out length, exclusive terminating `\0'
|
||||
*/
|
||||
NNG_DECL unsigned int
|
||||
base64_encode(const unsigned char *in, unsigned int inlen, char *out);
|
||||
|
||||
/*
|
||||
* return values is out length
|
||||
*/
|
||||
NNG_DECL unsigned int
|
||||
base64_decode(const char *in, unsigned int inlen, unsigned char *out);
|
||||
|
||||
#endif /* BASE64_H */
|
@ -0,0 +1,116 @@
|
||||
# ifndef BINARY_SEARCH_H
|
||||
# define BINARY_SEARCH_H
|
||||
|
||||
#include "cvector.h"
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
* @brief binary_search - vec is an dynamic array
|
||||
* @param l - it is the left boundry of the vec
|
||||
* @param index - index is the result we search
|
||||
* @param e - e contain message we want to search
|
||||
* @param cmp - cmp is a compare method
|
||||
* @return true or false, if we find or not
|
||||
*/
|
||||
static inline bool
|
||||
_binary_search(
|
||||
void **vec, int l, size_t *index, void *e, int (*cmp)(void *x, void *y))
|
||||
{
|
||||
|
||||
int r = cvector_size(vec) - 1;
|
||||
int m = 0;
|
||||
|
||||
// if we do not find the element
|
||||
// vec = [0, 1, 3, 4], e = 2 ,
|
||||
// m will be 2, index = 2 ok
|
||||
// vec = [0, 1, 2, 4], e = 3 ,
|
||||
// m will be 2, index = 2 error,
|
||||
// index = 2 + add(1) ok
|
||||
int add = 0;
|
||||
|
||||
// log_info("l: %d", l);
|
||||
// log_info("r: %d", r);
|
||||
|
||||
while ( l <= r) {
|
||||
m = l + (r - l) / 2;
|
||||
|
||||
// Check if x is present at mid
|
||||
if (cmp(vec[m], e) == 0) {
|
||||
*index = m;
|
||||
return true;
|
||||
}
|
||||
// log_info("m: %d", m);
|
||||
|
||||
// If x greater, ignore left half
|
||||
if (cmp(vec[m], e) < 0) {
|
||||
l = m + 1;
|
||||
add = 1;
|
||||
|
||||
// If x is smaller, ignore right half
|
||||
} else {
|
||||
r = m - 1;
|
||||
add = 0;
|
||||
}
|
||||
}
|
||||
// log_info("m: %d", m);
|
||||
|
||||
// if we reach here, then element was
|
||||
// not present
|
||||
*index = m + add;
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
_binary_search_uint32(uint32_t *vec, int l, size_t *index, uint32_t e,
|
||||
int (*cmp)(uint32_t x, uint32_t y))
|
||||
{
|
||||
int r = cvector_size(vec) - 1;
|
||||
int m = 0;
|
||||
|
||||
// if we do not find the element
|
||||
// vec = [0, 1, 3, 4], e = 2 ,
|
||||
// m will be 2, index = 2 ok
|
||||
// vec = [0, 1, 2, 4], e = 3 ,
|
||||
// m will be 2, index = 2 error,
|
||||
// index = 2 + add(1) ok
|
||||
int add = 0;
|
||||
|
||||
// log_info("l: %d", l);
|
||||
// log_info("r: %d", r);
|
||||
|
||||
while ( l <= r) {
|
||||
m = l + (r - l) / 2;
|
||||
|
||||
// Check if x is present at mid
|
||||
if (cmp(vec[m], e) == 0) {
|
||||
*index = m;
|
||||
return true;
|
||||
}
|
||||
// log_info("m: %d", m);
|
||||
|
||||
// If x greater, ignore left half
|
||||
if (cmp(vec[m], e) < 0) {
|
||||
l = m + 1;
|
||||
add = 1;
|
||||
|
||||
// If x is smaller, ignore right half
|
||||
} else {
|
||||
r = m - 1;
|
||||
add = 0;
|
||||
}
|
||||
}
|
||||
// log_info("m: %d", m);
|
||||
|
||||
// if we reach here, then element was
|
||||
// not present
|
||||
*index = m + add;
|
||||
return false;
|
||||
}
|
||||
|
||||
#define binary_search(vec, l, index, e, cmp) \
|
||||
_binary_search(vec, l, index, e, cmp)
|
||||
#define binary_search_uint32(vec, l, index, e, cmp) \
|
||||
_binary_search_uint32(vec, l, index, e, cmp)
|
||||
|
||||
#endif
|
@ -0,0 +1,62 @@
|
||||
#ifndef BLF_H
|
||||
#define BLF_H
|
||||
#include "nng/nng.h"
|
||||
#include "nng/supplemental/nanolib/conf.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct blf_object blf_object;
|
||||
typedef void (*blf_cb)(blf_object *arg);
|
||||
|
||||
typedef enum {
|
||||
WRITE_TO_NORMAL1,
|
||||
WRITE_TO_TEMP1,
|
||||
} blf_write_type;
|
||||
|
||||
typedef struct {
|
||||
uint32_t start_idx;
|
||||
uint32_t end_idx;
|
||||
char *filename;
|
||||
} blf_file_range;
|
||||
|
||||
typedef struct {
|
||||
blf_file_range **range;
|
||||
int size;
|
||||
int start; // file range start index
|
||||
} blf_file_ranges;
|
||||
|
||||
typedef struct {
|
||||
uint8_t *data;
|
||||
uint32_t size;
|
||||
} blf_data_packet;
|
||||
|
||||
struct blf_object {
|
||||
uint64_t *keys;
|
||||
uint8_t **darray;
|
||||
uint32_t *dsize;
|
||||
uint32_t size;
|
||||
nng_aio *aio;
|
||||
void *arg;
|
||||
blf_file_ranges *ranges;
|
||||
blf_write_type type;
|
||||
};
|
||||
|
||||
blf_object *blf_object_alloc(uint64_t *keys, uint8_t **darray, uint32_t *dsize,
|
||||
uint32_t size, nng_aio *aio, void *arg);
|
||||
void blf_object_free(blf_object *elem);
|
||||
|
||||
int blf_write_batch_async(blf_object *elem);
|
||||
int blf_write_launcher(conf_blf *conf);
|
||||
|
||||
const char *blf_find(uint64_t key);
|
||||
const char **blf_find_span(
|
||||
uint64_t start_key, uint64_t end_key, uint32_t *size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -0,0 +1,294 @@
|
||||
/*
|
||||
Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef cJSON__h
|
||||
#define cJSON__h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#if !defined(__WINDOWS__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32))
|
||||
#define __WINDOWS__
|
||||
#endif
|
||||
|
||||
#ifdef __WINDOWS__
|
||||
|
||||
/* When compiling for windows, we specify a specific calling convention to avoid issues where we are being called from a project with a different default calling convention. For windows you have 3 define options:
|
||||
|
||||
CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever dllexport symbols
|
||||
CJSON_EXPORT_SYMBOLS - Define this on library build when you want to dllexport symbols (default)
|
||||
CJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol
|
||||
|
||||
For *nix builds that support visibility attribute, you can define similar behavior by
|
||||
|
||||
setting default visibility to hidden by adding
|
||||
-fvisibility=hidden (for gcc)
|
||||
or
|
||||
-xldscope=hidden (for sun cc)
|
||||
to CFLAGS
|
||||
|
||||
then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJSON_EXPORT_SYMBOLS does
|
||||
|
||||
*/
|
||||
|
||||
#define CJSON_CDECL __cdecl
|
||||
#define CJSON_STDCALL __stdcall
|
||||
|
||||
/* export symbols by default, this is necessary for copy pasting the C and header file */
|
||||
#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && !defined(CJSON_EXPORT_SYMBOLS)
|
||||
#define CJSON_EXPORT_SYMBOLS
|
||||
#endif
|
||||
|
||||
#if defined(CJSON_HIDE_SYMBOLS)
|
||||
#define CJSON_PUBLIC(type) type CJSON_STDCALL
|
||||
#elif defined(CJSON_EXPORT_SYMBOLS)
|
||||
#define CJSON_PUBLIC(type) __declspec(dllexport) type CJSON_STDCALL
|
||||
#elif defined(CJSON_IMPORT_SYMBOLS)
|
||||
#define CJSON_PUBLIC(type) __declspec(dllimport) type CJSON_STDCALL
|
||||
#endif
|
||||
#else /* !__WINDOWS__ */
|
||||
#define CJSON_CDECL
|
||||
#define CJSON_STDCALL
|
||||
|
||||
|
||||
#if defined(NNG_SHARED_LIB) && defined(NNG_HIDDEN_VISIBILITY)
|
||||
#define CJSON_PUBLIC(type) __attribute__((visibility("default"))) type
|
||||
#else
|
||||
#define CJSON_PUBLIC(type) type
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* project version */
|
||||
#define CJSON_VERSION_MAJOR 1
|
||||
#define CJSON_VERSION_MINOR 7
|
||||
#define CJSON_VERSION_PATCH 15
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/* cJSON Types: */
|
||||
#define cJSON_Invalid (0)
|
||||
#define cJSON_False (1 << 0)
|
||||
#define cJSON_True (1 << 1)
|
||||
#define cJSON_NULL (1 << 2)
|
||||
#define cJSON_Number (1 << 3)
|
||||
#define cJSON_String (1 << 4)
|
||||
#define cJSON_Array (1 << 5)
|
||||
#define cJSON_Object (1 << 6)
|
||||
#define cJSON_Raw (1 << 7) /* raw json */
|
||||
|
||||
#define cJSON_IsReference 256
|
||||
#define cJSON_StringIsConst 512
|
||||
|
||||
/* The cJSON structure: */
|
||||
typedef struct cJSON
|
||||
{
|
||||
/* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
|
||||
struct cJSON *next;
|
||||
struct cJSON *prev;
|
||||
/* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
|
||||
struct cJSON *child;
|
||||
|
||||
/* The type of the item, as above. */
|
||||
int type;
|
||||
|
||||
/* The item's string, if type==cJSON_String and type == cJSON_Raw */
|
||||
char *valuestring;
|
||||
/* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */
|
||||
int valueint;
|
||||
/* The item's number, if type==cJSON_Number */
|
||||
double valuedouble;
|
||||
|
||||
/* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
|
||||
char *string;
|
||||
} cJSON;
|
||||
|
||||
typedef struct cJSON_Hooks
|
||||
{
|
||||
/* malloc/free are CDECL on Windows regardless of the default calling convention of the compiler, so ensure the hooks allow passing those functions directly. */
|
||||
void *(CJSON_CDECL *malloc_fn)(size_t sz);
|
||||
void (CJSON_CDECL *free_fn)(void *ptr);
|
||||
} cJSON_Hooks;
|
||||
|
||||
typedef int cJSON_bool;
|
||||
|
||||
/* Limits how deeply nested arrays/objects can be before cJSON rejects to parse them.
|
||||
* This is to prevent stack overflows. */
|
||||
#ifndef CJSON_NESTING_LIMIT
|
||||
#define CJSON_NESTING_LIMIT 1000
|
||||
#endif
|
||||
|
||||
/* returns the version of cJSON as a string */
|
||||
CJSON_PUBLIC(const char*) cJSON_Version(void);
|
||||
|
||||
/* Supply malloc, realloc and free functions to cJSON */
|
||||
CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks);
|
||||
|
||||
/* Memory Management: the caller is always responsible to free the results from all variants of cJSON_Parse (with cJSON_Delete) and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The exception is cJSON_PrintPreallocated, where the caller has full responsibility of the buffer. */
|
||||
/* Supply a block of JSON, and this returns a cJSON object you can interrogate. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_ParseWithLength(const char *value, size_t buffer_length);
|
||||
/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
|
||||
/* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error so will match cJSON_GetErrorPtr(). */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_ParseWithLengthOpts(const char *value, size_t buffer_length, const char **return_parse_end, cJSON_bool require_null_terminated);
|
||||
|
||||
/* Render a cJSON entity to text for transfer/storage. */
|
||||
CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item);
|
||||
/* Render a cJSON entity to text for transfer/storage without any formatting. */
|
||||
CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item);
|
||||
/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */
|
||||
CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt);
|
||||
/* Render a cJSON entity to text using a buffer already allocated in memory with given length. Returns 1 on success and 0 on failure. */
|
||||
/* NOTE: cJSON is not always 100% accurate in estimating how much memory it will use, so to be safe allocate 5 bytes more than you actually need */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format);
|
||||
/* Delete a cJSON entity and all subentities. */
|
||||
CJSON_PUBLIC(void) cJSON_Delete(cJSON *item);
|
||||
|
||||
/* Returns the number of items in an array (or object). */
|
||||
CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array);
|
||||
/* Retrieve item number "index" from array "array". Returns NULL if unsuccessful. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index);
|
||||
/* Get item "string" from object. Case insensitive. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string);
|
||||
/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
|
||||
CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void);
|
||||
|
||||
/* Check item type and return its value */
|
||||
CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON * const item);
|
||||
CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON * const item);
|
||||
|
||||
/* These functions check the type of an item */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item);
|
||||
|
||||
/* These calls create a cJSON item of the appropriate type. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string);
|
||||
/* raw json */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void);
|
||||
|
||||
/* Create a string where valuestring references a string so
|
||||
* it will not be freed by cJSON_Delete */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string);
|
||||
/* Create an object/array that only references it's elements so
|
||||
* they will not be freed by cJSON_Delete */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child);
|
||||
|
||||
/* These utilities create an Array of count items.
|
||||
* The parameter count cannot be greater than the number of elements in the number array, otherwise array access will be out of bounds.*/
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int count);
|
||||
|
||||
/* Append item to the specified array/object. */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);
|
||||
/* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object.
|
||||
* WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) is zero before
|
||||
* writing to `item->string` */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item);
|
||||
/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item);
|
||||
|
||||
/* Remove/Detach items from Arrays/Objects. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which);
|
||||
CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string);
|
||||
CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string);
|
||||
CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string);
|
||||
|
||||
/* Update array items. */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object,const char *string,cJSON *newitem);
|
||||
|
||||
/* Duplicate a cJSON item */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse);
|
||||
/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will
|
||||
* need to be released. With recurse!=0, it will duplicate any children connected to the item.
|
||||
* The item->next and ->prev pointers are always zero on return from Duplicate. */
|
||||
/* Recursively compare two cJSON items for equality. If either a or b is NULL or invalid, they will be considered unequal.
|
||||
* case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive);
|
||||
|
||||
/* Minify a strings, remove blank characters(such as ' ', '\t', '\r', '\n') from strings.
|
||||
* The input pointer json cannot point to a read-only address area, such as a string constant,
|
||||
* but should point to a readable and writable address area. */
|
||||
CJSON_PUBLIC(void) cJSON_Minify(char *json);
|
||||
|
||||
/* Helper functions for creating and adding items to an object at the same time.
|
||||
* They return the added item or NULL on failure. */
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name);
|
||||
|
||||
/* When assigning an integer value, it needs to be propagated to valuedouble too. */
|
||||
#define cJSON_SetIntValue(object, number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number))
|
||||
/* helper for the cJSON_SetNumberValue macro */
|
||||
CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number);
|
||||
#define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number))
|
||||
/* Change the valuestring of a cJSON_String object, only takes effect when type of object is cJSON_String */
|
||||
CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring);
|
||||
|
||||
/* Macro for iterating over an array or object */
|
||||
#define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next)
|
||||
|
||||
/* malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks */
|
||||
CJSON_PUBLIC(void *) cJSON_malloc(size_t size);
|
||||
CJSON_PUBLIC(void) cJSON_free(void *object);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -0,0 +1,37 @@
|
||||
//
|
||||
// Copyright 2020 NanoMQ Team, Inc. <jaylin@emqx.io>
|
||||
//
|
||||
// This software is supplied under the terms of the MIT License, a
|
||||
// copy of which should be located in the distribution where this
|
||||
// file was obtained (LICENSE.txt). A copy of the license may also be
|
||||
// found online at https://opensource.org/licenses/MIT.
|
||||
//
|
||||
#include <sys/types.h>
|
||||
|
||||
#define CMD_BUFF_LEN 1024
|
||||
extern char *cmd_output_buff;
|
||||
extern int cmd_output_len;
|
||||
|
||||
#ifndef NNG_PLATFORM_WINDOWS
|
||||
|
||||
#define CMD_RUN(cmd) \
|
||||
do { \
|
||||
ret = cmd_run(cmd); \
|
||||
if (ret < 0) \
|
||||
goto err; \
|
||||
} while (0)
|
||||
|
||||
#define CMD_FRUN(fcmd, ...) \
|
||||
do { \
|
||||
ret = nano_cmd_frun(fcmd, __VA_ARGS__); \
|
||||
if (ret < 0) \
|
||||
goto err; \
|
||||
} while (0)
|
||||
|
||||
extern int nano_cmd_run(const char *cmd);
|
||||
extern int nano_cmd_run_status(const char *cmd);
|
||||
extern int nano_cmd_frun(const char *format, ...);
|
||||
|
||||
#endif
|
||||
|
||||
extern void nano_cmd_cleanup(void);
|
@ -0,0 +1,691 @@
|
||||
#ifndef CONF_H
|
||||
#define CONF_H
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "nng/nng.h"
|
||||
#include "rule.h"
|
||||
#include "acl_conf.h"
|
||||
#include "log.h"
|
||||
#include "ringbuffer.h"
|
||||
#include "nng/supplemental/util/platform.h"
|
||||
|
||||
#define PID_PATH_NAME "/tmp/nanomq/nanomq.pid"
|
||||
#define CONF_PATH_NAME "/etc/nanomq.conf"
|
||||
#define CONF_ZMQ_GATEWAY_PATH_NAME "/etc/nanomq_zmq_gateway.conf"
|
||||
#define CONF_VSOMEIP_GATEWAY_PATH_NAME "/etc/nanomq_vsomeip_gateway.conf"
|
||||
|
||||
#define CONF_DDS_GATEWAY_PATH_NAME "/etc/nanomq_dds_gateway.conf"
|
||||
|
||||
#define CONF_TCP_URL_DEFAULT "nmq-tcp://0.0.0.0:1883"
|
||||
#define CONF_TLS_URL_DEFAULT "tls+nmq-tcp://0.0.0.0:8883"
|
||||
#define CONF_WS_URL_DEFAULT "nmq-ws://0.0.0.0:8083/mqtt"
|
||||
#define CONF_WSS_URL_DEFAULT "nmq-wss://0.0.0.0:8086/mqtt"
|
||||
|
||||
#define BROKER_NMQ_TCP_URL_PREFIX "nmq-tcp"
|
||||
#define BROKER_NMQ_TCP_TLS_URL_PREFIX "tls+nmq-tcp"
|
||||
#define BROKER_NMQ_WS_URL_PREFIX "nmq-ws"
|
||||
#define BROKER_NMQ_WSS_URL_PREFIX "nmq-wss"
|
||||
|
||||
#define BROKER_TCP_URL_PREFIX "broker+tcp"
|
||||
#define BROKER_WS_URL_PREFIX "nmq+ws"
|
||||
#define BROKER_WSS_URL_PREFIX "nmq+wss"
|
||||
|
||||
#define RULE_ENG_OFF 0
|
||||
#define RULE_ENG_SDB 1
|
||||
#define RULE_ENG_FDB (1 << 1)
|
||||
#define RULE_ENG_MDB (1 << 2)
|
||||
#define RULE_ENG_RPB (1 << 3)
|
||||
|
||||
|
||||
#define FREE_NONULL(p) \
|
||||
if (p) { \
|
||||
free(p); \
|
||||
p = NULL; \
|
||||
}
|
||||
|
||||
struct conf_auth {
|
||||
bool enable;
|
||||
size_t count;
|
||||
char **usernames;
|
||||
char **passwords;
|
||||
};
|
||||
|
||||
typedef struct conf_auth conf_auth;
|
||||
|
||||
struct conf_tls {
|
||||
bool enable;
|
||||
char *url; // "tls+nmq-tcp://addr:port"
|
||||
char *cafile;
|
||||
char *certfile;
|
||||
char *keyfile;
|
||||
char *ca;
|
||||
char *cert;
|
||||
char *key;
|
||||
char *key_password;
|
||||
bool verify_peer;
|
||||
bool set_fail; // fail_if_no_peer_cert
|
||||
};
|
||||
|
||||
typedef struct conf_tls conf_tls;
|
||||
|
||||
// TODO: params for one single tcp node should be in here.
|
||||
typedef struct {
|
||||
bool enable;
|
||||
char *url;
|
||||
uint8_t nodelay;
|
||||
uint8_t keepalive;
|
||||
uint8_t quickack;
|
||||
uint16_t keepidle;
|
||||
uint16_t keepintvl;
|
||||
uint16_t keepcnt;
|
||||
uint16_t sendtimeo;
|
||||
uint16_t recvtimeo;
|
||||
} conf_tcp;
|
||||
|
||||
typedef struct {
|
||||
size_t count;
|
||||
conf_tls **nodes;
|
||||
} conf_tls_list;
|
||||
|
||||
typedef struct {
|
||||
size_t count;
|
||||
conf_tcp **nodes;
|
||||
} conf_tcp_list;
|
||||
|
||||
struct conf_sqlite {
|
||||
bool enable;
|
||||
size_t disk_cache_size; // specify the max rows of sqlite table
|
||||
char * mounted_file_path; // specify the db file path
|
||||
size_t
|
||||
flush_mem_threshold; // flush to sqlite table when count of message
|
||||
// is equal or greater than this value
|
||||
uint64_t resend_interval; // resend caching message interval (ms)
|
||||
};
|
||||
|
||||
typedef struct conf_sqlite conf_sqlite;
|
||||
|
||||
struct conf_http_header {
|
||||
char *key;
|
||||
char *value;
|
||||
};
|
||||
|
||||
typedef struct conf_http_header conf_http_header;
|
||||
|
||||
typedef enum {
|
||||
ACCESS,
|
||||
USERNAME,
|
||||
CLIENTID,
|
||||
IPADDRESS,
|
||||
PROTOCOL,
|
||||
PASSWORD,
|
||||
SOCKPORT, // sockport of server accepted
|
||||
COMMON_NAME, // common name of client TLS cert
|
||||
SUBJECT, // subject of client TLS cert
|
||||
TOPIC,
|
||||
MOUNTPOINT,
|
||||
} http_param_type;
|
||||
|
||||
struct conf_http_param {
|
||||
char * name;
|
||||
http_param_type type;
|
||||
};
|
||||
|
||||
typedef struct conf_http_param conf_http_param;
|
||||
|
||||
struct conf_auth_http_req {
|
||||
char *url;
|
||||
char *method;
|
||||
size_t header_count;
|
||||
conf_http_header **headers;
|
||||
size_t param_count;
|
||||
conf_http_param **params;
|
||||
// TODO not support yet
|
||||
conf_tls tls;
|
||||
};
|
||||
|
||||
typedef struct conf_auth_http_req conf_auth_http_req;
|
||||
|
||||
struct conf_auth_http {
|
||||
bool enable;
|
||||
conf_auth_http_req auth_req;
|
||||
conf_auth_http_req super_req;
|
||||
conf_auth_http_req acl_req;
|
||||
uint64_t timeout; // seconds
|
||||
uint64_t connect_timeout; // seconds
|
||||
size_t pool_size;
|
||||
};
|
||||
|
||||
typedef struct conf_auth_http conf_auth_http;
|
||||
|
||||
struct conf_jwt {
|
||||
char *iss;
|
||||
char *public_keyfile;
|
||||
char *private_keyfile;
|
||||
char *public_key;
|
||||
char *private_key;
|
||||
size_t public_key_len;
|
||||
size_t private_key_len;
|
||||
};
|
||||
|
||||
typedef struct conf_jwt conf_jwt;
|
||||
|
||||
typedef enum {
|
||||
BASIC,
|
||||
JWT,
|
||||
NONE_AUTH,
|
||||
} auth_type_t;
|
||||
|
||||
struct conf_http_server {
|
||||
bool enable;
|
||||
uint16_t port;
|
||||
char *username;
|
||||
char *password;
|
||||
size_t parallel;
|
||||
auth_type_t auth_type;
|
||||
conf_jwt jwt;
|
||||
nng_socket *broker_sock;
|
||||
};
|
||||
|
||||
typedef struct conf_http_server conf_http_server;
|
||||
|
||||
struct conf_websocket {
|
||||
bool enable;
|
||||
char *url; // "nmq-ws://addr:port/path"
|
||||
char *tls_url; // "nmq-wss://addr:port/path"
|
||||
};
|
||||
|
||||
typedef struct conf_websocket conf_websocket;
|
||||
|
||||
#define NO_RETAIN 2 // default retain flag value, none 0, 1
|
||||
#define NO_QOS 3 // default QoS level value for forwarding bridge msg, 3 = keep old qos
|
||||
|
||||
typedef struct {
|
||||
char *remote_topic;
|
||||
uint32_t remote_topic_len;
|
||||
char *local_topic;
|
||||
uint32_t local_topic_len;
|
||||
char *prefix;
|
||||
uint32_t prefix_len;
|
||||
char *suffix;
|
||||
uint32_t suffix_len;
|
||||
uint8_t nolocal;
|
||||
uint8_t retain; // override for retain
|
||||
uint8_t qos; // override for QoS
|
||||
uint8_t retain_as_published;
|
||||
uint8_t retain_handling;
|
||||
uint32_t stream_id; // only effective when multi_stream is enabled
|
||||
} topics;
|
||||
|
||||
typedef struct {
|
||||
char *key;
|
||||
char *value;
|
||||
}conf_user_property;
|
||||
|
||||
typedef struct {
|
||||
uint32_t session_expiry_interval;
|
||||
uint8_t request_problem_info;
|
||||
uint8_t request_response_info;
|
||||
uint16_t receive_maximum;
|
||||
uint16_t topic_alias_maximum;
|
||||
uint32_t maximum_packet_size;
|
||||
size_t user_property_size;
|
||||
conf_user_property **user_property;
|
||||
} conf_bridge_conn_properties;
|
||||
|
||||
typedef struct {
|
||||
uint8_t payload_format_indicator;
|
||||
uint32_t message_expiry_interval;
|
||||
char * content_type;
|
||||
char * response_topic;
|
||||
char * correlation_data;
|
||||
uint32_t will_delay_interval;
|
||||
size_t user_property_size;
|
||||
conf_user_property **user_property;
|
||||
} conf_bridge_conn_will_properties;
|
||||
|
||||
typedef struct {
|
||||
uint32_t identifier;
|
||||
size_t user_property_size;
|
||||
conf_user_property **user_property;
|
||||
} conf_bridge_sub_properties;
|
||||
|
||||
struct conf_bridge_node {
|
||||
bool enable;
|
||||
bool dynamic;
|
||||
bool clean_start;
|
||||
bool transparent;
|
||||
bool will_flag;
|
||||
bool will_retain;
|
||||
void *sock;
|
||||
void *bridge_arg; // for reloading bridge case
|
||||
char *name;
|
||||
char *address;
|
||||
char *host;
|
||||
char *clientid;
|
||||
char *username;
|
||||
char *password;
|
||||
char *will_payload;
|
||||
char *will_topic;
|
||||
uint8_t proto_ver;
|
||||
uint8_t will_qos;
|
||||
uint16_t port;
|
||||
uint16_t keepalive;
|
||||
uint16_t backoff_max;
|
||||
uint64_t cancel_timeout;
|
||||
uint64_t resend_interval; // resend caching message interval (ms)
|
||||
uint64_t resend_wait;
|
||||
size_t sub_count;
|
||||
size_t forwards_count;
|
||||
size_t max_recv_queue_len;
|
||||
size_t max_send_queue_len;
|
||||
topics **forwards_list;
|
||||
uint64_t parallel;
|
||||
topics **sub_list;
|
||||
conf_tls tls;
|
||||
conf_tcp tcp;
|
||||
conf_sqlite *sqlite;
|
||||
nng_aio **bridge_aio;
|
||||
nng_mtx *mtx;
|
||||
|
||||
bool hybrid; // enable/disable hybrid bridging
|
||||
char **hybrid_servers;
|
||||
|
||||
// MQTT v5 property
|
||||
conf_bridge_conn_properties * conn_properties;
|
||||
conf_bridge_conn_will_properties *will_properties;
|
||||
conf_bridge_sub_properties * sub_properties;
|
||||
|
||||
#if defined(SUPP_QUIC)
|
||||
// config params for QUIC only
|
||||
bool multi_stream;
|
||||
bool stream_auto_genid; // generate stream id automatically for each stream
|
||||
bool qos_first; // send QoS msg in high priority
|
||||
uint64_t qkeepalive; //keepalive timeout interval of QUIC transport
|
||||
uint64_t qconnect_timeout; // HandshakeIdleTimeoutMs of QUIC
|
||||
uint32_t qdiscon_timeout; // DisconnectTimeoutMs
|
||||
uint32_t qidle_timeout; // Disconnect after idle
|
||||
uint32_t qsend_idle_timeout; // SendIdleTimeoutMs
|
||||
uint32_t qinitial_rtt_ms; // Initial RTT estimate.
|
||||
uint32_t qmax_ack_delay_ms; // MaxAckDelayMs How long to wait after receiving data before sending an ACK.
|
||||
uint8_t qcongestion_control; // congestion control algorithm 1: bbr 0: cubic
|
||||
bool quic_0rtt; // 0RTT.
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef struct conf_bridge_node conf_bridge_node;
|
||||
|
||||
typedef struct ringBuffer_node ringBuffer_node;
|
||||
struct ringBuffer_node {
|
||||
char *name;
|
||||
uint32_t fullOp;
|
||||
uint64_t cap;
|
||||
};
|
||||
|
||||
typedef struct conf_exchange_node conf_exchange_node;
|
||||
struct conf_exchange_node {
|
||||
char *name;
|
||||
char *topic;
|
||||
ringBuffer_node **rbufs;
|
||||
size_t rbufs_sz;
|
||||
|
||||
nng_socket *sock;
|
||||
nng_mtx *mtx;
|
||||
char *exchange_url;
|
||||
};
|
||||
|
||||
typedef struct conf_exchange_encryption conf_exchange_encryption;
|
||||
struct conf_exchange_encryption {
|
||||
bool enable;
|
||||
char *key;
|
||||
};
|
||||
|
||||
typedef struct conf_exchange conf_exchange;
|
||||
struct conf_exchange {
|
||||
size_t count;
|
||||
conf_exchange_node **nodes;
|
||||
conf_exchange_encryption *encryption;
|
||||
};
|
||||
|
||||
#if defined(SUPP_PLUGIN)
|
||||
typedef struct conf_plugin_lib conf_plugin_lib;
|
||||
struct conf_plugin_lib {
|
||||
char *path;
|
||||
};
|
||||
|
||||
typedef struct conf_plugin conf_plugin;
|
||||
struct conf_plugin {
|
||||
struct conf_plugin_lib **libs;
|
||||
size_t path_sz;
|
||||
};
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
UNCOMPRESSED,
|
||||
SNAPPY,
|
||||
GZIP,
|
||||
BROTLI,
|
||||
ZSTD,
|
||||
LZ4
|
||||
} compression_type;
|
||||
|
||||
typedef enum { AES_GCM_V1 = 0, AES_GCM_CTR_V1 = 1 } cipher_type;
|
||||
|
||||
struct conf_parquet_encryption {
|
||||
bool enable;
|
||||
char *key_id;
|
||||
char *key;
|
||||
cipher_type type;
|
||||
};
|
||||
|
||||
typedef struct conf_parquet_encryption conf_parquet_encryption;
|
||||
|
||||
struct conf_parquet {
|
||||
bool enable;
|
||||
char *dir;
|
||||
char *file_name_prefix;
|
||||
uint8_t file_count;
|
||||
uint32_t limit_frequency;
|
||||
uint8_t file_index;
|
||||
int32_t file_size;
|
||||
compression_type comp_type;
|
||||
conf_parquet_encryption encryption;
|
||||
};
|
||||
typedef struct conf_parquet conf_parquet;
|
||||
|
||||
struct conf_blf {
|
||||
bool enable;
|
||||
char *dir;
|
||||
char *file_name_prefix;
|
||||
uint8_t file_count;
|
||||
uint8_t file_index;
|
||||
int32_t file_size;
|
||||
compression_type comp_type;
|
||||
};
|
||||
typedef struct conf_blf conf_blf;
|
||||
|
||||
struct conf_bridge {
|
||||
size_t count;
|
||||
conf_bridge_node **nodes;
|
||||
conf_sqlite sqlite;
|
||||
};
|
||||
|
||||
typedef struct conf_bridge conf_bridge;
|
||||
typedef struct {
|
||||
char *zmq_sub_url;
|
||||
char *zmq_pub_url;
|
||||
char *mqtt_url;
|
||||
char *sub_topic;
|
||||
char *pub_topic;
|
||||
char *zmq_sub_pre;
|
||||
char *zmq_pub_pre;
|
||||
char *path;
|
||||
char *username;
|
||||
char *password;
|
||||
void *zmq_sender;
|
||||
int proto_ver;
|
||||
int keepalive;
|
||||
bool clean_start;
|
||||
int parallel;
|
||||
enum { PUB_SUB, REQ_REP } type;
|
||||
conf_http_server http_server;
|
||||
} zmq_gateway_conf;
|
||||
|
||||
typedef struct {
|
||||
nng_socket *sock;
|
||||
char *mqtt_url;
|
||||
char *sub_topic;
|
||||
char *pub_topic;
|
||||
char *username;
|
||||
char *password;
|
||||
char *clientid;
|
||||
char *path;
|
||||
int proto_ver;
|
||||
int keepalive;
|
||||
bool clean_start;
|
||||
uint8_t sub_qos;
|
||||
int parallel;
|
||||
|
||||
conf_http_server http_server;
|
||||
|
||||
// vsomeip parameter
|
||||
uint16_t service_id;
|
||||
uint16_t service_instance_id;
|
||||
uint16_t service_method_id;
|
||||
uint16_t service_event_id;
|
||||
uint16_t service_eventgroup_id;
|
||||
char *conf_path;
|
||||
} vsomeip_gateway_conf;
|
||||
|
||||
typedef struct {
|
||||
char *from;
|
||||
char *to;
|
||||
char *struct_name;
|
||||
} dds_gateway_topic;
|
||||
|
||||
typedef struct {
|
||||
dds_gateway_topic **dds2mqtt;
|
||||
size_t dds2mqtt_sz;
|
||||
dds_gateway_topic **mqtt2dds;
|
||||
size_t mqtt2dds_sz;
|
||||
} dds_gateway_forward;
|
||||
|
||||
typedef struct {
|
||||
nng_socket *sock;
|
||||
bool clean_start;
|
||||
uint8_t proto_ver;
|
||||
uint16_t port;
|
||||
uint16_t keepalive;
|
||||
char * address;
|
||||
char * clientid;
|
||||
char * username;
|
||||
char * password;
|
||||
conf_tls tls;
|
||||
} dds_gateway_mqtt;
|
||||
|
||||
typedef struct {
|
||||
char * idl_type;
|
||||
size_t domain_id;
|
||||
char * subscriber_partition;
|
||||
char * publisher_partition;
|
||||
bool shm_mode;
|
||||
char * shm_log_level;
|
||||
} dds_gateway_dds;
|
||||
|
||||
typedef struct {
|
||||
char * path;
|
||||
dds_gateway_mqtt mqtt;
|
||||
dds_gateway_dds dds;
|
||||
dds_gateway_forward forward;
|
||||
conf_http_server http_server;
|
||||
} dds_gateway_conf;
|
||||
|
||||
typedef enum {
|
||||
CLIENT_CONNECT,
|
||||
CLIENT_CONNACK,
|
||||
CLIENT_CONNECTED,
|
||||
CLIENT_DISCONNECTED,
|
||||
CLIENT_SUBSCRIBE,
|
||||
CLIENT_UNSUBSCRIBE,
|
||||
SESSION_SUBSCRIBED,
|
||||
SESSION_UNSUBSCRIBED,
|
||||
SESSION_TERMINATED,
|
||||
MESSAGE_PUBLISH,
|
||||
MESSAGE_DELIVERED,
|
||||
MESSAGE_ACKED,
|
||||
UNKNOWN_EVENT,
|
||||
} webhook_event;
|
||||
|
||||
typedef enum {
|
||||
plain,
|
||||
base64,
|
||||
base62
|
||||
} hook_payload_type;
|
||||
|
||||
struct conf_web_hook_rule {
|
||||
uint16_t rule_num;
|
||||
webhook_event event;
|
||||
char * action;
|
||||
char * topic;
|
||||
};
|
||||
|
||||
typedef struct conf_web_hook_rule conf_web_hook_rule;
|
||||
|
||||
struct conf_web_hook {
|
||||
bool enable;
|
||||
char * url;
|
||||
size_t pool_size;
|
||||
hook_payload_type encode_payload;
|
||||
size_t header_count;
|
||||
conf_http_header **headers;
|
||||
|
||||
uint16_t rule_count;
|
||||
conf_web_hook_rule **rules;
|
||||
|
||||
nng_mtx *ex_mtx; // mutex for saios
|
||||
nng_aio *ex_aio; // Await flush
|
||||
nng_aio **saios; // Aios for sending message
|
||||
|
||||
// TODO not support yet
|
||||
conf_tls tls;
|
||||
};
|
||||
|
||||
typedef struct conf_web_hook conf_web_hook;
|
||||
|
||||
typedef enum {
|
||||
memory,
|
||||
sqlite,
|
||||
} persistence_type;
|
||||
|
||||
struct conf {
|
||||
char *vin;
|
||||
char *cmd_ipc_url;
|
||||
char *hook_ipc_url;
|
||||
char *conf_file;
|
||||
char *url;
|
||||
bool enable;
|
||||
int property_size;
|
||||
int msq_len;
|
||||
uint32_t num_taskq_thread;
|
||||
uint32_t max_taskq_thread;
|
||||
uint32_t parallel; // broker ctx
|
||||
uint64_t total_ctx; // Total ctx of work (bridge + AWS + broker + HTTP)
|
||||
uint64_t max_packet_size; // byte
|
||||
uint32_t client_max_packet_size; // byte
|
||||
uint32_t max_inflight_window;
|
||||
uint32_t max_awaiting_rel;
|
||||
uint32_t await_rel_timeout;
|
||||
uint32_t qos_duration;
|
||||
float backoff;
|
||||
void *db_root;
|
||||
bool allow_anonymous;
|
||||
bool daemon;
|
||||
bool ipc_internal;
|
||||
bool bridge_mode;
|
||||
|
||||
conf_tcp_list tcp_list;
|
||||
conf_tls_list tls_list;
|
||||
conf_sqlite sqlite;
|
||||
conf_tls tls;
|
||||
conf_http_server http_server;
|
||||
conf_websocket websocket;
|
||||
conf_bridge bridge; //standard MQTT
|
||||
conf_bridge aws_bridge; // AWS IoT Core
|
||||
conf_exchange exchange;
|
||||
conf_parquet parquet;
|
||||
conf_blf blf;
|
||||
#if defined(SUPP_PLUGIN)
|
||||
conf_plugin plugin;
|
||||
#endif
|
||||
conf_web_hook web_hook;
|
||||
#if defined(ENABLE_LOG)
|
||||
conf_log log;
|
||||
#endif
|
||||
#if defined(SUPP_RULE_ENGINE)
|
||||
conf_rule rule_eng;
|
||||
#endif
|
||||
#ifdef ACL_SUPP
|
||||
conf_acl acl;
|
||||
acl_permit acl_nomatch;
|
||||
bool enable_acl_cache;
|
||||
size_t acl_cache_max_size;
|
||||
size_t acl_cache_ttl;
|
||||
enum { ACL_IGNORE, ACL_DISCONNECT } acl_deny_action;
|
||||
#endif
|
||||
conf_auth auths;
|
||||
conf_auth_http auth_http;
|
||||
struct hashmap_s *cid_table;
|
||||
};
|
||||
|
||||
typedef struct conf conf;
|
||||
|
||||
webhook_event get_webhook_event(const char *hook_type, const char *hook_name);
|
||||
|
||||
NNG_DECL int get_size(const char *str, uint64_t *size);
|
||||
NNG_DECL int get_time(const char *str, uint64_t *second);
|
||||
NNG_DECL void conf_parse(conf *nanomq_conf);
|
||||
NNG_DECL void conf_parse_ver2(conf *nanomq_conf);
|
||||
NNG_DECL void conf_gateway_parse_ver2(zmq_gateway_conf *gateway);
|
||||
NNG_DECL void conf_vsomeip_gateway_parse_ver2(vsomeip_gateway_conf *config);
|
||||
NNG_DECL void conf_dds_gateway_init(dds_gateway_conf *config);
|
||||
NNG_DECL void conf_dds_gateway_parse_ver2(dds_gateway_conf *config);
|
||||
NNG_DECL void conf_dds_gateway_destory(dds_gateway_conf *config);
|
||||
NNG_DECL void conf_init(conf *nanomq_conf);
|
||||
NNG_DECL void print_conf(conf *nanomq_conf);
|
||||
NNG_DECL void conf_set_threads(conf *nanomq_conf);
|
||||
NNG_DECL void conf_fini(conf *nanomq_conf);
|
||||
NNG_DECL void conf_update(const char *fpath, const char *key, char *value);
|
||||
NNG_DECL void conf_update2(const char *fpath, const char *key1,
|
||||
const char *key2, const char *key3, char *value);
|
||||
NNG_DECL void
|
||||
conf_bridge_node_parse(
|
||||
conf_bridge_node *node, conf_sqlite *bridge_sqlite, cJSON *obj);
|
||||
NNG_DECL void conf_bridge_node_destroy(conf_bridge_node *node);
|
||||
|
||||
NNG_DECL void conf_update_var(
|
||||
const char *fpath, const char *key, uint8_t type, void *var);
|
||||
NNG_DECL void conf_update_var2(const char *fpath, const char *key1,
|
||||
const char *key2, const char *key3, uint8_t type, void *var);
|
||||
NNG_DECL const char* conf_get_vin(void);
|
||||
NNG_DECL void conf_free_vin();
|
||||
|
||||
#define conf_update_int(path, key, var) \
|
||||
conf_update_var(path, key, 0, (void *) &(var))
|
||||
#define conf_update_u8(path, key, var) \
|
||||
conf_update_var(path, key, 1, (void *) &(var))
|
||||
#define conf_update_u16(path, key, var) \
|
||||
conf_update_var(path, key, 2, (void *) &(var))
|
||||
#define conf_update_u32(path, key, var) \
|
||||
conf_update_var(path, key, 3, (void *) &(var))
|
||||
#define conf_update_u64(path, key, var) \
|
||||
conf_update_var(path, key, 4, (void *) &(var))
|
||||
#define conf_update_long(path, key, var) \
|
||||
conf_update_var(path, key, 5, (void *) &(var))
|
||||
#define conf_update_double(path, key, var) \
|
||||
conf_update_var(path, key, 6, (void *) &(var))
|
||||
#define conf_update_bool(path, key, var) \
|
||||
conf_update_var(path, key, 7, (void *) &(var))
|
||||
|
||||
#define conf_update2_int(path, key1, key2, key3, var) \
|
||||
conf_update_var2(path, key1, key2, key3, 0, (void *) &(var))
|
||||
#define conf_update2_u8(path, key1, key2, key3, var) \
|
||||
conf_update_var2(path, key1, key2, key3, 1, (void *) &(var))
|
||||
#define conf_update2_u16(path, key1, key2, key3, var) \
|
||||
conf_update_var2(path, key1, key2, key3, 2, (void *) &(var))
|
||||
#define conf_update2_u32(path, key1, key2, key3, var) \
|
||||
conf_update_var2(path, key1, key2, key3, 3, (void *) &(var))
|
||||
#define conf_update2_u64(path, key1, key2, key3, var) \
|
||||
conf_update_var2(path, key1, key2, key3, 4, (void *) &(var))
|
||||
#define conf_update2_long(path, key1, key2, key3, var) \
|
||||
conf_update_var2(path, key1, key2, key3, 5, (void *) &(var))
|
||||
#define conf_update2_double(path, key1, key2, key3, var) \
|
||||
conf_update_var2(path, key1, key2, key3, 6, (void *) &(var))
|
||||
#define conf_update2_bool(path, key1, key2, key3, var) \
|
||||
conf_update_var2(path, key1, key2, key3, 7, (void *) &(var))
|
||||
|
||||
#endif
|
@ -0,0 +1,228 @@
|
||||
|
||||
#ifndef CVECTOR_H_
|
||||
#define CVECTOR_H_
|
||||
|
||||
#include <assert.h> /* for assert */
|
||||
#include <stdlib.h> /* for malloc/realloc/free */
|
||||
|
||||
/**
|
||||
* @brief cvector_vector_type - The vector type used in this library
|
||||
*/
|
||||
#define cvector(type) type *
|
||||
/**
|
||||
* @brief cvector_set_capacity - For internal use, sets the capacity variable
|
||||
* of the vector
|
||||
* @param vec - the vector
|
||||
* @param size - the new capacity to set
|
||||
* @return void
|
||||
*/
|
||||
#define cvector_set_capacity(vec, size) \
|
||||
do { \
|
||||
if (vec) { \
|
||||
((size_t *) (vec))[-1] = (size); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* @brief cvector_set_size - For internal use, sets the size variable of the
|
||||
* vector
|
||||
* @param vec - the vector
|
||||
* @param size - the new capacity to set
|
||||
* @return void
|
||||
*/
|
||||
#define cvector_set_size(vec, size) \
|
||||
do { \
|
||||
if (vec) { \
|
||||
((size_t *) (vec))[-2] = (size); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* @brief cvector_capacity - gets the current capacity of the vector
|
||||
* @param vec - the vector
|
||||
* @return the capacity as a size_t
|
||||
*/
|
||||
#define cvector_capacity(vec) ((vec) ? ((size_t *) (vec))[-1] : (size_t) 0)
|
||||
|
||||
/**
|
||||
* @brief cvector_size - gets the current size of the vector
|
||||
* @param vec - the vector
|
||||
* @return the size as a size_t
|
||||
*/
|
||||
#define cvector_size(vec) ((vec) ? ((size_t *) (vec))[-2] : (size_t) 0)
|
||||
|
||||
/**
|
||||
* @brief cvector_empty - returns non-zero if the vector is empty
|
||||
* @param vec - the vector
|
||||
* @return non-zero if empty, zero if non-empty
|
||||
*/
|
||||
#define cvector_empty(vec) (cvector_size(vec) == 0)
|
||||
|
||||
/**
|
||||
* @brief cvector_grow - For internal use, ensures that the vector is at least
|
||||
* <count> elements big
|
||||
* @param vec - the vector
|
||||
* @param count - the new capacity to set
|
||||
* @return void
|
||||
*/
|
||||
#define cvector_grow(vec, count) \
|
||||
do { \
|
||||
const size_t cv_sz = \
|
||||
(count) * sizeof(*(vec)) + (sizeof(size_t) * 2); \
|
||||
if (!(vec)) { \
|
||||
size_t *cv_p = malloc(cv_sz); \
|
||||
assert(cv_p); \
|
||||
(vec) = (void *) (&cv_p[2]); \
|
||||
cvector_set_capacity((vec), (count)); \
|
||||
cvector_set_size((vec), 0); \
|
||||
} else { \
|
||||
size_t *cv_p1 = &((size_t *) (vec))[-2]; \
|
||||
size_t *cv_p2 = realloc(cv_p1, (cv_sz)); \
|
||||
assert(cv_p2); \
|
||||
(vec) = (void *) (&cv_p2[2]); \
|
||||
cvector_set_capacity((vec), (count)); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* @brief cvector_pop_back - removes the last element from the vector
|
||||
* @param vec - the vector
|
||||
* @return void
|
||||
*/
|
||||
#define cvector_pop_back(vec) \
|
||||
do { \
|
||||
cvector_set_size((vec), cvector_size(vec) - 1); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* @brief cvector_erase - removes the element at index i from the vector
|
||||
* @param vec - the vector
|
||||
* @param i - index of element to remove
|
||||
* @return void
|
||||
*/
|
||||
#define cvector_erase(vec, i) \
|
||||
do { \
|
||||
if (vec) { \
|
||||
const size_t cv_sz = cvector_size(vec); \
|
||||
if ((i) < cv_sz) { \
|
||||
cvector_set_size((vec), cv_sz - 1); \
|
||||
size_t cv_x; \
|
||||
for (cv_x = (i); cv_x < (cv_sz - 1); \
|
||||
++cv_x) { \
|
||||
(vec)[cv_x] = (vec)[cv_x + 1]; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* @brief cvector_free - frees all memory associated with the vector
|
||||
* @param vec - the vector
|
||||
* @return void
|
||||
*/
|
||||
#define cvector_free(vec) \
|
||||
do { \
|
||||
if (vec) { \
|
||||
size_t *p1 = &((size_t *) (vec))[-2]; \
|
||||
free(p1); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* @brief cvector_begin - returns an iterator to first element of the vector
|
||||
* @param vec - the vector
|
||||
* @return a pointer to the first element (or NULL)
|
||||
*/
|
||||
#define cvector_begin(vec) (vec)
|
||||
|
||||
/**
|
||||
* @brief cvector_end - returns an iterator to one past the last element of the
|
||||
* vector
|
||||
* @param vec - the vector
|
||||
* @return a pointer to one past the last element (or NULL)
|
||||
*/
|
||||
#define cvector_end(vec) ((vec) ? &((vec)[cvector_size(vec)]) : NULL)
|
||||
|
||||
/* user request to use logarithmic growth algorithm */
|
||||
#ifdef CVECTOR_LOGARITHMIC_GROWTH
|
||||
|
||||
/**
|
||||
* @brief cvector_push_back - adds an element to the end of the vector
|
||||
* @param vec - the vector
|
||||
* @param value - the value to add
|
||||
* @return void
|
||||
*/
|
||||
#define cvector_push_back(vec, value) \
|
||||
do { \
|
||||
size_t cv_cap = cvector_capacity(vec); \
|
||||
if (cv_cap <= cvector_size(vec)) { \
|
||||
cvector_grow( \
|
||||
(vec), !cv_cap ? cv_cap + 1 : cv_cap * 2); \
|
||||
} \
|
||||
vec[cvector_size(vec)] = (value); \
|
||||
cvector_set_size((vec), cvector_size(vec) + 1); \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
|
||||
/**
|
||||
* @brief cvector_push_back - adds an element to the end of the vector
|
||||
* @param vec - the vector
|
||||
* @param value - the value to add
|
||||
* @return void
|
||||
*/
|
||||
#define cvector_push_back(vec, value) \
|
||||
do { \
|
||||
size_t cv_cap = cvector_capacity(vec); \
|
||||
if (cv_cap <= cvector_size(vec)) { \
|
||||
cvector_grow((vec), cv_cap + 1); \
|
||||
} \
|
||||
vec[cvector_size(vec)] = (value); \
|
||||
cvector_set_size((vec), cvector_size(vec) + 1); \
|
||||
} while (0)
|
||||
|
||||
#endif /* CVECTOR_LOGARITHMIC_GROWTH */
|
||||
|
||||
/**
|
||||
* @brief cvector_copy - copy a vector
|
||||
* @param from - the original vector
|
||||
* @param to - destination to which the function copy to
|
||||
* @return void
|
||||
*/
|
||||
#define cvector_copy(from, to) \
|
||||
do { \
|
||||
for (size_t i = 0; i < cvector_size(from); i++) { \
|
||||
cvector_push_back(to, from[i]); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#endif /* CVECTOR_H_ */
|
||||
|
||||
/**
|
||||
* @brief cvector_insert - insert the element at index i to the vector
|
||||
* @param vec - the vector
|
||||
* @param i - index of element to insert
|
||||
* @param value - value to insert
|
||||
* @return void
|
||||
*/
|
||||
#define cvector_insert(vec, i, value) \
|
||||
do { \
|
||||
if (cvector_empty(vec)) { \
|
||||
cvector_push_back(vec, value); \
|
||||
} else { \
|
||||
size_t cv_cap = cvector_capacity(vec); \
|
||||
if (cv_cap <= cvector_size(vec)) { \
|
||||
cvector_grow((vec), \
|
||||
!cv_cap ? cv_cap + 1 : cv_cap * 2); \
|
||||
} \
|
||||
const size_t cv_sz = cvector_size(vec); \
|
||||
if ((i) < cv_sz) { \
|
||||
cvector_set_size((vec), cv_sz + 1); \
|
||||
size_t cv_x; \
|
||||
for (cv_x = (cv_sz); cv_x > (i); cv_x--) { \
|
||||
(vec)[cv_x] = (vec)[cv_x - 1]; \
|
||||
} \
|
||||
vec[i] = (value); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
@ -0,0 +1,63 @@
|
||||
#ifndef NANOLIB_ENV_H
|
||||
#define NANOLIB_ENV_H
|
||||
|
||||
#include "conf.h"
|
||||
#include "nng/nng.h"
|
||||
|
||||
#define NANOMQ_BROKER_URL "NANOMQ_BROKER_URL"
|
||||
#define NANOMQ_EXCHANGER_URL "NANOMQ_EXCHANGER_URL"
|
||||
#define NANOMQ_DAEMON "NANOMQ_DAEMON"
|
||||
#define NANOMQ_TCP_ENABLE "NANOMQ_TCP_ENABLE"
|
||||
#define NANOMQ_NUM_TASKQ_THREAD "NANOMQ_MAX_TASKQ_THREAD"
|
||||
#define NANOMQ_MAX_TASKQ_THREAD "NANOMQ_MAX_TASKQ_THREAD"
|
||||
#define NANOMQ_PARALLEL "NANOMQ_PARALLEL"
|
||||
#define NANOMQ_PROPERTY_SIZE "NANOMQ_PROPERTY_SIZE"
|
||||
#define NANOMQ_MAX_PACKET_SIZE "NANOMQ_MAX_PACKET_SIZE"
|
||||
#define NANOMQ_CLIENT_MAX_PACKET_SIZE "NANOMQ_CLIENT_MAX_PACKET_SIZE"
|
||||
#define NANOMQ_MSQ_LEN "NANOMQ_MSQ_LEN"
|
||||
#define NANOMQ_QOS_DURATION "NANOMQ_QOS_DURATION"
|
||||
#define NANOMQ_ALLOW_ANONYMOUS "NANOMQ_ALLOW_ANONYMOUS"
|
||||
#define NANOMQ_MSG_PERSISTENCE "NANOMQ_MSG_PERSISTENCE"
|
||||
|
||||
#define NANOMQ_WEBSOCKET_ENABLE "NANOMQ_WEBSOCKET_ENABLE"
|
||||
#define NANOMQ_WEBSOCKET_URL "NANOMQ_WEBSOCKET_URL"
|
||||
#define NANOMQ_WEBSOCKET_TLS_URL "NANOMQ_WEBSOCKET_TLS_URL"
|
||||
|
||||
#define NANOMQ_HTTP_SERVER_ENABLE "NANOMQ_HTTP_SERVER_ENABLE"
|
||||
#define NANOMQ_HTTP_SERVER_PORT "NANOMQ_HTTP_SERVER_PORT"
|
||||
#define NANOMQ_HTTP_SERVER_PARALLEL "NANOMQ_HTTP_SERVER_PARALLEL"
|
||||
#define NANOMQ_HTTP_SERVER_USERNAME "NANOMQ_HTTP_SERVER_USERNAME"
|
||||
#define NANOMQ_HTTP_SERVER_PASSWORD "NANOMQ_HTTP_SERVER_PASSWORD"
|
||||
#define NANOMQ_HTTP_SERVER_AUTH_TYPE "NANOMQ_HTTP_SERVER_AUTH_TYPE"
|
||||
#define NANOMQ_HTTP_SERVER_JWT_PUBLIC_KEYFILE \
|
||||
"NANOMQ_HTTP_SERVER_JWT_PUBLIC_KEYFILE"
|
||||
#define NANOMQ_HTTP_SERVER_JWT_PRIVATE_KEYFILE \
|
||||
"NANOMQ_HTTP_SERVER_JWT_PRIVATE_KEYFILE"
|
||||
|
||||
#define NANOMQ_TLS_ENABLE "NANOMQ_TLS_ENABLE"
|
||||
#define NANOMQ_TLS_URL "NANOMQ_TLS_URL"
|
||||
#define NANOMQ_TLS_CA_CERT_PATH "NANOMQ_TLS_CA_CERT_PATH"
|
||||
#define NANOMQ_TLS_CERT_PATH "NANOMQ_TLS_CERT_PATH"
|
||||
#define NANOMQ_TLS_KEY_PATH "NANOMQ_TLS_KEY_PATH"
|
||||
#define NANOMQ_TLS_KEY_PASSWORD "NANOMQ_TLS_KEY_PASSWORD"
|
||||
#define NANOMQ_TLS_VERIFY_PEER "NANOMQ_TLS_VERIFY_PEER"
|
||||
#define NANOMQ_TLS_FAIL_IF_NO_PEER_CERT "NANOMQ_TLS_FAIL_IF_NO_PEER_CERT"
|
||||
|
||||
#define NANOMQ_LOG_LEVEL "NANOMQ_LOG_LEVEL"
|
||||
#define NANOMQ_LOG_TO "NANOMQ_LOG_TO"
|
||||
#define NANOMQ_LOG_UDS_ADDR "NANOMQ_LOG_UDS_ADDR"
|
||||
#define NANOMQ_LOG_DIR "NANOMQ_LOG_DIR"
|
||||
#define NANOMQ_LOG_FILE "NANOMQ_LOG_FILE"
|
||||
#define NANOMQ_LOG_ROTATION_SIZE "NANOMQ_LOG_ROTATION_SIZE"
|
||||
#define NANOMQ_LOG_ROTATION_COUNT "NANOMQ_LOG_ROTATION_COUNT"
|
||||
|
||||
#define NANOMQ_CONF_PATH "NANOMQ_CONF_PATH"
|
||||
|
||||
#define NANOMQ_VIN "NANOMQ_VIN"
|
||||
#define NANOMQ_PID_FILE "NANOMQ_PID_FILE"
|
||||
|
||||
NNG_DECL void read_env_conf(conf *config);
|
||||
NNG_DECL char *read_env_vin();
|
||||
NNG_DECL char *read_env_pid_file();
|
||||
|
||||
#endif
|
@ -0,0 +1,18 @@
|
||||
#ifndef NANO_FILE_H
|
||||
#define NANO_FILE_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "nng/nng.h"
|
||||
|
||||
NNG_DECL bool nano_file_exists(const char *fpath);
|
||||
NNG_DECL char * nano_getcwd(char *buf, size_t size);
|
||||
NNG_DECL int64_t nano_getline(
|
||||
char **restrict line, size_t *restrict len, FILE *restrict fp);
|
||||
NNG_DECL char * nano_concat_path(const char *dir, const char *file_name);
|
||||
NNG_DECL int file_write_string(const char *fpath, const char *string);
|
||||
NNG_DECL int file_create_dir(const char *fpath);
|
||||
NNG_DECL size_t file_load_data(const char *filepath, void **data);
|
||||
|
||||
#endif
|
@ -0,0 +1,121 @@
|
||||
#ifndef HASH_TABLE_H
|
||||
#define HASH_TABLE_H
|
||||
|
||||
#include "cvector.h"
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "nng/nng.h"
|
||||
#include "nng/mqtt/packet.h"
|
||||
|
||||
struct topic_queue {
|
||||
uint8_t qos;
|
||||
char *topic;
|
||||
struct topic_queue *next;
|
||||
};
|
||||
|
||||
typedef struct topic_queue topic_queue;
|
||||
|
||||
struct msg_queue {
|
||||
char * msg;
|
||||
struct msg_queue *next;
|
||||
};
|
||||
|
||||
typedef struct msg_queue msg_queue;
|
||||
|
||||
// atpair is alias topic pair
|
||||
typedef struct dbhash_atpair_s dbhash_atpair_t;
|
||||
|
||||
struct dbhash_atpair_s {
|
||||
uint32_t alias;
|
||||
char * topic;
|
||||
};
|
||||
|
||||
typedef struct dbhash_ptpair_s dbhash_ptpair_t;
|
||||
|
||||
// ptpair is pipe topic pair
|
||||
struct dbhash_ptpair_s {
|
||||
uint32_t pipe;
|
||||
char * topic;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief alias_cmp - A callback to compare different alias
|
||||
* @param x - normally x is pointer of dbhash_atpair_t
|
||||
* @param y - normally y is pointer of alias
|
||||
* @return 0, minus or plus
|
||||
*/
|
||||
static inline int
|
||||
alias_cmp(void *x_, void *y_)
|
||||
{
|
||||
uint32_t * alias = (uint32_t *) y_;
|
||||
dbhash_atpair_t *ele_x = (dbhash_atpair_t *) x_;
|
||||
return *alias - ele_x->alias;
|
||||
}
|
||||
|
||||
NNG_DECL void dbhash_init_alias_table(void);
|
||||
|
||||
NNG_DECL void dbhash_destroy_alias_table(void);
|
||||
// This function do not verify value of alias and topic,
|
||||
// therefore you should make sure alias and topic is
|
||||
// not illegal.
|
||||
NNG_DECL void dbhash_insert_atpair(uint32_t pipe_id, uint32_t alias, const char *topic);
|
||||
|
||||
NNG_DECL const char *dbhash_find_atpair(uint32_t pipe_id, uint32_t alias);
|
||||
|
||||
NNG_DECL void dbhash_del_atpair_queue(uint32_t pipe_id);
|
||||
|
||||
NNG_DECL void dbhash_init_pipe_table(void);
|
||||
|
||||
NNG_DECL void dbhash_destroy_pipe_table(void);
|
||||
|
||||
NNG_DECL void dbhash_insert_topic(uint32_t id, char *val, uint8_t qos);
|
||||
|
||||
NNG_DECL bool dbhash_check_topic(uint32_t id, char *val);
|
||||
|
||||
NNG_DECL char *dbhash_get_first_topic(uint32_t id);
|
||||
|
||||
NNG_DECL topic_queue *topic_queue_init(char *topic, int topic_len);
|
||||
|
||||
NNG_DECL void topic_queue_release(topic_queue *tq);
|
||||
|
||||
NNG_DECL topic_queue *init_topic_queue_with_topic_node(topic_node *tn);
|
||||
|
||||
NNG_DECL struct topic_queue *dbhash_get_topic_queue(uint32_t id);
|
||||
|
||||
NNG_DECL struct topic_queue *dbhash_copy_topic_queue(uint32_t id);
|
||||
|
||||
NNG_DECL void dbhash_del_topic(uint32_t id, char *topic);
|
||||
|
||||
NNG_DECL void *dbhash_del_topic_queue(
|
||||
uint32_t id, void *(*cb)(void *, char *), void *args);
|
||||
|
||||
NNG_DECL bool dbhash_check_id(uint32_t id);
|
||||
|
||||
NNG_DECL void *dbhash_check_id_and_do(uint32_t id, void *(*cb)(void *), void *arg);
|
||||
|
||||
NNG_DECL void dbhash_print_topic_queue(uint32_t id);
|
||||
|
||||
NNG_DECL topic_queue **dbhash_get_topic_queue_all(size_t *sz);
|
||||
|
||||
NNG_DECL dbhash_ptpair_t *dbhash_ptpair_alloc(uint32_t p, char *t);
|
||||
|
||||
NNG_DECL void dbhash_ptpair_free(dbhash_ptpair_t *pt);
|
||||
|
||||
NNG_DECL dbhash_ptpair_t **dbhash_get_ptpair_all(void);
|
||||
|
||||
NNG_DECL size_t dbhash_get_pipe_cnt(void);
|
||||
|
||||
NNG_DECL void dbhash_init_cached_table(void);
|
||||
NNG_DECL void dbhash_destroy_cached_table(void);
|
||||
|
||||
NNG_DECL void dbhash_cache_topic_all(uint32_t pid, uint32_t cid);
|
||||
|
||||
NNG_DECL void dbhash_restore_topic_all(uint32_t cid, uint32_t pid);
|
||||
|
||||
NNG_DECL struct topic_queue *dbhash_get_cached_topic(uint32_t cid);
|
||||
|
||||
NNG_DECL void dbhash_del_cached_topic_all(uint32_t key);
|
||||
|
||||
NNG_DECL bool dbhash_cached_check_id(uint32_t key);
|
||||
|
||||
#endif
|
@ -0,0 +1,9 @@
|
||||
#ifndef HOCON_H
|
||||
#define HOCON_H
|
||||
#include "cJSON.h"
|
||||
|
||||
cJSON *hocon_parse_file(const char *file);
|
||||
cJSON *hocon_parse_str(char *str, size_t len);
|
||||
|
||||
|
||||
#endif
|
@ -0,0 +1,627 @@
|
||||
/* The MIT License
|
||||
|
||||
Copyright (c) 2008, 2009, 2011 by Attractive Chaos <attractor@live.co.uk>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
An example:
|
||||
|
||||
#include "khash.h"
|
||||
KHASH_MAP_INIT_INT(32, char)
|
||||
int main() {
|
||||
int ret, is_missing;
|
||||
khiter_t k;
|
||||
khash_t(32) *h = kh_init(32);
|
||||
k = kh_put(32, h, 5, &ret);
|
||||
kh_value(h, k) = 10;
|
||||
k = kh_get(32, h, 10);
|
||||
is_missing = (k == kh_end(h));
|
||||
k = kh_get(32, h, 5);
|
||||
kh_del(32, h, k);
|
||||
for (k = kh_begin(h); k != kh_end(h); ++k)
|
||||
if (kh_exist(h, k)) kh_value(h, k) = 1;
|
||||
kh_destroy(32, h);
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
2013-05-02 (0.2.8):
|
||||
|
||||
* Use quadratic probing. When the capacity is power of 2, stepping function
|
||||
i*(i+1)/2 guarantees to traverse each bucket. It is better than double
|
||||
hashing on cache performance and is more robust than linear probing.
|
||||
|
||||
In theory, double hashing should be more robust than quadratic probing.
|
||||
However, my implementation is probably not for large hash tables, because
|
||||
the second hash function is closely tied to the first hash function,
|
||||
which reduce the effectiveness of double hashing.
|
||||
|
||||
Reference: http://research.cs.vt.edu/AVresearch/hashing/quadratic.php
|
||||
|
||||
2011-12-29 (0.2.7):
|
||||
|
||||
* Minor code clean up; no actual effect.
|
||||
|
||||
2011-09-16 (0.2.6):
|
||||
|
||||
* The capacity is a power of 2. This seems to dramatically improve the
|
||||
speed for simple keys. Thank Zilong Tan for the suggestion. Reference:
|
||||
|
||||
- http://code.google.com/p/ulib/
|
||||
- http://nothings.org/computer/judy/
|
||||
|
||||
* Allow to optionally use linear probing which usually has better
|
||||
performance for random input. Double hashing is still the default as it
|
||||
is more robust to certain non-random input.
|
||||
|
||||
* Added Wang's integer hash function (not used by default). This hash
|
||||
function is more robust to certain non-random input.
|
||||
|
||||
2011-02-14 (0.2.5):
|
||||
|
||||
* Allow to declare global functions.
|
||||
|
||||
2009-09-26 (0.2.4):
|
||||
|
||||
* Improve portability
|
||||
|
||||
2008-09-19 (0.2.3):
|
||||
|
||||
* Corrected the example
|
||||
* Improved interfaces
|
||||
|
||||
2008-09-11 (0.2.2):
|
||||
|
||||
* Improved speed a little in kh_put()
|
||||
|
||||
2008-09-10 (0.2.1):
|
||||
|
||||
* Added kh_clear()
|
||||
* Fixed a compiling error
|
||||
|
||||
2008-09-02 (0.2.0):
|
||||
|
||||
* Changed to token concatenation which increases flexibility.
|
||||
|
||||
2008-08-31 (0.1.2):
|
||||
|
||||
* Fixed a bug in kh_get(), which has not been tested previously.
|
||||
|
||||
2008-08-31 (0.1.1):
|
||||
|
||||
* Added destructor
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __AC_KHASH_H
|
||||
#define __AC_KHASH_H
|
||||
|
||||
/*!
|
||||
@header
|
||||
|
||||
Generic hash table library.
|
||||
*/
|
||||
|
||||
#define AC_VERSION_KHASH_H "0.2.8"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
/* compiler specific configuration */
|
||||
|
||||
#if UINT_MAX == 0xffffffffu
|
||||
typedef unsigned int khint32_t;
|
||||
#elif ULONG_MAX == 0xffffffffu
|
||||
typedef unsigned long khint32_t;
|
||||
#endif
|
||||
|
||||
#if ULONG_MAX == ULLONG_MAX
|
||||
typedef unsigned long khint64_t;
|
||||
#else
|
||||
typedef unsigned long long khint64_t;
|
||||
#endif
|
||||
|
||||
#ifndef kh_inline
|
||||
#ifdef _MSC_VER
|
||||
#define kh_inline __inline
|
||||
#else
|
||||
#define kh_inline inline
|
||||
#endif
|
||||
#endif /* kh_inline */
|
||||
|
||||
#ifndef klib_unused
|
||||
#if (defined __clang__ && __clang_major__ >= 3) || (defined __GNUC__ && __GNUC__ >= 3)
|
||||
#define klib_unused __attribute__ ((__unused__))
|
||||
#else
|
||||
#define klib_unused
|
||||
#endif
|
||||
#endif /* klib_unused */
|
||||
|
||||
typedef khint32_t khint_t;
|
||||
typedef khint_t khiter_t;
|
||||
|
||||
#define __ac_isempty(flag, i) ((flag[i>>4]>>((i&0xfU)<<1))&2)
|
||||
#define __ac_isdel(flag, i) ((flag[i>>4]>>((i&0xfU)<<1))&1)
|
||||
#define __ac_iseither(flag, i) ((flag[i>>4]>>((i&0xfU)<<1))&3)
|
||||
#define __ac_set_isdel_false(flag, i) (flag[i>>4]&=~(1ul<<((i&0xfU)<<1)))
|
||||
#define __ac_set_isempty_false(flag, i) (flag[i>>4]&=~(2ul<<((i&0xfU)<<1)))
|
||||
#define __ac_set_isboth_false(flag, i) (flag[i>>4]&=~(3ul<<((i&0xfU)<<1)))
|
||||
#define __ac_set_isdel_true(flag, i) (flag[i>>4]|=1ul<<((i&0xfU)<<1))
|
||||
|
||||
#define __ac_fsize(m) ((m) < 16? 1 : (m)>>4)
|
||||
|
||||
#ifndef kroundup32
|
||||
#define kroundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x))
|
||||
#endif
|
||||
|
||||
#ifndef kcalloc
|
||||
#define kcalloc(N,Z) calloc(N,Z)
|
||||
#endif
|
||||
#ifndef kmalloc
|
||||
#define kmalloc(Z) malloc(Z)
|
||||
#endif
|
||||
#ifndef krealloc
|
||||
#define krealloc(P,Z) realloc(P,Z)
|
||||
#endif
|
||||
#ifndef kfree
|
||||
#define kfree(P) free(P)
|
||||
#endif
|
||||
|
||||
static const double __ac_HASH_UPPER = 0.77;
|
||||
|
||||
#define __KHASH_TYPE(name, khkey_t, khval_t) \
|
||||
typedef struct kh_##name##_s { \
|
||||
khint_t n_buckets, size, n_occupied, upper_bound; \
|
||||
khint32_t *flags; \
|
||||
khkey_t *keys; \
|
||||
khval_t *vals; \
|
||||
} kh_##name##_t;
|
||||
|
||||
#define __KHASH_PROTOTYPES(name, khkey_t, khval_t) \
|
||||
extern kh_##name##_t *kh_init_##name(void); \
|
||||
extern void kh_destroy_##name(kh_##name##_t *h); \
|
||||
extern void kh_clear_##name(kh_##name##_t *h); \
|
||||
extern khint_t kh_get_##name(const kh_##name##_t *h, khkey_t key); \
|
||||
extern int kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets); \
|
||||
extern khint_t kh_put_##name(kh_##name##_t *h, khkey_t key, int *ret); \
|
||||
extern void kh_del_##name(kh_##name##_t *h, khint_t x);
|
||||
|
||||
#define __KHASH_IMPL(name, SCOPE, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \
|
||||
SCOPE kh_##name##_t *kh_init_##name(void) { \
|
||||
return (kh_##name##_t*)kcalloc(1, sizeof(kh_##name##_t)); \
|
||||
} \
|
||||
SCOPE void kh_destroy_##name(kh_##name##_t *h) \
|
||||
{ \
|
||||
if (h) { \
|
||||
kfree((void *)h->keys); kfree(h->flags); \
|
||||
kfree((void *)h->vals); \
|
||||
kfree(h); \
|
||||
} \
|
||||
} \
|
||||
SCOPE void kh_clear_##name(kh_##name##_t *h) \
|
||||
{ \
|
||||
if (h && h->flags) { \
|
||||
memset(h->flags, 0xaa, __ac_fsize(h->n_buckets) * sizeof(khint32_t)); \
|
||||
h->size = h->n_occupied = 0; \
|
||||
} \
|
||||
} \
|
||||
SCOPE khint_t kh_get_##name(const kh_##name##_t *h, khkey_t key) \
|
||||
{ \
|
||||
if (h->n_buckets) { \
|
||||
khint_t k, i, last, mask, step = 0; \
|
||||
mask = h->n_buckets - 1; \
|
||||
k = __hash_func(key); i = k & mask; \
|
||||
last = i; \
|
||||
while (!__ac_isempty(h->flags, i) && (__ac_isdel(h->flags, i) || !__hash_equal(h->keys[i], key))) { \
|
||||
i = (i + (++step)) & mask; \
|
||||
if (i == last) return h->n_buckets; \
|
||||
} \
|
||||
return __ac_iseither(h->flags, i)? h->n_buckets : i; \
|
||||
} else return 0; \
|
||||
} \
|
||||
SCOPE int kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets) \
|
||||
{ /* This function uses 0.25*n_buckets bytes of working space instead of [sizeof(key_t+val_t)+.25]*n_buckets. */ \
|
||||
khint32_t *new_flags = 0; \
|
||||
khint_t j = 1; \
|
||||
{ \
|
||||
kroundup32(new_n_buckets); \
|
||||
if (new_n_buckets < 4) new_n_buckets = 4; \
|
||||
if (h->size >= (khint_t)(new_n_buckets * __ac_HASH_UPPER + 0.5)) j = 0; /* requested size is too small */ \
|
||||
else { /* hash table size to be changed (shrink or expand); rehash */ \
|
||||
new_flags = (khint32_t*)kmalloc(__ac_fsize(new_n_buckets) * sizeof(khint32_t)); \
|
||||
if (!new_flags) return -1; \
|
||||
memset(new_flags, 0xaa, __ac_fsize(new_n_buckets) * sizeof(khint32_t)); \
|
||||
if (h->n_buckets < new_n_buckets) { /* expand */ \
|
||||
khkey_t *new_keys = (khkey_t*)krealloc((void *)h->keys, new_n_buckets * sizeof(khkey_t)); \
|
||||
if (!new_keys) { kfree(new_flags); return -1; } \
|
||||
h->keys = new_keys; \
|
||||
if (kh_is_map) { \
|
||||
khval_t *new_vals = (khval_t*)krealloc((void *)h->vals, new_n_buckets * sizeof(khval_t)); \
|
||||
if (!new_vals) { kfree(new_flags); return -1; } \
|
||||
h->vals = new_vals; \
|
||||
} \
|
||||
} /* otherwise shrink */ \
|
||||
} \
|
||||
} \
|
||||
if (j) { /* rehashing is needed */ \
|
||||
for (j = 0; j != h->n_buckets; ++j) { \
|
||||
if (__ac_iseither(h->flags, j) == 0) { \
|
||||
khkey_t key = h->keys[j]; \
|
||||
khval_t val; \
|
||||
khint_t new_mask; \
|
||||
new_mask = new_n_buckets - 1; \
|
||||
if (kh_is_map) val = h->vals[j]; \
|
||||
__ac_set_isdel_true(h->flags, j); \
|
||||
while (1) { /* kick-out process; sort of like in Cuckoo hashing */ \
|
||||
khint_t k, i, step = 0; \
|
||||
k = __hash_func(key); \
|
||||
i = k & new_mask; \
|
||||
while (!__ac_isempty(new_flags, i)) i = (i + (++step)) & new_mask; \
|
||||
__ac_set_isempty_false(new_flags, i); \
|
||||
if (i < h->n_buckets && __ac_iseither(h->flags, i) == 0) { /* kick out the existing element */ \
|
||||
{ khkey_t tmp = h->keys[i]; h->keys[i] = key; key = tmp; } \
|
||||
if (kh_is_map) { khval_t tmp = h->vals[i]; h->vals[i] = val; val = tmp; } \
|
||||
__ac_set_isdel_true(h->flags, i); /* mark it as deleted in the old hash table */ \
|
||||
} else { /* write the element and jump out of the loop */ \
|
||||
h->keys[i] = key; \
|
||||
if (kh_is_map) h->vals[i] = val; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
if (h->n_buckets > new_n_buckets) { /* shrink the hash table */ \
|
||||
h->keys = (khkey_t*)krealloc((void *)h->keys, new_n_buckets * sizeof(khkey_t)); \
|
||||
if (kh_is_map) h->vals = (khval_t*)krealloc((void *)h->vals, new_n_buckets * sizeof(khval_t)); \
|
||||
} \
|
||||
kfree(h->flags); /* free the working space */ \
|
||||
h->flags = new_flags; \
|
||||
h->n_buckets = new_n_buckets; \
|
||||
h->n_occupied = h->size; \
|
||||
h->upper_bound = (khint_t)(h->n_buckets * __ac_HASH_UPPER + 0.5); \
|
||||
} \
|
||||
return 0; \
|
||||
} \
|
||||
SCOPE khint_t kh_put_##name(kh_##name##_t *h, khkey_t key, int *ret) \
|
||||
{ \
|
||||
khint_t x; \
|
||||
if (h->n_occupied >= h->upper_bound) { /* update the hash table */ \
|
||||
if (h->n_buckets > (h->size<<1)) { \
|
||||
if (kh_resize_##name(h, h->n_buckets - 1) < 0) { /* clear "deleted" elements */ \
|
||||
*ret = -1; return h->n_buckets; \
|
||||
} \
|
||||
} else if (kh_resize_##name(h, h->n_buckets + 1) < 0) { /* expand the hash table */ \
|
||||
*ret = -1; return h->n_buckets; \
|
||||
} \
|
||||
} /* TODO: to implement automatically shrinking; resize() already support shrinking */ \
|
||||
{ \
|
||||
khint_t k, i, site, last, mask = h->n_buckets - 1, step = 0; \
|
||||
x = site = h->n_buckets; k = __hash_func(key); i = k & mask; \
|
||||
if (__ac_isempty(h->flags, i)) x = i; /* for speed up */ \
|
||||
else { \
|
||||
last = i; \
|
||||
while (!__ac_isempty(h->flags, i) && (__ac_isdel(h->flags, i) || !__hash_equal(h->keys[i], key))) { \
|
||||
if (__ac_isdel(h->flags, i)) site = i; \
|
||||
i = (i + (++step)) & mask; \
|
||||
if (i == last) { x = site; break; } \
|
||||
} \
|
||||
if (x == h->n_buckets) { \
|
||||
if (__ac_isempty(h->flags, i) && site != h->n_buckets) x = site; \
|
||||
else x = i; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
if (__ac_isempty(h->flags, x)) { /* not present at all */ \
|
||||
h->keys[x] = key; \
|
||||
__ac_set_isboth_false(h->flags, x); \
|
||||
++h->size; ++h->n_occupied; \
|
||||
*ret = 1; \
|
||||
} else if (__ac_isdel(h->flags, x)) { /* deleted */ \
|
||||
h->keys[x] = key; \
|
||||
__ac_set_isboth_false(h->flags, x); \
|
||||
++h->size; \
|
||||
*ret = 2; \
|
||||
} else *ret = 0; /* Don't touch h->keys[x] if present and not deleted */ \
|
||||
return x; \
|
||||
} \
|
||||
SCOPE void kh_del_##name(kh_##name##_t *h, khint_t x) \
|
||||
{ \
|
||||
if (x != h->n_buckets && !__ac_iseither(h->flags, x)) { \
|
||||
__ac_set_isdel_true(h->flags, x); \
|
||||
--h->size; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define KHASH_DECLARE(name, khkey_t, khval_t) \
|
||||
__KHASH_TYPE(name, khkey_t, khval_t) \
|
||||
__KHASH_PROTOTYPES(name, khkey_t, khval_t)
|
||||
|
||||
#define KHASH_INIT2(name, SCOPE, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \
|
||||
__KHASH_TYPE(name, khkey_t, khval_t) \
|
||||
__KHASH_IMPL(name, SCOPE, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal)
|
||||
|
||||
#define KHASH_INIT(name, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \
|
||||
KHASH_INIT2(name, static kh_inline klib_unused, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal)
|
||||
|
||||
/* --- BEGIN OF HASH FUNCTIONS --- */
|
||||
|
||||
/*! @function
|
||||
@abstract Integer hash function
|
||||
@param key The integer [khint32_t]
|
||||
@return The hash value [khint_t]
|
||||
*/
|
||||
#define kh_int_hash_func(key) (khint32_t)(key)
|
||||
/*! @function
|
||||
@abstract Integer comparison function
|
||||
*/
|
||||
#define kh_int_hash_equal(a, b) ((a) == (b))
|
||||
/*! @function
|
||||
@abstract 64-bit integer hash function
|
||||
@param key The integer [khint64_t]
|
||||
@return The hash value [khint_t]
|
||||
*/
|
||||
#define kh_int64_hash_func(key) (khint32_t)((key)>>33^(key)^(key)<<11)
|
||||
/*! @function
|
||||
@abstract 64-bit integer comparison function
|
||||
*/
|
||||
#define kh_int64_hash_equal(a, b) ((a) == (b))
|
||||
/*! @function
|
||||
@abstract const char* hash function
|
||||
@param s Pointer to a null terminated string
|
||||
@return The hash value
|
||||
*/
|
||||
static kh_inline khint_t __ac_X31_hash_string(const char *s)
|
||||
{
|
||||
khint_t h = (khint_t)*s;
|
||||
if (h) for (++s ; *s; ++s) h = (h << 5) - h + (khint_t)*s;
|
||||
return h;
|
||||
}
|
||||
/*! @function
|
||||
@abstract Another interface to const char* hash function
|
||||
@param key Pointer to a null terminated string [const char*]
|
||||
@return The hash value [khint_t]
|
||||
*/
|
||||
#define kh_str_hash_func(key) __ac_X31_hash_string(key)
|
||||
/*! @function
|
||||
@abstract Const char* comparison function
|
||||
*/
|
||||
#define kh_str_hash_equal(a, b) (strcmp(a, b) == 0)
|
||||
|
||||
static kh_inline khint_t __ac_Wang_hash(khint_t key)
|
||||
{
|
||||
key += ~(key << 15);
|
||||
key ^= (key >> 10);
|
||||
key += (key << 3);
|
||||
key ^= (key >> 6);
|
||||
key += ~(key << 11);
|
||||
key ^= (key >> 16);
|
||||
return key;
|
||||
}
|
||||
#define kh_int_hash_func2(key) __ac_Wang_hash((khint_t)key)
|
||||
|
||||
/* --- END OF HASH FUNCTIONS --- */
|
||||
|
||||
/* Other convenient macros... */
|
||||
|
||||
/*!
|
||||
@abstract Type of the hash table.
|
||||
@param name Name of the hash table [symbol]
|
||||
*/
|
||||
#define khash_t(name) kh_##name##_t
|
||||
|
||||
/*! @function
|
||||
@abstract Initiate a hash table.
|
||||
@param name Name of the hash table [symbol]
|
||||
@return Pointer to the hash table [khash_t(name)*]
|
||||
*/
|
||||
#define kh_init(name) kh_init_##name()
|
||||
|
||||
/*! @function
|
||||
@abstract Destroy a hash table.
|
||||
@param name Name of the hash table [symbol]
|
||||
@param h Pointer to the hash table [khash_t(name)*]
|
||||
*/
|
||||
#define kh_destroy(name, h) kh_destroy_##name(h)
|
||||
|
||||
/*! @function
|
||||
@abstract Reset a hash table without deallocating memory.
|
||||
@param name Name of the hash table [symbol]
|
||||
@param h Pointer to the hash table [khash_t(name)*]
|
||||
*/
|
||||
#define kh_clear(name, h) kh_clear_##name(h)
|
||||
|
||||
/*! @function
|
||||
@abstract Resize a hash table.
|
||||
@param name Name of the hash table [symbol]
|
||||
@param h Pointer to the hash table [khash_t(name)*]
|
||||
@param s New size [khint_t]
|
||||
*/
|
||||
#define kh_resize(name, h, s) kh_resize_##name(h, s)
|
||||
|
||||
/*! @function
|
||||
@abstract Insert a key to the hash table.
|
||||
@param name Name of the hash table [symbol]
|
||||
@param h Pointer to the hash table [khash_t(name)*]
|
||||
@param k Key [type of keys]
|
||||
@param r Extra return code: -1 if the operation failed;
|
||||
0 if the key is present in the hash table;
|
||||
1 if the bucket is empty (never used); 2 if the element in
|
||||
the bucket has been deleted [int*]
|
||||
@return Iterator to the inserted element [khint_t]
|
||||
*/
|
||||
#define kh_put(name, h, k, r) kh_put_##name(h, k, r)
|
||||
|
||||
/*! @function
|
||||
@abstract Retrieve a key from the hash table.
|
||||
@param name Name of the hash table [symbol]
|
||||
@param h Pointer to the hash table [khash_t(name)*]
|
||||
@param k Key [type of keys]
|
||||
@return Iterator to the found element, or kh_end(h) if the element is absent [khint_t]
|
||||
*/
|
||||
#define kh_get(name, h, k) kh_get_##name(h, k)
|
||||
|
||||
/*! @function
|
||||
@abstract Remove a key from the hash table.
|
||||
@param name Name of the hash table [symbol]
|
||||
@param h Pointer to the hash table [khash_t(name)*]
|
||||
@param k Iterator to the element to be deleted [khint_t]
|
||||
*/
|
||||
#define kh_del(name, h, k) kh_del_##name(h, k)
|
||||
|
||||
/*! @function
|
||||
@abstract Test whether a bucket contains data.
|
||||
@param h Pointer to the hash table [khash_t(name)*]
|
||||
@param x Iterator to the bucket [khint_t]
|
||||
@return 1 if containing data; 0 otherwise [int]
|
||||
*/
|
||||
#define kh_exist(h, x) (!__ac_iseither((h)->flags, (x)))
|
||||
|
||||
/*! @function
|
||||
@abstract Get key given an iterator
|
||||
@param h Pointer to the hash table [khash_t(name)*]
|
||||
@param x Iterator to the bucket [khint_t]
|
||||
@return Key [type of keys]
|
||||
*/
|
||||
#define kh_key(h, x) ((h)->keys[x])
|
||||
|
||||
/*! @function
|
||||
@abstract Get value given an iterator
|
||||
@param h Pointer to the hash table [khash_t(name)*]
|
||||
@param x Iterator to the bucket [khint_t]
|
||||
@return Value [type of values]
|
||||
@discussion For hash sets, calling this results in segfault.
|
||||
*/
|
||||
#define kh_val(h, x) ((h)->vals[x])
|
||||
|
||||
/*! @function
|
||||
@abstract Alias of kh_val()
|
||||
*/
|
||||
#define kh_value(h, x) ((h)->vals[x])
|
||||
|
||||
/*! @function
|
||||
@abstract Get the start iterator
|
||||
@param h Pointer to the hash table [khash_t(name)*]
|
||||
@return The start iterator [khint_t]
|
||||
*/
|
||||
#define kh_begin(h) (khint_t)(0)
|
||||
|
||||
/*! @function
|
||||
@abstract Get the end iterator
|
||||
@param h Pointer to the hash table [khash_t(name)*]
|
||||
@return The end iterator [khint_t]
|
||||
*/
|
||||
#define kh_end(h) ((h)->n_buckets)
|
||||
|
||||
/*! @function
|
||||
@abstract Get the number of elements in the hash table
|
||||
@param h Pointer to the hash table [khash_t(name)*]
|
||||
@return Number of elements in the hash table [khint_t]
|
||||
*/
|
||||
#define kh_size(h) ((h)->size)
|
||||
|
||||
/*! @function
|
||||
@abstract Get the number of buckets in the hash table
|
||||
@param h Pointer to the hash table [khash_t(name)*]
|
||||
@return Number of buckets in the hash table [khint_t]
|
||||
*/
|
||||
#define kh_n_buckets(h) ((h)->n_buckets)
|
||||
|
||||
/*! @function
|
||||
@abstract Iterate over the entries in the hash table
|
||||
@param h Pointer to the hash table [khash_t(name)*]
|
||||
@param kvar Variable to which key will be assigned
|
||||
@param vvar Variable to which value will be assigned
|
||||
@param code Block of code to execute
|
||||
*/
|
||||
#define kh_foreach(h, kvar, vvar, code) { khint_t __i; \
|
||||
for (__i = kh_begin(h); __i != kh_end(h); ++__i) { \
|
||||
if (!kh_exist(h,__i)) continue; \
|
||||
(kvar) = kh_key(h,__i); \
|
||||
(vvar) = kh_val(h,__i); \
|
||||
code; \
|
||||
} }
|
||||
|
||||
/*! @function
|
||||
@abstract Iterate over the values in the hash table
|
||||
@param h Pointer to the hash table [khash_t(name)*]
|
||||
@param vvar Variable to which value will be assigned
|
||||
@param code Block of code to execute
|
||||
*/
|
||||
#define kh_foreach_value(h, vvar, code) { khint_t __i; \
|
||||
for (__i = kh_begin(h); __i != kh_end(h); ++__i) { \
|
||||
if (!kh_exist(h,__i)) continue; \
|
||||
(vvar) = kh_val(h,__i); \
|
||||
code; \
|
||||
} }
|
||||
|
||||
/* More convenient interfaces */
|
||||
|
||||
/*! @function
|
||||
@abstract Instantiate a hash set containing integer keys
|
||||
@param name Name of the hash table [symbol]
|
||||
*/
|
||||
#define KHASH_SET_INIT_INT(name) \
|
||||
KHASH_INIT(name, khint32_t, char, 0, kh_int_hash_func, kh_int_hash_equal)
|
||||
|
||||
/*! @function
|
||||
@abstract Instantiate a hash map containing integer keys
|
||||
@param name Name of the hash table [symbol]
|
||||
@param khval_t Type of values [type]
|
||||
*/
|
||||
#define KHASH_MAP_INIT_INT(name, khval_t) \
|
||||
KHASH_INIT(name, khint32_t, khval_t, 1, kh_int_hash_func, kh_int_hash_equal)
|
||||
|
||||
/*! @function
|
||||
@abstract Instantiate a hash set containing 64-bit integer keys
|
||||
@param name Name of the hash table [symbol]
|
||||
*/
|
||||
#define KHASH_SET_INIT_INT64(name) \
|
||||
KHASH_INIT(name, khint64_t, char, 0, kh_int64_hash_func, kh_int64_hash_equal)
|
||||
|
||||
/*! @function
|
||||
@abstract Instantiate a hash map containing 64-bit integer keys
|
||||
@param name Name of the hash table [symbol]
|
||||
@param khval_t Type of values [type]
|
||||
*/
|
||||
#define KHASH_MAP_INIT_INT64(name, khval_t) \
|
||||
KHASH_INIT(name, khint64_t, khval_t, 1, kh_int64_hash_func, kh_int64_hash_equal)
|
||||
|
||||
typedef const char *kh_cstr_t;
|
||||
/*! @function
|
||||
@abstract Instantiate a hash map containing const char* keys
|
||||
@param name Name of the hash table [symbol]
|
||||
*/
|
||||
#define KHASH_SET_INIT_STR(name) \
|
||||
KHASH_INIT(name, kh_cstr_t, char, 0, kh_str_hash_func, kh_str_hash_equal)
|
||||
|
||||
/*! @function
|
||||
@abstract Instantiate a hash map containing const char* keys
|
||||
@param name Name of the hash table [symbol]
|
||||
@param khval_t Type of values [type]
|
||||
*/
|
||||
#define KHASH_MAP_INIT_STR(name, khval_t) \
|
||||
KHASH_INIT(name, kh_cstr_t, khval_t, 1, kh_str_hash_func, kh_str_hash_equal)
|
||||
|
||||
#endif /* __AC_KHASH_H */
|
@ -0,0 +1,33 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
struct linkedListNode {
|
||||
void *data;
|
||||
unsigned long long expiredAt;
|
||||
struct linkedListNode *next;
|
||||
struct linkedListNode *prev;
|
||||
};
|
||||
|
||||
struct linkedList {
|
||||
unsigned int cap;
|
||||
unsigned int size;
|
||||
unsigned int overWrite;
|
||||
unsigned long long expiredAt;
|
||||
|
||||
struct linkedListNode *head;
|
||||
struct linkedListNode *tail;
|
||||
};
|
||||
|
||||
int linkedList_replace_head(struct linkedList *list,
|
||||
void *data,
|
||||
unsigned long long expiredAt);
|
||||
int linkedList_init(struct linkedList **list,
|
||||
unsigned int cap,
|
||||
unsigned int overWrite,
|
||||
unsigned long long expiredAt);
|
||||
int linkedList_enqueue(struct linkedList *list,
|
||||
void *data,
|
||||
unsigned long long expiredAt);
|
||||
int linkedList_dequeue(struct linkedList *list,
|
||||
void **data);
|
||||
int linkedList_release(struct linkedList *list);
|
@ -0,0 +1,111 @@
|
||||
#ifndef NNG_NANOLIB_LOG_H
|
||||
#define NNG_NANOLIB_LOG_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "nng/nng.h"
|
||||
|
||||
#define LOG_VERSION "0.2.1"
|
||||
|
||||
/**
|
||||
* 2023-12-08 move conf_log to log.h
|
||||
*/
|
||||
|
||||
// log type
|
||||
#define LOG_TO_FILE (1 << 0)
|
||||
#define LOG_TO_CONSOLE (1 << 1)
|
||||
#define LOG_TO_SYSLOG (1 << 2)
|
||||
#define LOG_TO_UDS (1 << 3)
|
||||
|
||||
typedef struct conf_log conf_log;
|
||||
struct conf_log {
|
||||
uint8_t type;
|
||||
int level;
|
||||
char *dir;
|
||||
char *file;
|
||||
char *uds_addr;
|
||||
FILE *fp;
|
||||
char *abs_path; // absolut path of log file
|
||||
char *rotation_sz_str; // 1000KB, 100MB, 10GB
|
||||
uint64_t rotation_sz; // unit: byte
|
||||
size_t rotation_count; // rotation count
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
va_list ap;
|
||||
const char *fmt;
|
||||
const char *file;
|
||||
const char *func;
|
||||
struct tm time;
|
||||
void * udata;
|
||||
int line;
|
||||
int level;
|
||||
conf_log * config;
|
||||
} log_event;
|
||||
|
||||
typedef void (*log_func)(log_event *ev);
|
||||
|
||||
enum {
|
||||
NNG_LOG_FATAL = 0,
|
||||
NNG_LOG_ERROR,
|
||||
NNG_LOG_WARN,
|
||||
NNG_LOG_INFO,
|
||||
NNG_LOG_DEBUG,
|
||||
NNG_LOG_TRACE,
|
||||
};
|
||||
|
||||
NNG_DECL const char *log_level_string(int level);
|
||||
NNG_DECL int log_level_num(const char *level);
|
||||
NNG_DECL void log_set_level(int level);
|
||||
NNG_DECL int log_add_callback(
|
||||
log_func fn, void *udata, int level, void *mtx, conf_log *config);
|
||||
NNG_DECL void log_add_console(int level, void *mtx);
|
||||
NNG_DECL int log_add_fp(FILE *fp, int level, void *mtx, conf_log *config);
|
||||
NNG_DECL void log_add_syslog(const char *log_name, uint8_t level, void *mtx);
|
||||
NNG_DECL void log_add_uds(const char *uds_path, const char *log_name, uint8_t level, void *mtx);
|
||||
NNG_DECL void uds_closelog(void);
|
||||
NNG_DECL void log_log(int level, const char *file, int line, const char *func,
|
||||
const char *fmt, ...);
|
||||
NNG_DECL void log_clear_callback();
|
||||
#ifdef ENABLE_LOG
|
||||
|
||||
#define log_trace(...) \
|
||||
log_log(NNG_LOG_TRACE, __FILE__, __LINE__, __FUNCTION__, __VA_ARGS__)
|
||||
#define log_debug(...) \
|
||||
log_log(NNG_LOG_DEBUG, __FILE__, __LINE__, __FUNCTION__, __VA_ARGS__)
|
||||
#define log_info(...) \
|
||||
log_log(NNG_LOG_INFO, __FILE__, __LINE__, __FUNCTION__, __VA_ARGS__)
|
||||
#define log_warn(...) \
|
||||
log_log(NNG_LOG_WARN, __FILE__, __LINE__, __FUNCTION__, __VA_ARGS__)
|
||||
#define log_error(...) \
|
||||
log_log(NNG_LOG_ERROR, __FILE__, __LINE__, __FUNCTION__, __VA_ARGS__)
|
||||
#define log_fatal(...) \
|
||||
log_log(NNG_LOG_FATAL, __FILE__, __LINE__, __FUNCTION__, __VA_ARGS__)
|
||||
|
||||
#else
|
||||
|
||||
static inline void dummy_log_function(const char *fmt, ...) { (void)fmt; }
|
||||
|
||||
#define log_trace(...) dummy_log_function(__VA_ARGS__)
|
||||
#define log_debug(...) dummy_log_function(__VA_ARGS__)
|
||||
#define log_info(...) dummy_log_function(__VA_ARGS__)
|
||||
#define log_warn(...) dummy_log_function(__VA_ARGS__)
|
||||
#define log_error(...) dummy_log_function(__VA_ARGS__)
|
||||
#define log_fatal(...) dummy_log_function(__VA_ARGS__)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -0,0 +1,77 @@
|
||||
#ifndef NANOLIB_MD5_H
|
||||
#define NANOLIB_MD5_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#if defined(__WINDOWS__) || defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32)
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#define READ_DATA_SIZE 1024
|
||||
#define MD5_SIZE 16
|
||||
#define MD5_STR_LEN (MD5_SIZE * 2)
|
||||
#define MD5_LEN 32
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned int count[2];
|
||||
unsigned int state[4];
|
||||
unsigned char buffer[64];
|
||||
} MD5_CTX;
|
||||
|
||||
|
||||
#define F(x,y,z) ((x & y) | (~x & z))
|
||||
#define G(x,y,z) ((x & z) | (y & ~z))
|
||||
#define H(x,y,z) (x^y^z)
|
||||
#define I(x,y,z) (y ^ (x | ~z))
|
||||
#define ROTATE_LEFT(x,n) ((x << n) | (x >> (32-n)))
|
||||
|
||||
#define FF(a,b,c,d,x,s,ac) \
|
||||
{ \
|
||||
a += F(b,c,d) + x + ac; \
|
||||
a = ROTATE_LEFT(a,s); \
|
||||
a += b; \
|
||||
}
|
||||
#define GG(a,b,c,d,x,s,ac) \
|
||||
{ \
|
||||
a += G(b,c,d) + x + ac; \
|
||||
a = ROTATE_LEFT(a,s); \
|
||||
a += b; \
|
||||
}
|
||||
#define HH(a,b,c,d,x,s,ac) \
|
||||
{ \
|
||||
a += H(b,c,d) + x + ac; \
|
||||
a = ROTATE_LEFT(a,s); \
|
||||
a += b; \
|
||||
}
|
||||
#define II(a,b,c,d,x,s,ac) \
|
||||
{ \
|
||||
a += I(b,c,d) + x + ac; \
|
||||
a = ROTATE_LEFT(a,s); \
|
||||
a += b; \
|
||||
}
|
||||
|
||||
int ComputeStringMD5(unsigned char *dest_str, unsigned int dest_len, char *md5_str);
|
||||
int ComputeFileMD5(const char *file_path, char *md5_str);
|
||||
|
||||
void MD5Init(MD5_CTX *context);
|
||||
void MD5Update(MD5_CTX *context, unsigned char *input, unsigned int inputlen);
|
||||
void MD5Final(MD5_CTX *context, unsigned char digest[16]);
|
||||
void MD5Transform(unsigned int state[4], unsigned char block[64]);
|
||||
void MD5Encode(unsigned char *output, unsigned int *input, unsigned int len);
|
||||
void MD5Decode(unsigned int *output, unsigned char *input, unsigned int len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -0,0 +1,138 @@
|
||||
#ifndef MQTT_DB_H
|
||||
#define MQTT_DB_H
|
||||
|
||||
#include "cvector.h"
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "nng/nng.h"
|
||||
|
||||
|
||||
typedef enum {
|
||||
MQTT_VERSION_V311 = 4,
|
||||
MQTT_VERSION_V5 = 5,
|
||||
} mqtt_version_t;
|
||||
|
||||
typedef struct dbtree dbtree;
|
||||
|
||||
typedef struct {
|
||||
char * topic;
|
||||
char **clients;
|
||||
int cld_cnt;
|
||||
} dbtree_info;
|
||||
|
||||
/**
|
||||
* @brief dbtree_create - Create a dbtree.
|
||||
* @param dbtree - dbtree
|
||||
* @return void
|
||||
*/
|
||||
NNG_DECL void dbtree_create(dbtree **db);
|
||||
|
||||
/**
|
||||
* @brief dbtree_destory - Destory dbtree tree
|
||||
* @param dbtree - dbtree
|
||||
* @return void
|
||||
*/
|
||||
NNG_DECL void dbtree_destory(dbtree *db);
|
||||
|
||||
/**
|
||||
* @brief dbtree_print - Print dbtree for debug.
|
||||
* @param dbtree - dbtree
|
||||
* @return void
|
||||
*/
|
||||
NNG_DECL void dbtree_print(dbtree *db);
|
||||
|
||||
/**
|
||||
* @brief dbtree_insert_client - check if this
|
||||
* topic and pipe id is exist on the tree, if
|
||||
* there is not exist, this func will insert node
|
||||
* recursively until find all topic then insert
|
||||
* client on the node.
|
||||
* @param dbtree - dbtree_node
|
||||
* @param topic - topic
|
||||
* @param pipe_id - pipe id
|
||||
* @return
|
||||
*/
|
||||
NNG_DECL void *dbtree_insert_client(
|
||||
dbtree *db, char *topic, uint32_t pipe_id);
|
||||
|
||||
/**
|
||||
* @brief dbtree_find_client - check if this
|
||||
* topic and pipe id is exist on the tree, if
|
||||
* there is not exist, return it.
|
||||
* @param dbtree - dbtree_node
|
||||
* @param topic - topic
|
||||
* @param ctxt - data related with pipe_id
|
||||
* @param pipe_id - pipe id
|
||||
* @return
|
||||
*/
|
||||
// void *dbtree_find_client(dbtree *db, char *topic, uint32_t pipe_id);
|
||||
|
||||
/**
|
||||
* @brief dbtree_delete_client - This function will
|
||||
* be called when disconnection and cleansession = 1.
|
||||
* check if this topic and client id is exist on the
|
||||
* tree, if there is exist, this func will delete
|
||||
* related node and client on the tree
|
||||
* @param dbtree - dbtree
|
||||
* @param topic - topic
|
||||
* @param pipe_id - pipe id
|
||||
* @return
|
||||
*/
|
||||
NNG_DECL void *dbtree_delete_client(
|
||||
dbtree *db, char *topic, uint32_t pipe_id);
|
||||
|
||||
/**
|
||||
* @brief dbtree_find_clients_and_cache_msg - Get all
|
||||
* subscribers online to this topic
|
||||
* @param dbtree - dbtree
|
||||
* @param topic - topic
|
||||
* @return pipe id array
|
||||
*/
|
||||
NNG_DECL uint32_t *dbtree_find_clients(dbtree *db, char *topic);
|
||||
|
||||
/**
|
||||
* @brief dbtree_insert_retain - Insert retain message to this topic.
|
||||
* @param db - dbtree
|
||||
* @param topic - topic
|
||||
* @param ret_msg - dbtree_retain_msg
|
||||
* @return
|
||||
*/
|
||||
NNG_DECL nng_msg *dbtree_insert_retain(
|
||||
dbtree *db, char *topic, nng_msg *ret_msg);
|
||||
|
||||
/**
|
||||
* @brief dbtree_delete_retain - Delete all retain message to this topic.
|
||||
* @param db - dbtree
|
||||
* @param topic - topic
|
||||
* @return ctxt or NULL, if client can be delete or not
|
||||
*/
|
||||
NNG_DECL nng_msg *dbtree_delete_retain(dbtree *db, char *topic);
|
||||
|
||||
/**
|
||||
* @brief dbtree_find_retain - Get all retain message to this topic.
|
||||
* @param db - dbtree
|
||||
* @param topic - topic
|
||||
* @return dbtree_retain_msg pointer vector
|
||||
*/
|
||||
NNG_DECL nng_msg **dbtree_find_retain(dbtree *db, char *topic);
|
||||
|
||||
/**
|
||||
* @brief dbtree_find_shared_clients - This function
|
||||
* will Find shared subscribe client.
|
||||
* @param dbtree - dbtree
|
||||
* @param topic - topic
|
||||
* @return pipe id array
|
||||
*/
|
||||
NNG_DECL uint32_t *dbtree_find_shared_clients(dbtree *db, char *topic);
|
||||
|
||||
/**
|
||||
* @brief dbtree_get_tree - This function will
|
||||
* get all info about this tree.
|
||||
* @param dbtree - dbtree
|
||||
* @param cb - a callback function
|
||||
* @return all info about this tree
|
||||
*/
|
||||
NNG_DECL void ***dbtree_get_tree(dbtree *db, void *(*cb)(uint32_t pipe_id));
|
||||
|
||||
#endif
|
@ -0,0 +1,10 @@
|
||||
#ifndef NANOLIB_H
|
||||
#define NANOLIB_H
|
||||
|
||||
#include "hash_table.h"
|
||||
#include "mqtt_db.h"
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#endif
|
@ -0,0 +1,76 @@
|
||||
#ifndef PARQUET_H
|
||||
#define PARQUET_H
|
||||
#include "nng/nng.h"
|
||||
#include "nng/supplemental/nanolib/conf.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct parquet_object parquet_object;
|
||||
typedef void (*parquet_cb)(parquet_object *arg);
|
||||
|
||||
typedef enum {
|
||||
WRITE_TO_NORMAL,
|
||||
WRITE_TO_TEMP,
|
||||
} parquet_write_type;
|
||||
|
||||
typedef struct {
|
||||
uint32_t start_idx;
|
||||
uint32_t end_idx;
|
||||
char *filename;
|
||||
} parquet_file_range;
|
||||
|
||||
typedef struct {
|
||||
parquet_file_range **range;
|
||||
int size;
|
||||
int start; // file range start index
|
||||
} parquet_file_ranges;
|
||||
|
||||
typedef struct {
|
||||
uint8_t *data;
|
||||
uint32_t size;
|
||||
} parquet_data_packet;
|
||||
|
||||
struct parquet_object {
|
||||
uint64_t *keys;
|
||||
uint8_t **darray;
|
||||
uint32_t *dsize;
|
||||
uint32_t size;
|
||||
nng_aio *aio;
|
||||
void *arg;
|
||||
parquet_file_ranges *ranges;
|
||||
parquet_write_type type;
|
||||
char *topic;
|
||||
};
|
||||
|
||||
parquet_object *parquet_object_alloc(uint64_t *keys, uint8_t **darray,
|
||||
uint32_t *dsize, uint32_t size, nng_aio *aio, void *arg);
|
||||
void parquet_object_free(parquet_object *elem);
|
||||
|
||||
parquet_file_range *parquet_file_range_alloc(uint32_t start_idx, uint32_t end_idx, char *filename);
|
||||
void parquet_file_range_free(parquet_file_range *range);
|
||||
|
||||
void parquet_object_set_cb(parquet_object *obj, parquet_cb cb);
|
||||
int parquet_write_batch_async(parquet_object *elem);
|
||||
// Write a batch to a temporary Parquet file, utilize it in scenarios where a single
|
||||
// file is sufficient for writing, sending, and subsequent deletion.
|
||||
int parquet_write_batch_tmp_async(parquet_object *elem);
|
||||
int parquet_write_launcher(conf_parquet *conf);
|
||||
|
||||
const char *parquet_find(uint64_t key);
|
||||
const char **parquet_find_span(
|
||||
uint64_t start_key, uint64_t end_key, uint32_t *size);
|
||||
|
||||
parquet_data_packet *parquet_find_data_packet(conf_parquet *conf, char *filename, uint64_t key);
|
||||
|
||||
parquet_data_packet **parquet_find_data_packets(conf_parquet *conf, char **filenames, uint64_t *keys, uint32_t len);
|
||||
|
||||
parquet_data_packet **parquet_find_data_span_packets(conf_parquet *conf, uint64_t start_key, uint64_t end_key, uint32_t *size, char *topic);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -0,0 +1,105 @@
|
||||
/* A Bison parser, made by GNU Bison 3.8.2. */
|
||||
|
||||
/* Bison interface for Yacc-like parsers in C
|
||||
|
||||
Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation,
|
||||
Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* As a special exception, you may create a larger work that contains
|
||||
part or all of the Bison parser skeleton and distribute that work
|
||||
under terms of your choice, so long as that work isn't itself a
|
||||
parser generator using the skeleton or a modified version thereof
|
||||
as a parser skeleton. Alternatively, if you modify or redistribute
|
||||
the parser skeleton itself, you may (at your option) remove this
|
||||
special exception, which will cause the skeleton and the resulting
|
||||
Bison output files to be licensed under the GNU General Public
|
||||
License without this special exception.
|
||||
|
||||
This special exception was added by the Free Software Foundation in
|
||||
version 2.2 of Bison. */
|
||||
|
||||
/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual,
|
||||
especially those whose name start with YY_ or yy_. They are
|
||||
private implementation details that can be changed or removed. */
|
||||
|
||||
#ifndef YY_YY_NANOMQ_NNG_SRC_SUPPLEMENTAL_NANOLIB_PARSER_H_INCLUDED
|
||||
# define YY_YY_NANOMQ_NNG_SRC_SUPPLEMENTAL_NANOLIB_PARSER_H_INCLUDED
|
||||
/* Debug traces. */
|
||||
#ifndef YYDEBUG
|
||||
# define YYDEBUG 0
|
||||
#endif
|
||||
#if YYDEBUG
|
||||
extern int yydebug;
|
||||
#endif
|
||||
|
||||
/* Token kinds. */
|
||||
#ifndef YYTOKENTYPE
|
||||
# define YYTOKENTYPE
|
||||
enum yytokentype
|
||||
{
|
||||
YYEMPTY = -2,
|
||||
YYEOF = 0, /* "end of file" */
|
||||
YYerror = 256, /* error */
|
||||
YYUNDEF = 257, /* "invalid token" */
|
||||
LCURLY = 258, /* LCURLY */
|
||||
RCURLY = 259, /* RCURLY */
|
||||
LBRAC = 260, /* LBRAC */
|
||||
RBRAC = 261, /* RBRAC */
|
||||
COMMA = 262, /* COMMA */
|
||||
PUNCT = 263, /* PUNCT */
|
||||
VTRUE = 264, /* VTRUE */
|
||||
VFALSE = 265, /* VFALSE */
|
||||
VNULL = 266, /* VNULL */
|
||||
STRING = 267, /* STRING */
|
||||
USTRING = 268, /* USTRING */
|
||||
RSTRING = 269, /* RSTRING */
|
||||
BYTESIZE = 270, /* BYTESIZE */
|
||||
PERCENT = 271, /* PERCENT */
|
||||
DURATION = 272, /* DURATION */
|
||||
DECIMAL = 273, /* DECIMAL */
|
||||
INTEGER = 274 /* INTEGER */
|
||||
};
|
||||
typedef enum yytokentype yytoken_kind_t;
|
||||
#endif
|
||||
|
||||
/* Value type. */
|
||||
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
||||
union YYSTYPE
|
||||
{
|
||||
#line 25 "parser.y"
|
||||
|
||||
double intval;
|
||||
double floatval;
|
||||
char *strval;
|
||||
struct cJSON *jsonval;
|
||||
struct jso_kv *jkval;
|
||||
|
||||
#line 91 "nng/src/supplemental/nanolib/parser.h"
|
||||
|
||||
};
|
||||
typedef union YYSTYPE YYSTYPE;
|
||||
# define YYSTYPE_IS_TRIVIAL 1
|
||||
# define YYSTYPE_IS_DECLARED 1
|
||||
#endif
|
||||
|
||||
|
||||
extern YYSTYPE yylval;
|
||||
|
||||
|
||||
int yyparse (struct cJSON **jso);
|
||||
|
||||
|
||||
#endif /* !YY_YY_NANOMQ_NNG_SRC_SUPPLEMENTAL_NANOLIB_PARSER_H_INCLUDED */
|
@ -0,0 +1,87 @@
|
||||
#ifndef QUEUE_H
|
||||
#define QUEUE_H
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define INITIAL_SIZE 5
|
||||
|
||||
typedef struct {
|
||||
void** array;
|
||||
int front;
|
||||
int rear;
|
||||
int size;
|
||||
int capacity;
|
||||
} CircularQueue;
|
||||
|
||||
|
||||
#define INIT_QUEUE(queue) \
|
||||
do { \
|
||||
(queue).array = (void**)malloc(INITIAL_SIZE * sizeof(void*)); \
|
||||
(queue).front = -1; \
|
||||
(queue).rear = -1; \
|
||||
(queue).size = 0; \
|
||||
(queue).capacity = INITIAL_SIZE; \
|
||||
} while(0)
|
||||
|
||||
#define NEXT_INDEX(index, size) (((index) + 1) % (size))
|
||||
|
||||
#define IS_EMPTY(queue) ((queue).size == 0)
|
||||
|
||||
#define QUEUE_SIZE(queue) ((queue).size)
|
||||
|
||||
#define ENQUEUE(queue, element) \
|
||||
do { \
|
||||
if ((queue).size == (queue).capacity) { \
|
||||
int new_capacity = (queue).capacity * 2; \
|
||||
void** new_array = (void**)malloc(new_capacity * sizeof(void*)); \
|
||||
int i = 0; \
|
||||
int j = (queue).front; \
|
||||
while (i < (queue).size) { \
|
||||
new_array[i] = (queue).array[j]; \
|
||||
i++; \
|
||||
j = NEXT_INDEX(j, (queue).capacity); \
|
||||
} \
|
||||
free((queue).array); \
|
||||
(queue).array = new_array; \
|
||||
(queue).front = 0; \
|
||||
(queue).rear = (queue).size - 1; \
|
||||
(queue).capacity = new_capacity; \
|
||||
} \
|
||||
if (IS_EMPTY(queue)) { \
|
||||
(queue).front = 0; \
|
||||
} \
|
||||
(queue).rear = NEXT_INDEX((queue).rear, (queue).capacity); \
|
||||
(queue).array[(queue).rear] = (element); \
|
||||
(queue).size++; \
|
||||
} while(0)
|
||||
|
||||
#define DEQUEUE(queue) \
|
||||
({ \
|
||||
void* dequeued_element = NULL; \
|
||||
if (IS_EMPTY(queue)) { \
|
||||
printf("Queue is empty. Cannot dequeue.\n"); \
|
||||
} else { \
|
||||
dequeued_element = (queue).array[(queue).front]; \
|
||||
(queue).front = NEXT_INDEX((queue).front, (queue).capacity); \
|
||||
(queue).size--; \
|
||||
if (IS_EMPTY(queue)) { \
|
||||
(queue).front = -1; \
|
||||
(queue).rear = -1; \
|
||||
} \
|
||||
} \
|
||||
dequeued_element; \
|
||||
})
|
||||
|
||||
|
||||
#define FOREACH_QUEUE(queue, elem) \
|
||||
for (int i = (queue).front, _count = 0; \
|
||||
(queue).size != 0 && _count < (queue).size; \
|
||||
i = NEXT_INDEX(i, (queue).capacity), _count++) \
|
||||
\
|
||||
for (elem = (queue).array[i]; \
|
||||
elem != NULL; \
|
||||
elem = NULL)
|
||||
|
||||
#define DESTROY_QUEUE(queue) free((queue).array)
|
||||
|
||||
#endif
|
@ -0,0 +1,138 @@
|
||||
//
|
||||
// Copyright 2023 NanoMQ Team, Inc. <jaylin@emqx.io>
|
||||
//
|
||||
// This software is supplied under the terms of the MIT License, a
|
||||
// copy of which should be located in the distribution where this
|
||||
// file was obtained (LICENSE.txt). A copy of the license may also be
|
||||
// found online at https://opensource.org/licenses/MIT.
|
||||
//
|
||||
|
||||
#ifndef RINGBUFFER_H
|
||||
#define RINGBUFFER_H
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "nng/nng.h"
|
||||
#include "nng/supplemental/util/platform.h"
|
||||
#include "nng/supplemental/nanolib/cvector.h"
|
||||
|
||||
#define RBNAME_LEN 100
|
||||
#define RINGBUFFER_MAX_SIZE 0xffffffff
|
||||
#define RBRULELIST_MAX_SIZE 0xff
|
||||
|
||||
#define ENQUEUE_IN_HOOK 0x0001
|
||||
#define ENQUEUE_OUT_HOOK 0x0010
|
||||
#define DEQUEUE_IN_HOOK 0x0100
|
||||
#define DEQUEUE_OUT_HOOK 0x1000
|
||||
#define HOOK_MASK ((ENQUEUE_IN_HOOK) | (ENQUEUE_OUT_HOOK) | (DEQUEUE_IN_HOOK) | (DEQUEUE_OUT_HOOK))
|
||||
|
||||
typedef struct ringBuffer_s ringBuffer_t;
|
||||
typedef struct ringBufferMsg_s ringBufferMsg_t;
|
||||
typedef struct ringBufferRule_s ringBufferRule_t;
|
||||
|
||||
/* For RB_FULL_FILE */
|
||||
typedef struct ringBufferFile_s ringBufferFile_t;
|
||||
typedef struct ringBufferFileRange_s ringBufferFileRange_t;
|
||||
|
||||
struct ringBufferMsg_s {
|
||||
uint64_t key;
|
||||
void *data;
|
||||
/* TTL of each message */
|
||||
unsigned long long expiredAt;
|
||||
};
|
||||
|
||||
enum fullOption {
|
||||
RB_FULL_NONE,
|
||||
RB_FULL_DROP,
|
||||
RB_FULL_RETURN,
|
||||
RB_FULL_FILE,
|
||||
|
||||
RB_FULL_MAX
|
||||
};
|
||||
|
||||
struct ringBufferFileRange_s {
|
||||
uint64_t startidx;
|
||||
uint64_t endidx;
|
||||
char *filename;
|
||||
};
|
||||
|
||||
struct ringBufferFile_s {
|
||||
uint64_t *keys;
|
||||
nng_aio *aio;
|
||||
ringBufferFileRange_t **ranges;
|
||||
};
|
||||
|
||||
struct ringBuffer_s {
|
||||
char name[RBNAME_LEN];
|
||||
unsigned int head;
|
||||
unsigned int tail;
|
||||
unsigned int size;
|
||||
unsigned int cap;
|
||||
/* TTL of all messages in ringbuffer */
|
||||
unsigned long long expiredAt;
|
||||
unsigned int enqinRuleListLen;
|
||||
unsigned int enqoutRuleListLen;
|
||||
unsigned int deqinRuleListLen;
|
||||
unsigned int deqoutRuleListLen;
|
||||
ringBufferRule_t *enqinRuleList[RBRULELIST_MAX_SIZE];
|
||||
ringBufferRule_t *enqoutRuleList[RBRULELIST_MAX_SIZE];
|
||||
ringBufferRule_t *deqinRuleList[RBRULELIST_MAX_SIZE];
|
||||
ringBufferRule_t *deqoutRuleList[RBRULELIST_MAX_SIZE];
|
||||
|
||||
enum fullOption fullOp;
|
||||
|
||||
/* FOR RB_FULL_FILE */
|
||||
ringBufferFile_t **files;
|
||||
|
||||
nng_mtx *ring_lock;
|
||||
|
||||
ringBufferMsg_t *msgs;
|
||||
};
|
||||
|
||||
struct ringBufferRule_s {
|
||||
/*
|
||||
* flag: ENQUEUE_IN_HOOK/ENQUEUE_OUT_HOOK/DEQUEUE_IN_HOOK/DEQUEUE_OUT_HOOK
|
||||
* return: 0: success, -1: failed
|
||||
*/
|
||||
int (*match)(ringBuffer_t *rb, void *data, int flag);
|
||||
/*
|
||||
* return: 0: continue, -1: stop and return
|
||||
*/
|
||||
int (*target)(ringBuffer_t *rb, void *data, int flag);
|
||||
};
|
||||
|
||||
|
||||
int ringBuffer_add_rule(ringBuffer_t *rb,
|
||||
int (*match)(ringBuffer_t *rb, void *data, int flag),
|
||||
int (*target)(ringBuffer_t *rb, void *data, int flag),
|
||||
int flag);
|
||||
|
||||
int ringBuffer_init(ringBuffer_t **rb,
|
||||
unsigned int cap,
|
||||
enum fullOption fullOp,
|
||||
unsigned long long expiredAt);
|
||||
int ringBuffer_enqueue(ringBuffer_t *rb,
|
||||
uint64_t key,
|
||||
void *data,
|
||||
unsigned long long expiredAt,
|
||||
nng_aio *aio);
|
||||
int ringBuffer_dequeue(ringBuffer_t *rb, void **data);
|
||||
int ringBuffer_release(ringBuffer_t *rb);
|
||||
|
||||
int ringBuffer_search_msg_by_key(ringBuffer_t *rb, uint64_t key, nng_msg **msg);
|
||||
int ringBuffer_search_msgs_by_key(ringBuffer_t *rb, uint64_t key, uint32_t count, nng_msg ***list);
|
||||
int ringBuffer_search_msgs_fuzz(ringBuffer_t *rb,
|
||||
uint64_t start,
|
||||
uint64_t end,
|
||||
uint32_t *count,
|
||||
nng_msg ***list);
|
||||
int ringBuffer_get_and_clean_msgs(ringBuffer_t *rb,
|
||||
unsigned int *count, nng_msg ***list);
|
||||
|
||||
int ringBuffer_set_fullOp(ringBuffer_t *rb, enum fullOption fullOp);
|
||||
#ifdef SUPP_PARQUET
|
||||
int ringBuffer_get_msgs_from_file(ringBuffer_t *rb, void ***msgs, int **msgLen);
|
||||
int ringBuffer_get_msgs_from_file_by_keys(ringBuffer_t *rb, uint64_t *keys, uint32_t count,
|
||||
void ***msgs, int **msgLen);
|
||||
#endif
|
||||
|
||||
#endif
|
@ -0,0 +1,138 @@
|
||||
#ifndef RULE_H
|
||||
#define RULE_H
|
||||
#include <stdint.h>
|
||||
#include "nng/nng.h"
|
||||
#include "nng/supplemental/util/platform.h"
|
||||
|
||||
typedef enum {
|
||||
RULE_QOS,
|
||||
RULE_ID,
|
||||
RULE_TOPIC,
|
||||
RULE_CLIENTID,
|
||||
RULE_USERNAME,
|
||||
RULE_PASSWORD,
|
||||
RULE_TIMESTAMP,
|
||||
RULE_PAYLOAD_ALL,
|
||||
RULE_PAYLOAD_FIELD,
|
||||
} rule_type;
|
||||
|
||||
typedef enum {
|
||||
RULE_CMP_NONE, // compare type init value
|
||||
RULE_CMP_EQUAL, // compare symbol '='
|
||||
RULE_CMP_UNEQUAL, // compare symbol '!=' or '<>'
|
||||
RULE_CMP_GREATER, // compare symbol '>'
|
||||
RULE_CMP_LESS, // compare symbol '<'
|
||||
RULE_CMP_GREATER_AND_EQUAL, // compare symbol '>='
|
||||
RULE_CMP_LESS_AND_EQUAL, // compare symbol '<='
|
||||
} rule_cmp_type;
|
||||
|
||||
typedef enum {
|
||||
RULE_FORWORD_SQLITE,
|
||||
RULE_FORWORD_FDB,
|
||||
RULE_FORWORD_MYSQL,
|
||||
RULE_FORWORD_REPUB
|
||||
} rule_forword_type;
|
||||
|
||||
typedef struct {
|
||||
char **psa; // payload string array, for multi level json
|
||||
char *pas; // payload field string or alias
|
||||
char *filter; // payload field related filter
|
||||
rule_cmp_type cmp_type; // payload field compare type
|
||||
bool is_store; // payload value is store or not
|
||||
uint8_t type; // payload field value type
|
||||
void *value; // payload field value
|
||||
} rule_payload;
|
||||
|
||||
typedef struct {
|
||||
bool flag[9];
|
||||
bool auto_inc;
|
||||
uint8_t type;
|
||||
void *value;
|
||||
char **key_arr;
|
||||
} rule_key;
|
||||
|
||||
typedef struct {
|
||||
char *address;
|
||||
uint8_t proto_ver;
|
||||
char *clientid;
|
||||
bool clean_start;
|
||||
char *username;
|
||||
char *password;
|
||||
uint16_t keepalive;
|
||||
char *topic;
|
||||
void *sock;
|
||||
} repub_t;
|
||||
|
||||
typedef struct {
|
||||
char *table;
|
||||
char *host;
|
||||
char *username;
|
||||
char *password;
|
||||
void *conn;
|
||||
} rule_mysql;
|
||||
|
||||
typedef struct {
|
||||
/*
|
||||
** flag[0] == RULE_QOS,
|
||||
** flag[1] == RULE_ID,
|
||||
** flag[2] == RULE_TOPIC,
|
||||
** flag[3] == RULE_CLIENTID,
|
||||
** flag[4] == RULE_USERNAME,
|
||||
** flag[5] == RULE_PASSWORD,
|
||||
** flag[6] == RULE_TIMESTAMP,
|
||||
** flag[7] == RULE_PAYLOAD_ALL,
|
||||
** flag[8] == RULE_PAYLOAD_FIELD,
|
||||
*/
|
||||
bool flag[9]; // if this field need to store
|
||||
bool enabled; // if this rule is enabled
|
||||
rule_cmp_type cmp_type[8]; // filter compare type
|
||||
rule_forword_type forword_type; // forword type
|
||||
char *topic; // topic parse from sql 'from'
|
||||
char *as[8]; // if field string as a new string
|
||||
rule_payload **payload; // this is for payload info
|
||||
char **filter; // filter parse from sql 'where'
|
||||
char *sqlite_table;
|
||||
char *raw_sql;
|
||||
uint32_t rule_id;
|
||||
rule_key *key;
|
||||
repub_t *repub;
|
||||
rule_mysql *mysql;
|
||||
} rule;
|
||||
|
||||
typedef struct {
|
||||
/*
|
||||
** 00000000 == OFF,
|
||||
** 00000001 == Sqlite ON,
|
||||
** 00000010 == Fdb ON,
|
||||
** 00000100 == MySOL ON
|
||||
** 00001000 == Repub ON
|
||||
** 00010000
|
||||
** 00100000
|
||||
** 01000000
|
||||
*/
|
||||
uint8_t option;
|
||||
/*
|
||||
** rdb[0] == Sqlite
|
||||
** rdb[1] == Fdb
|
||||
** rdb[2] == MySOL
|
||||
** rdb[3] == RePub
|
||||
*/
|
||||
void *rdb[3];
|
||||
rule *rules;
|
||||
char *sqlite_db;
|
||||
char *mysql_db;
|
||||
nng_mtx *rule_mutex;
|
||||
} conf_rule;
|
||||
|
||||
int rule_find_key(const char *str, size_t len);
|
||||
uint32_t rule_generate_rule_id(void);
|
||||
char *rule_get_key_arr(char *p, rule_key *key);
|
||||
bool rule_sql_parse(conf_rule *cr, char *sql);
|
||||
repub_t *rule_repub_init(void);
|
||||
void rule_repub_free(repub_t *repub);
|
||||
void rule_free(rule *r);
|
||||
bool rule_mysql_check(rule_mysql *mysql);
|
||||
void rule_mysql_free(rule_mysql *mysql);
|
||||
rule_mysql *rule_mysql_init(void);
|
||||
|
||||
#endif
|
@ -0,0 +1,479 @@
|
||||
#ifndef yyHEADER_H
|
||||
#define yyHEADER_H 1
|
||||
#define yyIN_HEADER 1
|
||||
|
||||
#line 6 "nng/src/supplemental/nanolib/scanner.h"
|
||||
|
||||
#line 8 "nng/src/supplemental/nanolib/scanner.h"
|
||||
|
||||
#define YY_INT_ALIGNED short int
|
||||
|
||||
/* A lexical scanner generated by flex */
|
||||
|
||||
#define FLEX_SCANNER
|
||||
#define YY_FLEX_MAJOR_VERSION 2
|
||||
#define YY_FLEX_MINOR_VERSION 6
|
||||
#define YY_FLEX_SUBMINOR_VERSION 4
|
||||
#if YY_FLEX_SUBMINOR_VERSION > 0
|
||||
#define FLEX_BETA
|
||||
#endif
|
||||
|
||||
/* First, we deal with platform-specific or compiler-specific issues. */
|
||||
|
||||
/* begin standard C headers. */
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* end standard C headers. */
|
||||
|
||||
/* flex integer type definitions */
|
||||
|
||||
#ifndef FLEXINT_H
|
||||
#define FLEXINT_H
|
||||
|
||||
/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
|
||||
|
||||
#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
|
||||
|
||||
/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
|
||||
* if you want the limit (max/min) macros for int types.
|
||||
*/
|
||||
#ifndef __STDC_LIMIT_MACROS
|
||||
#define __STDC_LIMIT_MACROS 1
|
||||
#endif
|
||||
|
||||
#include <inttypes.h>
|
||||
typedef int8_t flex_int8_t;
|
||||
typedef uint8_t flex_uint8_t;
|
||||
typedef int16_t flex_int16_t;
|
||||
typedef uint16_t flex_uint16_t;
|
||||
typedef int32_t flex_int32_t;
|
||||
typedef uint32_t flex_uint32_t;
|
||||
#else
|
||||
typedef signed char flex_int8_t;
|
||||
typedef short int flex_int16_t;
|
||||
typedef int flex_int32_t;
|
||||
typedef unsigned char flex_uint8_t;
|
||||
typedef unsigned short int flex_uint16_t;
|
||||
typedef unsigned int flex_uint32_t;
|
||||
|
||||
/* Limits of integral types. */
|
||||
#ifndef INT8_MIN
|
||||
#define INT8_MIN (-128)
|
||||
#endif
|
||||
#ifndef INT16_MIN
|
||||
#define INT16_MIN (-32767-1)
|
||||
#endif
|
||||
#ifndef INT32_MIN
|
||||
#define INT32_MIN (-2147483647-1)
|
||||
#endif
|
||||
#ifndef INT8_MAX
|
||||
#define INT8_MAX (127)
|
||||
#endif
|
||||
#ifndef INT16_MAX
|
||||
#define INT16_MAX (32767)
|
||||
#endif
|
||||
#ifndef INT32_MAX
|
||||
#define INT32_MAX (2147483647)
|
||||
#endif
|
||||
#ifndef UINT8_MAX
|
||||
#define UINT8_MAX (255U)
|
||||
#endif
|
||||
#ifndef UINT16_MAX
|
||||
#define UINT16_MAX (65535U)
|
||||
#endif
|
||||
#ifndef UINT32_MAX
|
||||
#define UINT32_MAX (4294967295U)
|
||||
#endif
|
||||
|
||||
#ifndef SIZE_MAX
|
||||
#define SIZE_MAX (~(size_t)0)
|
||||
#endif
|
||||
|
||||
#endif /* ! C99 */
|
||||
|
||||
#endif /* ! FLEXINT_H */
|
||||
|
||||
/* begin standard C++ headers. */
|
||||
|
||||
/* TODO: this is always defined, so inline it */
|
||||
#define yyconst const
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ >= 3
|
||||
#define yynoreturn __attribute__((__noreturn__))
|
||||
#else
|
||||
#define yynoreturn
|
||||
#endif
|
||||
|
||||
/* Size of default input buffer. */
|
||||
#ifndef YY_BUF_SIZE
|
||||
#ifdef __ia64__
|
||||
/* On IA-64, the buffer size is 16k, not 8k.
|
||||
* Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
|
||||
* Ditto for the __ia64__ case accordingly.
|
||||
*/
|
||||
#define YY_BUF_SIZE 32768
|
||||
#else
|
||||
#define YY_BUF_SIZE 16384
|
||||
#endif /* __ia64__ */
|
||||
#endif
|
||||
|
||||
#ifndef YY_TYPEDEF_YY_BUFFER_STATE
|
||||
#define YY_TYPEDEF_YY_BUFFER_STATE
|
||||
typedef struct yy_buffer_state *YY_BUFFER_STATE;
|
||||
#endif
|
||||
|
||||
#ifndef YY_TYPEDEF_YY_SIZE_T
|
||||
#define YY_TYPEDEF_YY_SIZE_T
|
||||
typedef size_t yy_size_t;
|
||||
#endif
|
||||
|
||||
extern int yyleng;
|
||||
|
||||
extern FILE *yyin, *yyout;
|
||||
|
||||
#ifndef YY_STRUCT_YY_BUFFER_STATE
|
||||
#define YY_STRUCT_YY_BUFFER_STATE
|
||||
struct yy_buffer_state
|
||||
{
|
||||
FILE *yy_input_file;
|
||||
|
||||
char *yy_ch_buf; /* input buffer */
|
||||
char *yy_buf_pos; /* current position in input buffer */
|
||||
|
||||
/* Size of input buffer in bytes, not including room for EOB
|
||||
* characters.
|
||||
*/
|
||||
int yy_buf_size;
|
||||
|
||||
/* Number of characters read into yy_ch_buf, not including EOB
|
||||
* characters.
|
||||
*/
|
||||
int yy_n_chars;
|
||||
|
||||
/* Whether we "own" the buffer - i.e., we know we created it,
|
||||
* and can realloc() it to grow it, and should free() it to
|
||||
* delete it.
|
||||
*/
|
||||
int yy_is_our_buffer;
|
||||
|
||||
/* Whether this is an "interactive" input source; if so, and
|
||||
* if we're using stdio for input, then we want to use getc()
|
||||
* instead of fread(), to make sure we stop fetching input after
|
||||
* each newline.
|
||||
*/
|
||||
int yy_is_interactive;
|
||||
|
||||
/* Whether we're considered to be at the beginning of a line.
|
||||
* If so, '^' rules will be active on the next match, otherwise
|
||||
* not.
|
||||
*/
|
||||
int yy_at_bol;
|
||||
|
||||
int yy_bs_lineno; /**< The line count. */
|
||||
int yy_bs_column; /**< The column count. */
|
||||
|
||||
/* Whether to try to fill the input buffer when we reach the
|
||||
* end of it.
|
||||
*/
|
||||
int yy_fill_buffer;
|
||||
|
||||
int yy_buffer_status;
|
||||
|
||||
};
|
||||
#endif /* !YY_STRUCT_YY_BUFFER_STATE */
|
||||
|
||||
void yyrestart ( FILE *input_file );
|
||||
void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer );
|
||||
YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size );
|
||||
void yy_delete_buffer ( YY_BUFFER_STATE b );
|
||||
void yy_flush_buffer ( YY_BUFFER_STATE b );
|
||||
void yypush_buffer_state ( YY_BUFFER_STATE new_buffer );
|
||||
void yypop_buffer_state ( void );
|
||||
|
||||
YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size );
|
||||
YY_BUFFER_STATE yy_scan_string ( const char *yy_str );
|
||||
YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len );
|
||||
|
||||
void *yyalloc ( yy_size_t );
|
||||
void *yyrealloc ( void *, yy_size_t );
|
||||
void yyfree ( void * );
|
||||
|
||||
/* Begin user sect3 */
|
||||
|
||||
#define yywrap() (/*CONSTCOND*/1)
|
||||
#define YY_SKIP_YYWRAP
|
||||
|
||||
extern int yylineno;
|
||||
|
||||
extern char *yytext;
|
||||
#ifdef yytext_ptr
|
||||
#undef yytext_ptr
|
||||
#endif
|
||||
#define yytext_ptr yytext
|
||||
|
||||
#ifdef YY_HEADER_EXPORT_START_CONDITIONS
|
||||
#define INITIAL 0
|
||||
#define incl 1
|
||||
#define inclr 2
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef YY_NO_UNISTD_H
|
||||
/* Special case for "unistd.h", since it is non-ANSI. We include it way
|
||||
* down here because we want the user's section 1 to have been scanned first.
|
||||
* The user has a chance to override it with an option.
|
||||
*/
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifndef YY_EXTRA_TYPE
|
||||
#define YY_EXTRA_TYPE void *
|
||||
#endif
|
||||
|
||||
/* Accessor methods to globals.
|
||||
These are made visible to non-reentrant scanners for convenience. */
|
||||
|
||||
int yylex_destroy ( void );
|
||||
|
||||
int yyget_debug ( void );
|
||||
|
||||
void yyset_debug ( int debug_flag );
|
||||
|
||||
YY_EXTRA_TYPE yyget_extra ( void );
|
||||
|
||||
void yyset_extra ( YY_EXTRA_TYPE user_defined );
|
||||
|
||||
FILE *yyget_in ( void );
|
||||
|
||||
void yyset_in ( FILE * _in_str );
|
||||
|
||||
FILE *yyget_out ( void );
|
||||
|
||||
void yyset_out ( FILE * _out_str );
|
||||
|
||||
int yyget_leng ( void );
|
||||
|
||||
char *yyget_text ( void );
|
||||
|
||||
int yyget_lineno ( void );
|
||||
|
||||
void yyset_lineno ( int _line_number );
|
||||
|
||||
/* Macros after this point can all be overridden by user definitions in
|
||||
* section 1.
|
||||
*/
|
||||
|
||||
#ifndef YY_SKIP_YYWRAP
|
||||
#ifdef __cplusplus
|
||||
extern "C" int yywrap ( void );
|
||||
#else
|
||||
extern int yywrap ( void );
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef yytext_ptr
|
||||
static void yy_flex_strncpy ( char *, const char *, int );
|
||||
#endif
|
||||
|
||||
#ifdef YY_NEED_STRLEN
|
||||
static int yy_flex_strlen ( const char * );
|
||||
#endif
|
||||
|
||||
#ifndef YY_NO_INPUT
|
||||
|
||||
#endif
|
||||
|
||||
/* Amount of stuff to slurp up with each read. */
|
||||
#ifndef YY_READ_BUF_SIZE
|
||||
#ifdef __ia64__
|
||||
/* On IA-64, the buffer size is 16k, not 8k */
|
||||
#define YY_READ_BUF_SIZE 16384
|
||||
#else
|
||||
#define YY_READ_BUF_SIZE 8192
|
||||
#endif /* __ia64__ */
|
||||
#endif
|
||||
|
||||
/* Number of entries by which start-condition stack grows. */
|
||||
#ifndef YY_START_STACK_INCR
|
||||
#define YY_START_STACK_INCR 25
|
||||
#endif
|
||||
|
||||
/* Default declaration of generated scanner - a define so the user can
|
||||
* easily add parameters.
|
||||
*/
|
||||
#ifndef YY_DECL
|
||||
#define YY_DECL_IS_OURS 1
|
||||
|
||||
extern int yylex (void);
|
||||
|
||||
#define YY_DECL int yylex (void)
|
||||
#endif /* !YY_DECL */
|
||||
|
||||
/* yy_get_previous_state - get the state just before the EOB char was reached */
|
||||
|
||||
#undef YY_NEW_FILE
|
||||
#undef YY_FLUSH_BUFFER
|
||||
#undef yy_set_bol
|
||||
#undef yy_new_buffer
|
||||
#undef yy_set_interactive
|
||||
#undef YY_DO_BEFORE_ACTION
|
||||
|
||||
#ifdef YY_DECL_IS_OURS
|
||||
#undef YY_DECL_IS_OURS
|
||||
#undef YY_DECL
|
||||
#endif
|
||||
|
||||
#ifndef yy_create_buffer_ALREADY_DEFINED
|
||||
#undef yy_create_buffer
|
||||
#endif
|
||||
#ifndef yy_delete_buffer_ALREADY_DEFINED
|
||||
#undef yy_delete_buffer
|
||||
#endif
|
||||
#ifndef yy_scan_buffer_ALREADY_DEFINED
|
||||
#undef yy_scan_buffer
|
||||
#endif
|
||||
#ifndef yy_scan_string_ALREADY_DEFINED
|
||||
#undef yy_scan_string
|
||||
#endif
|
||||
#ifndef yy_scan_bytes_ALREADY_DEFINED
|
||||
#undef yy_scan_bytes
|
||||
#endif
|
||||
#ifndef yy_init_buffer_ALREADY_DEFINED
|
||||
#undef yy_init_buffer
|
||||
#endif
|
||||
#ifndef yy_flush_buffer_ALREADY_DEFINED
|
||||
#undef yy_flush_buffer
|
||||
#endif
|
||||
#ifndef yy_load_buffer_state_ALREADY_DEFINED
|
||||
#undef yy_load_buffer_state
|
||||
#endif
|
||||
#ifndef yy_switch_to_buffer_ALREADY_DEFINED
|
||||
#undef yy_switch_to_buffer
|
||||
#endif
|
||||
#ifndef yypush_buffer_state_ALREADY_DEFINED
|
||||
#undef yypush_buffer_state
|
||||
#endif
|
||||
#ifndef yypop_buffer_state_ALREADY_DEFINED
|
||||
#undef yypop_buffer_state
|
||||
#endif
|
||||
#ifndef yyensure_buffer_stack_ALREADY_DEFINED
|
||||
#undef yyensure_buffer_stack
|
||||
#endif
|
||||
#ifndef yylex_ALREADY_DEFINED
|
||||
#undef yylex
|
||||
#endif
|
||||
#ifndef yyrestart_ALREADY_DEFINED
|
||||
#undef yyrestart
|
||||
#endif
|
||||
#ifndef yylex_init_ALREADY_DEFINED
|
||||
#undef yylex_init
|
||||
#endif
|
||||
#ifndef yylex_init_extra_ALREADY_DEFINED
|
||||
#undef yylex_init_extra
|
||||
#endif
|
||||
#ifndef yylex_destroy_ALREADY_DEFINED
|
||||
#undef yylex_destroy
|
||||
#endif
|
||||
#ifndef yyget_debug_ALREADY_DEFINED
|
||||
#undef yyget_debug
|
||||
#endif
|
||||
#ifndef yyset_debug_ALREADY_DEFINED
|
||||
#undef yyset_debug
|
||||
#endif
|
||||
#ifndef yyget_extra_ALREADY_DEFINED
|
||||
#undef yyget_extra
|
||||
#endif
|
||||
#ifndef yyset_extra_ALREADY_DEFINED
|
||||
#undef yyset_extra
|
||||
#endif
|
||||
#ifndef yyget_in_ALREADY_DEFINED
|
||||
#undef yyget_in
|
||||
#endif
|
||||
#ifndef yyset_in_ALREADY_DEFINED
|
||||
#undef yyset_in
|
||||
#endif
|
||||
#ifndef yyget_out_ALREADY_DEFINED
|
||||
#undef yyget_out
|
||||
#endif
|
||||
#ifndef yyset_out_ALREADY_DEFINED
|
||||
#undef yyset_out
|
||||
#endif
|
||||
#ifndef yyget_leng_ALREADY_DEFINED
|
||||
#undef yyget_leng
|
||||
#endif
|
||||
#ifndef yyget_text_ALREADY_DEFINED
|
||||
#undef yyget_text
|
||||
#endif
|
||||
#ifndef yyget_lineno_ALREADY_DEFINED
|
||||
#undef yyget_lineno
|
||||
#endif
|
||||
#ifndef yyset_lineno_ALREADY_DEFINED
|
||||
#undef yyset_lineno
|
||||
#endif
|
||||
#ifndef yyget_column_ALREADY_DEFINED
|
||||
#undef yyget_column
|
||||
#endif
|
||||
#ifndef yyset_column_ALREADY_DEFINED
|
||||
#undef yyset_column
|
||||
#endif
|
||||
#ifndef yywrap_ALREADY_DEFINED
|
||||
#undef yywrap
|
||||
#endif
|
||||
#ifndef yyget_lval_ALREADY_DEFINED
|
||||
#undef yyget_lval
|
||||
#endif
|
||||
#ifndef yyset_lval_ALREADY_DEFINED
|
||||
#undef yyset_lval
|
||||
#endif
|
||||
#ifndef yyget_lloc_ALREADY_DEFINED
|
||||
#undef yyget_lloc
|
||||
#endif
|
||||
#ifndef yyset_lloc_ALREADY_DEFINED
|
||||
#undef yyset_lloc
|
||||
#endif
|
||||
#ifndef yyalloc_ALREADY_DEFINED
|
||||
#undef yyalloc
|
||||
#endif
|
||||
#ifndef yyrealloc_ALREADY_DEFINED
|
||||
#undef yyrealloc
|
||||
#endif
|
||||
#ifndef yyfree_ALREADY_DEFINED
|
||||
#undef yyfree
|
||||
#endif
|
||||
#ifndef yytext_ALREADY_DEFINED
|
||||
#undef yytext
|
||||
#endif
|
||||
#ifndef yyleng_ALREADY_DEFINED
|
||||
#undef yyleng
|
||||
#endif
|
||||
#ifndef yyin_ALREADY_DEFINED
|
||||
#undef yyin
|
||||
#endif
|
||||
#ifndef yyout_ALREADY_DEFINED
|
||||
#undef yyout
|
||||
#endif
|
||||
#ifndef yy_flex_debug_ALREADY_DEFINED
|
||||
#undef yy_flex_debug
|
||||
#endif
|
||||
#ifndef yylineno_ALREADY_DEFINED
|
||||
#undef yylineno
|
||||
#endif
|
||||
#ifndef yytables_fload_ALREADY_DEFINED
|
||||
#undef yytables_fload
|
||||
#endif
|
||||
#ifndef yytables_destroy_ALREADY_DEFINED
|
||||
#undef yytables_destroy
|
||||
#endif
|
||||
#ifndef yyTABLES_NAME_ALREADY_DEFINED
|
||||
#undef yyTABLES_NAME
|
||||
#endif
|
||||
|
||||
#line 74 "scanner.l"
|
||||
|
||||
|
||||
#line 476 "nng/src/supplemental/nanolib/scanner.h"
|
||||
#undef yyIN_HEADER
|
||||
#endif /* yyHEADER_H */
|
@ -0,0 +1,11 @@
|
||||
#ifndef _NNG_SUPPLEMENTAL_NANOLIB_UTILS_H
|
||||
#define _NNG_SUPPLEMENTAL_NANOLIB_UTILS_H
|
||||
|
||||
#include "nng/nng.h"
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
|
||||
NNG_DECL void fatal(const char *msg, ...);
|
||||
NNG_DECL void nng_fatal(const char *msg, int rv);
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user