Tracking de l'application VNode (moteur du jeu, services, broker.. etc
This commit is contained in:
		@@ -0,0 +1 @@
 | 
			
		||||
aux_source_directory(. DIR_LIB_SRCS)
 | 
			
		||||
@@ -0,0 +1,12 @@
 | 
			
		||||
#ifndef NANOMQ_ACL_HANDLER_H
 | 
			
		||||
#define NANOMQ_ACL_HANDLER_H
 | 
			
		||||
 | 
			
		||||
#include "nng/nng.h"
 | 
			
		||||
#include "nng/supplemental/nanolib/conf.h"
 | 
			
		||||
#include "nng/supplemental/nanolib/acl_conf.h"
 | 
			
		||||
 | 
			
		||||
#ifdef ACL_SUPP
 | 
			
		||||
extern bool auth_acl(
 | 
			
		||||
    conf *config, acl_action_type type, conn_param *param, const char *topic);
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
@@ -0,0 +1,10 @@
 | 
			
		||||
#ifndef AWS_BRIDGE_H
 | 
			
		||||
#define AWS_BRIDGE_H
 | 
			
		||||
 | 
			
		||||
#include "nng/supplemental/nanolib/conf.h"
 | 
			
		||||
#include "broker.h"
 | 
			
		||||
 | 
			
		||||
extern int  aws_bridge_client(conf_bridge_node *node);
 | 
			
		||||
extern void aws_bridge_forward(nano_work *work);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										42
									
								
								VNode/_software_lib/nanomq-0.22.10/include/nanomq/bridge.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								VNode/_software_lib/nanomq-0.22.10/include/nanomq/bridge.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,42 @@
 | 
			
		||||
#ifndef NANOMQ_BRIDGE_H
 | 
			
		||||
#define NANOMQ_BRIDGE_H
 | 
			
		||||
 | 
			
		||||
#include "nng/mqtt/mqtt_client.h"
 | 
			
		||||
#include "nng/nng.h"
 | 
			
		||||
#include "nng/supplemental/nanolib/conf.h"
 | 
			
		||||
#include "nng/supplemental/util/platform.h"
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include "broker.h"
 | 
			
		||||
#include "pub_handler.h"
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
	nng_socket       *sock;
 | 
			
		||||
	conf_bridge_node *config;		// bridge conf file
 | 
			
		||||
	nng_mqtt_client  *client;
 | 
			
		||||
	nng_msg          *connmsg;
 | 
			
		||||
	conf             *conf;			//parent conf file
 | 
			
		||||
	nng_mtx          *switch_mtx;
 | 
			
		||||
	nng_cv           *switch_cv;
 | 
			
		||||
	nng_mtx          *exec_mtx;
 | 
			
		||||
	nng_cv           *exec_cv;
 | 
			
		||||
	nng_duration     cancel_timeout;
 | 
			
		||||
} bridge_param;
 | 
			
		||||
 | 
			
		||||
extern bool topic_filter(const char *origin, const char *input);
 | 
			
		||||
extern int  bridge_client(
 | 
			
		||||
     nng_socket *sock, conf *config, conf_bridge_node *bridge_conf);
 | 
			
		||||
extern int hybrid_bridge_client(
 | 
			
		||||
    nng_socket *sock, conf *config, conf_bridge_node *node);
 | 
			
		||||
extern void bridge_handle_topic_reflection(nano_work *work, conf_bridge *bridge);
 | 
			
		||||
extern nng_msg *bridge_publish_msg(const char *topic, uint8_t *payload,
 | 
			
		||||
    uint32_t len, bool dup, uint8_t qos, bool retain, property *props);
 | 
			
		||||
 | 
			
		||||
extern int  bridge_reload(nng_socket *sock, conf *config, conf_bridge_node *node);
 | 
			
		||||
 | 
			
		||||
extern int bridge_subscribe(nng_socket *sock, conf_bridge_node *node,
 | 
			
		||||
    nng_mqtt_topic_qos *topic_qos, size_t sub_count, property *properties);
 | 
			
		||||
extern int bridge_unsubscribe(nng_socket *sock, conf_bridge_node *node,
 | 
			
		||||
    nng_mqtt_topic *topic, size_t unsub_count, property *properties);
 | 
			
		||||
 | 
			
		||||
#endif // NANOMQ_BRIDGE_H
 | 
			
		||||
							
								
								
									
										106
									
								
								VNode/_software_lib/nanomq-0.22.10/include/nanomq/broker.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								VNode/_software_lib/nanomq-0.22.10/include/nanomq/broker.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,106 @@
 | 
			
		||||
#ifndef NANOMQ_BROKER_H
 | 
			
		||||
#define NANOMQ_BROKER_H
 | 
			
		||||
 | 
			
		||||
#define HTTP_CTX_NUM 4
 | 
			
		||||
 | 
			
		||||
#include "nng/supplemental/nanolib/conf.h"
 | 
			
		||||
#include "nng/supplemental/nanolib/nanolib.h"
 | 
			
		||||
#include "nng/nng.h"
 | 
			
		||||
#include "nng/protocol/mqtt/mqtt.h"
 | 
			
		||||
#include "nng/supplemental/util/platform.h"
 | 
			
		||||
#include "nng/mqtt/packet.h"
 | 
			
		||||
#include "hashmap.h"
 | 
			
		||||
 | 
			
		||||
#define PROTO_MQTT_BROKER 0x00
 | 
			
		||||
#define PROTO_MQTT_BRIDGE 0x01
 | 
			
		||||
#define PROTO_AWS_BRIDGE 0x02
 | 
			
		||||
#define PROTO_HTTP_SERVER 0x03
 | 
			
		||||
#define PROTO_ICEORYX_BRIDGE 0x04
 | 
			
		||||
 | 
			
		||||
#define STATISTICS
 | 
			
		||||
 | 
			
		||||
#if defined(ENABLE_NANOMQ_TESTS)
 | 
			
		||||
	#undef STATISTICS
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
typedef struct work nano_work;
 | 
			
		||||
struct work {
 | 
			
		||||
	enum {
 | 
			
		||||
		INIT,
 | 
			
		||||
		RECV,
 | 
			
		||||
		WAIT,
 | 
			
		||||
		SEND, // Actions after sending msg
 | 
			
		||||
		HOOK, // Rule Engine
 | 
			
		||||
		END,  // Clear state and cache before disconnect
 | 
			
		||||
		CLOSE // sending disconnect packet and err code
 | 
			
		||||
	} state;
 | 
			
		||||
	uint8_t     proto;		  // logic proto
 | 
			
		||||
	uint8_t     proto_ver;   // MQTT version cache
 | 
			
		||||
	uint8_t     flag;        // flag for webhook & rule_engine
 | 
			
		||||
	nng_aio *   aio;
 | 
			
		||||
	nng_msg *   msg;
 | 
			
		||||
	nng_msg **  msg_ret;
 | 
			
		||||
	nng_ctx     ctx;        // ctx for mqtt broker
 | 
			
		||||
	nng_ctx     extra_ctx; //  ctx for bridging/http post
 | 
			
		||||
	nng_pipe    pid;
 | 
			
		||||
	dbtree *    db;
 | 
			
		||||
	dbtree *    db_ret;
 | 
			
		||||
	conf *      config;
 | 
			
		||||
 | 
			
		||||
	conf_bridge_node *node;	// only works for bridge ctx
 | 
			
		||||
	reason_code 	  code; // MQTT reason code
 | 
			
		||||
 | 
			
		||||
	nng_socket hook_sock;
 | 
			
		||||
 | 
			
		||||
	struct pipe_content *     pipe_ct;
 | 
			
		||||
	conn_param *              cparam;
 | 
			
		||||
	struct pub_packet_struct *pub_packet;
 | 
			
		||||
	packet_subscribe *        sub_pkt;
 | 
			
		||||
	packet_unsubscribe *      unsub_pkt;
 | 
			
		||||
 | 
			
		||||
	void *sqlite_db;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if defined(SUPP_PLUGIN)
 | 
			
		||||
	property *user_property;
 | 
			
		||||
#endif
 | 
			
		||||
#if defined(SUPP_ICEORYX)
 | 
			
		||||
	void *iceoryx_suber;
 | 
			
		||||
	void *iceoryx_puber;
 | 
			
		||||
	nng_socket iceoryx_sock;
 | 
			
		||||
#endif
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct client_ctx {
 | 
			
		||||
	nng_pipe pid;
 | 
			
		||||
#ifdef STATISTICS
 | 
			
		||||
	nng_atomic_u64 *recv_cnt;
 | 
			
		||||
#endif
 | 
			
		||||
	conn_param *cparam;
 | 
			
		||||
	uint32_t    prop_len;
 | 
			
		||||
	property   *properties;
 | 
			
		||||
	uint8_t     proto_ver;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static int broker_start_rc;
 | 
			
		||||
 | 
			
		||||
typedef struct client_ctx client_ctx;
 | 
			
		||||
 | 
			
		||||
extern int  broker_start(int argc, char **argv);
 | 
			
		||||
extern int  broker_stop(int argc, char **argv);
 | 
			
		||||
extern int  broker_restart(int argc, char **argv);
 | 
			
		||||
extern int  broker_reload(int argc, char **argv);
 | 
			
		||||
extern int  broker_dflt(int argc, char **argv);
 | 
			
		||||
extern void bridge_send_cb(void *arg);
 | 
			
		||||
extern void *broker_start_with_conf(void *nmq_conf);
 | 
			
		||||
 | 
			
		||||
#ifdef STATISTICS
 | 
			
		||||
extern uint64_t nanomq_get_message_in(void);
 | 
			
		||||
extern uint64_t nanomq_get_message_out(void);
 | 
			
		||||
extern uint64_t nanomq_get_message_drop(void);
 | 
			
		||||
#endif
 | 
			
		||||
extern dbtree *          get_broker_db(void);
 | 
			
		||||
extern struct hashmap_s *get_hashmap(void);
 | 
			
		||||
extern int               rule_engine_insert_sql(nano_work *work);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										20
									
								
								VNode/_software_lib/nanomq-0.22.10/include/nanomq/cmd_proc.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								VNode/_software_lib/nanomq-0.22.10/include/nanomq/cmd_proc.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
			
		||||
#ifndef NANOMQ_CMD_PROC_H
 | 
			
		||||
#define NANOMQ_CMD_PROC_H
 | 
			
		||||
 | 
			
		||||
#define CMD_IPC_URL "ipc:///tmp/nanomq_cmd.ipc"
 | 
			
		||||
#define IPC_URL_PATH "/tmp/nanomq_cmd.ipc"
 | 
			
		||||
// #define CMD_IPC_URL "tcp://127.0.0.1:10000"
 | 
			
		||||
#define CMD_PROC_PARALLEL 1
 | 
			
		||||
 | 
			
		||||
#include "nng/nng.h"
 | 
			
		||||
#include "nng/supplemental/nanolib/conf.h"
 | 
			
		||||
#include "nng/supplemental/nanolib/log.h"
 | 
			
		||||
 | 
			
		||||
typedef struct cmd_work cmd_work;
 | 
			
		||||
 | 
			
		||||
extern void      cmd_server_cb(void *arg);
 | 
			
		||||
extern cmd_work *alloc_cmd_work(nng_socket sock, conf *config);
 | 
			
		||||
extern void      start_cmd_client(const char *cmd, const char *url);
 | 
			
		||||
extern char *    encode_client_cmd(const char *conf_file, int type);
 | 
			
		||||
 | 
			
		||||
#endif // NANOMQ_CMD_PROC_H
 | 
			
		||||
							
								
								
									
										43
									
								
								VNode/_software_lib/nanomq-0.22.10/include/nanomq/conf_api.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								VNode/_software_lib/nanomq-0.22.10/include/nanomq/conf_api.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,43 @@
 | 
			
		||||
#ifndef NANOMQ_CONF_API_H
 | 
			
		||||
#define NANOMQ_CONF_API_H
 | 
			
		||||
 | 
			
		||||
#include "nng/supplemental/nanolib/conf.h"
 | 
			
		||||
#include "nng/supplemental/nanolib/cJSON.h"
 | 
			
		||||
#include "nng/supplemental/nanolib/file.h"
 | 
			
		||||
#include "nng/supplemental/nanolib/utils.h"
 | 
			
		||||
#include "nng/supplemental/nanolib/cvector.h"
 | 
			
		||||
#include "rest_api.h"
 | 
			
		||||
 | 
			
		||||
extern cJSON *get_reload_config(conf *config);
 | 
			
		||||
extern cJSON *get_basic_config(conf *config);
 | 
			
		||||
extern cJSON *get_tls_config(conf_tls *tls, bool is_server);
 | 
			
		||||
extern cJSON *get_auth_config(conf_auth *auth);
 | 
			
		||||
extern cJSON *get_auth_http_config(conf_auth_http *auth_http);
 | 
			
		||||
extern cJSON *get_websocket_config(conf_websocket *ws);
 | 
			
		||||
extern cJSON *get_http_config(conf_http_server *http);
 | 
			
		||||
extern cJSON *get_sqlite_config(conf_sqlite *sqlite);
 | 
			
		||||
extern cJSON *get_bridge_config(conf_bridge *bridge, const char *node_name);
 | 
			
		||||
extern void   set_bridge_node_conf(
 | 
			
		||||
      conf_bridge *config, cJSON *node_obj, const char *name);
 | 
			
		||||
 | 
			
		||||
extern void set_reload_config(cJSON *json, conf *config);
 | 
			
		||||
extern void set_basic_config(cJSON *json, conf *config);
 | 
			
		||||
extern void set_tls_config(
 | 
			
		||||
    cJSON *json, const char *conf_path, conf_tls *tls, const char *key_prefix);
 | 
			
		||||
extern void set_auth_config(
 | 
			
		||||
    cJSON *json, const char *conf_path, conf_auth *auth);
 | 
			
		||||
extern void set_auth_http_config(
 | 
			
		||||
    cJSON *json, const char *conf_path, conf_auth_http *auth);
 | 
			
		||||
extern void set_http_config(
 | 
			
		||||
    cJSON *json, const char *conf_path, conf_http_server *http);
 | 
			
		||||
extern void set_websocket_config(
 | 
			
		||||
    cJSON *json, const char *conf_path, conf_websocket *ws);
 | 
			
		||||
extern void set_sqlite_config(cJSON *json, const char *conf_path,
 | 
			
		||||
    conf_sqlite *sqlite, const char *key_prefix);
 | 
			
		||||
 | 
			
		||||
extern void reload_basic_config(conf *cur_conf, conf *new_conf);
 | 
			
		||||
extern void reload_sqlite_config(conf_sqlite *cur_conf, conf_sqlite *new_conf);
 | 
			
		||||
extern void reload_auth_config(conf_auth *cur_conf, conf_auth *new_conf);
 | 
			
		||||
extern void reload_log_config(conf *cur_conf, conf *new_conf);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -0,0 +1,2 @@
 | 
			
		||||
 | 
			
		||||
extern const char tmp_example[];
 | 
			
		||||
@@ -0,0 +1,79 @@
 | 
			
		||||
/*
 | 
			
		||||
 * AWS IoT Device SDK for Embedded C 202108.00
 | 
			
		||||
 * Copyright (C) 2020 Amazon.com, Inc. or its affiliates.  All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * 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 CORE_MQTT_CONFIG_H_
 | 
			
		||||
#define CORE_MQTT_CONFIG_H_
 | 
			
		||||
 | 
			
		||||
/**************************************************/
 | 
			
		||||
/******* DO NOT CHANGE the following order ********/
 | 
			
		||||
/**************************************************/
 | 
			
		||||
 | 
			
		||||
/* Include logging header files and define logging macros in the following order:
 | 
			
		||||
 * 1. Include the header file "logging_levels.h".
 | 
			
		||||
 * 2. Define the LIBRARY_LOG_NAME and LIBRARY_LOG_LEVEL macros depending on
 | 
			
		||||
 * the logging configuration for MQTT.
 | 
			
		||||
 * 3. Include the header file "logging_stack.h", if logging is enabled for MQTT.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <aws/logging_levels.h>
 | 
			
		||||
 | 
			
		||||
/* Logging configuration for the MQTT library. */
 | 
			
		||||
#ifndef LIBRARY_LOG_NAME
 | 
			
		||||
    #define LIBRARY_LOG_NAME    "MQTT"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef LIBRARY_LOG_LEVEL
 | 
			
		||||
    #define LIBRARY_LOG_LEVEL    LOG_NONE
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <aws/logging_stack.h>
 | 
			
		||||
 | 
			
		||||
/************ End of logging configuration ****************/
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Determines the maximum number of MQTT PUBLISH messages, pending
 | 
			
		||||
 * acknowledgement at a time, that are supported for incoming and outgoing
 | 
			
		||||
 * direction of messages, separately.
 | 
			
		||||
 *
 | 
			
		||||
 * QoS 1 and 2 MQTT PUBLISHes require acknowledgement from the server before
 | 
			
		||||
 * they can be completed. While they are awaiting the acknowledgement, the
 | 
			
		||||
 * client must maintain information about their state. The value of this
 | 
			
		||||
 * macro sets the limit on how many simultaneous PUBLISH states an MQTT
 | 
			
		||||
 * context maintains, separately, for both incoming and outgoing direction of
 | 
			
		||||
 * PUBLISHes.
 | 
			
		||||
 *
 | 
			
		||||
 * @note The MQTT context maintains separate state records for outgoing
 | 
			
		||||
 * and incoming PUBLISHes, and thus, 2 * MQTT_STATE_ARRAY_MAX_COUNT amount
 | 
			
		||||
 * of memory is statically allocated for the state records.
 | 
			
		||||
 */
 | 
			
		||||
#define MQTT_STATE_ARRAY_MAX_COUNT    ( 10U )
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Number of milliseconds to wait for a ping response to a ping
 | 
			
		||||
 * request as part of the keep-alive mechanism.
 | 
			
		||||
 *
 | 
			
		||||
 * If a ping response is not received before this timeout, then
 | 
			
		||||
 * #MQTT_ProcessLoop will return #MQTTKeepAliveTimeout.
 | 
			
		||||
 */
 | 
			
		||||
#define MQTT_PINGRESP_TIMEOUT_MS      ( 5000U )
 | 
			
		||||
 | 
			
		||||
#endif /* ifndef CORE_MQTT_CONFIG_H_ */
 | 
			
		||||
							
								
								
									
										12
									
								
								VNode/_software_lib/nanomq-0.22.10/include/nanomq/db_cli.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								VNode/_software_lib/nanomq-0.22.10/include/nanomq/db_cli.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
#ifndef DB_CLI_H
 | 
			
		||||
#define DB_CLI_H
 | 
			
		||||
 | 
			
		||||
#include "fdb_version.h"
 | 
			
		||||
#include <pthread.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
#include <foundationdb/fdb_c.h>
 | 
			
		||||
#include <foundationdb/fdb_c_options.g.h>
 | 
			
		||||
 | 
			
		||||
FDBDatabase* openDatabase(pthread_t* netThread);
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										113
									
								
								VNode/_software_lib/nanomq-0.22.10/include/nanomq/hashmap.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										113
									
								
								VNode/_software_lib/nanomq-0.22.10/include/nanomq/hashmap.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,113 @@
 | 
			
		||||
#ifndef SHEREDOM_HASHMAP_H_INCLUDED
 | 
			
		||||
#define SHEREDOM_HASHMAP_H_INCLUDED
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER)
 | 
			
		||||
// Workaround a bug in the MSVC runtime where it uses __cplusplus when not
 | 
			
		||||
// defined.
 | 
			
		||||
#pragma warning(push, 0)
 | 
			
		||||
#pragma warning(disable : 4668)
 | 
			
		||||
#endif
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include "nng/nng.h"
 | 
			
		||||
#include "nng/supplemental/util/platform.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if (defined(_MSC_VER) && defined(__AVX__)) ||                                 \
 | 
			
		||||
    (!defined(_MSC_VER) && defined(__SSE4_2__))
 | 
			
		||||
#define HASHMAP_SSE42
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(HASHMAP_SSE42)
 | 
			
		||||
#include <nmmintrin.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER)
 | 
			
		||||
#pragma warning(pop)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER)
 | 
			
		||||
#pragma warning(push)
 | 
			
		||||
/* Stop MSVC complaining about unreferenced functions */
 | 
			
		||||
#pragma warning(disable : 4505)
 | 
			
		||||
/* Stop MSVC complaining about not inlining functions */
 | 
			
		||||
#pragma warning(disable : 4710)
 | 
			
		||||
/* Stop MSVC complaining about inlining functions! */
 | 
			
		||||
#pragma warning(disable : 4711)
 | 
			
		||||
#elif defined(__clang__)
 | 
			
		||||
#pragma clang diagnostic push
 | 
			
		||||
#pragma clang diagnostic ignored "-Wunused-function"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER)
 | 
			
		||||
#define HASHMAP_USED
 | 
			
		||||
#elif defined(__GNUC__)
 | 
			
		||||
#define HASHMAP_USED __attribute__((used))
 | 
			
		||||
#else
 | 
			
		||||
#define HASHMAP_USED
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
typedef struct hashmap_s hashmap_s;
 | 
			
		||||
/* We need to keep keys and values. */
 | 
			
		||||
struct hashmap_element_s {
 | 
			
		||||
  const char *key;
 | 
			
		||||
  unsigned key_len;
 | 
			
		||||
  int in_use;
 | 
			
		||||
  uint32_t data;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* A hashmap has some maximum size and current size, as well as the data to
 | 
			
		||||
 * hold. */
 | 
			
		||||
struct hashmap_s {
 | 
			
		||||
  unsigned table_size;
 | 
			
		||||
  unsigned size;
 | 
			
		||||
  struct hashmap_element_s *data;
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define HASHMAP_MAX_CHAIN_LENGTH (8)
 | 
			
		||||
 | 
			
		||||
#if defined(__cplusplus)
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
int nano_hashmap_create(const unsigned initial_size,
 | 
			
		||||
                   struct hashmap_s * out_hashmap) HASHMAP_USED;
 | 
			
		||||
 | 
			
		||||
int nano_hashmap_put(struct hashmap_s * hashmap, const char *const key,
 | 
			
		||||
                const unsigned len, uint32_t value) HASHMAP_USED;
 | 
			
		||||
 | 
			
		||||
uint32_t nano_hashmap_get(const struct hashmap_s *const hashmap,
 | 
			
		||||
                  const char *const key,
 | 
			
		||||
                  const unsigned len) HASHMAP_USED;
 | 
			
		||||
 | 
			
		||||
int nano_hashmap_remove(struct hashmap_s * m, const char *const key,
 | 
			
		||||
            const unsigned len);
 | 
			
		||||
 | 
			
		||||
void nano_hashmap_destroy(struct hashmap_s * m);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if defined(__cplusplus)
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(__cplusplus)
 | 
			
		||||
#define HASHMAP_CAST(type, x) static_cast<type>(x)
 | 
			
		||||
#define HASHMAP_PTR_CAST(type, x) reinterpret_cast<type>(x)
 | 
			
		||||
#define HASHMAP_NULL NULL
 | 
			
		||||
#else
 | 
			
		||||
#define HASHMAP_CAST(type, x) ((type)x)
 | 
			
		||||
#define HASHMAP_PTR_CAST(type, x) ((type)x)
 | 
			
		||||
#define HASHMAP_NULL 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER)
 | 
			
		||||
#pragma warning(pop)
 | 
			
		||||
#elif defined(__clang__)
 | 
			
		||||
#pragma clang diagnostic pop
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										38
									
								
								VNode/_software_lib/nanomq-0.22.10/include/nanomq/mqtt_api.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								VNode/_software_lib/nanomq-0.22.10/include/nanomq/mqtt_api.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,38 @@
 | 
			
		||||
#ifndef MQTT_API_H
 | 
			
		||||
#define MQTT_API_H
 | 
			
		||||
 | 
			
		||||
#include "nng/mqtt/mqtt_client.h"
 | 
			
		||||
#include "nng/protocol/mqtt/mqtt.h"
 | 
			
		||||
#include "nng/supplemental/nanolib/conf.h"
 | 
			
		||||
#include "nng/supplemental/tls/tls.h"
 | 
			
		||||
#include "nng/supplemental/util/options.h"
 | 
			
		||||
#include "nng/supplemental/util/platform.h"
 | 
			
		||||
 | 
			
		||||
#define INPROC_SERVER_URL "inproc://inproc_server"
 | 
			
		||||
 | 
			
		||||
int nano_listen(
 | 
			
		||||
    nng_socket sid, const char *addr, nng_listener *lp, int flags, conf *conf);
 | 
			
		||||
int init_listener_tls(nng_listener l, conf_tls *tls);
 | 
			
		||||
 | 
			
		||||
extern int decode_common_mqtt_msg(nng_msg **dest, nng_msg *src);
 | 
			
		||||
extern int encode_common_mqtt_msg(
 | 
			
		||||
    nng_msg **dest, nng_msg *src, const char *clientid, uint8_t proto_ver);
 | 
			
		||||
 | 
			
		||||
extern int log_init(conf_log *log);
 | 
			
		||||
extern int log_fini(conf_log *log);
 | 
			
		||||
 | 
			
		||||
extern char *nano_pipe_get_local_address(nng_pipe p);
 | 
			
		||||
extern uint8_t *nano_pipe_get_local_address6(nng_pipe p);
 | 
			
		||||
extern uint16_t nano_pipe_get_local_port(nng_pipe p);
 | 
			
		||||
extern uint16_t nano_pipe_get_local_port6(nng_pipe p);
 | 
			
		||||
 | 
			
		||||
#if defined(SUPP_ICEORYX)
 | 
			
		||||
#include "nng/iceoryx_shm/iceoryx_shm.h"
 | 
			
		||||
extern int nano_iceoryx_send_nng_msg(
 | 
			
		||||
    nng_iceoryx_puber *puber, nng_msg *msg, nng_socket *sock);
 | 
			
		||||
extern int nano_iceoryx_recv_nng_msg(
 | 
			
		||||
    nng_iceoryx_suber *suber, nng_msg *icemsg, nng_msg **msg);
 | 
			
		||||
extern bool nano_iceoryx_topic_filter(char *icetopic, char *topic, uint32_t topicsz);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // MQTT_API_H
 | 
			
		||||
							
								
								
									
										67
									
								
								VNode/_software_lib/nanomq-0.22.10/include/nanomq/nanomq.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								VNode/_software_lib/nanomq-0.22.10/include/nanomq/nanomq.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,67 @@
 | 
			
		||||
#ifndef NANOMQ_NANOMQ_H
 | 
			
		||||
#define NANOMQ_NANOMQ_H
 | 
			
		||||
 | 
			
		||||
#include "nng/supplemental/nanolib/log.h"
 | 
			
		||||
 | 
			
		||||
#ifndef _GNU_SOURCE
 | 
			
		||||
#define _GNU_SOURCE
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define NNI_PUT16(ptr, u)                                    \
 | 
			
		||||
	do {                                                 \
 | 
			
		||||
		(ptr)[0] = (uint8_t)(((uint16_t)(u)) >> 8u); \
 | 
			
		||||
		(ptr)[1] = (uint8_t)((uint16_t)(u));         \
 | 
			
		||||
	} while (0)
 | 
			
		||||
 | 
			
		||||
#define NNI_PUT32(ptr, u)                                     \
 | 
			
		||||
	do {                                                  \
 | 
			
		||||
		(ptr)[0] = (uint8_t)(((uint32_t)(u)) >> 24u); \
 | 
			
		||||
		(ptr)[1] = (uint8_t)(((uint32_t)(u)) >> 16u); \
 | 
			
		||||
		(ptr)[2] = (uint8_t)(((uint32_t)(u)) >> 8u);  \
 | 
			
		||||
		(ptr)[3] = (uint8_t)((uint32_t)(u));          \
 | 
			
		||||
	} while (0)
 | 
			
		||||
 | 
			
		||||
#define NNI_PUT64(ptr, u)                                     \
 | 
			
		||||
	do {                                                  \
 | 
			
		||||
		(ptr)[0] = (uint8_t)(((uint64_t)(u)) >> 56u); \
 | 
			
		||||
		(ptr)[1] = (uint8_t)(((uint64_t)(u)) >> 48u); \
 | 
			
		||||
		(ptr)[2] = (uint8_t)(((uint64_t)(u)) >> 40u); \
 | 
			
		||||
		(ptr)[3] = (uint8_t)(((uint64_t)(u)) >> 32u); \
 | 
			
		||||
		(ptr)[4] = (uint8_t)(((uint64_t)(u)) >> 24u); \
 | 
			
		||||
		(ptr)[5] = (uint8_t)(((uint64_t)(u)) >> 16u); \
 | 
			
		||||
		(ptr)[6] = (uint8_t)(((uint64_t)(u)) >> 8u);  \
 | 
			
		||||
		(ptr)[7] = (uint8_t)((uint64_t)(u));          \
 | 
			
		||||
	} while (0)
 | 
			
		||||
 | 
			
		||||
#define NNI_GET16(ptr, v)                             \
 | 
			
		||||
	v = (((uint16_t)((uint8_t)(ptr)[0])) << 8u) + \
 | 
			
		||||
	    (((uint16_t)(uint8_t)(ptr)[1]))
 | 
			
		||||
 | 
			
		||||
#define NNI_GET32(ptr, v)                              \
 | 
			
		||||
	v = (((uint32_t)((uint8_t)(ptr)[0])) << 24u) + \
 | 
			
		||||
	    (((uint32_t)((uint8_t)(ptr)[1])) << 16u) + \
 | 
			
		||||
	    (((uint32_t)((uint8_t)(ptr)[2])) << 8u) +  \
 | 
			
		||||
	    (((uint32_t)(uint8_t)(ptr)[3]))
 | 
			
		||||
 | 
			
		||||
#define NNI_GET64(ptr, v)                              \
 | 
			
		||||
	v = (((uint64_t)((uint8_t)(ptr)[0])) << 56u) + \
 | 
			
		||||
	    (((uint64_t)((uint8_t)(ptr)[1])) << 48u) + \
 | 
			
		||||
	    (((uint64_t)((uint8_t)(ptr)[2])) << 40u) + \
 | 
			
		||||
	    (((uint64_t)((uint8_t)(ptr)[3])) << 32u) + \
 | 
			
		||||
	    (((uint64_t)((uint8_t)(ptr)[4])) << 24u) + \
 | 
			
		||||
	    (((uint64_t)((uint8_t)(ptr)[5])) << 16u) + \
 | 
			
		||||
	    (((uint64_t)((uint8_t)(ptr)[6])) << 8u) +  \
 | 
			
		||||
	    (((uint64_t)(uint8_t)(ptr)[7]))
 | 
			
		||||
 | 
			
		||||
#define NANO_UNUSED(x) (x) __attribute__((unused))
 | 
			
		||||
 | 
			
		||||
#define NANO_NNG_FATAL(s, rv)				\
 | 
			
		||||
	do {									\
 | 
			
		||||
		log_fatal(s);						\
 | 
			
		||||
		nng_fatal((s), (rv));				\
 | 
			
		||||
	} while(0)
 | 
			
		||||
 | 
			
		||||
extern int    get_cache_argc();
 | 
			
		||||
extern char **get_cache_argv();
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -0,0 +1,19 @@
 | 
			
		||||
#ifndef NANOMQ_RULE_H
 | 
			
		||||
#define NANOMQ_RULE_H
 | 
			
		||||
 | 
			
		||||
#include "nng/mqtt/mqtt_client.h"
 | 
			
		||||
#include "nng/supplemental/sqlite/sqlite3.h"
 | 
			
		||||
#include "nng/supplemental/nanolib/conf.h"
 | 
			
		||||
#include "nng/nng.h"
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
#if defined(SUPP_RULE_ENGINE)
 | 
			
		||||
extern int nano_client(nng_socket *sock, repub_t *repub);
 | 
			
		||||
extern int nano_client_publish(nng_socket *sock, const char *topic,
 | 
			
		||||
    uint8_t *payload, uint32_t len, uint8_t qos, property *props);
 | 
			
		||||
extern int nanomq_client_sqlite(conf_rule *cr, bool init_last);
 | 
			
		||||
extern int nanomq_client_mysql(conf_rule *cr, bool init_last);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // NANOMQ_RULE_H
 | 
			
		||||
							
								
								
									
										36
									
								
								VNode/_software_lib/nanomq-0.22.10/include/nanomq/plugin.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								VNode/_software_lib/nanomq-0.22.10/include/nanomq/plugin.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,36 @@
 | 
			
		||||
//
 | 
			
		||||
// Copyright 2024 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 NANOMQ_PLUGIN_H
 | 
			
		||||
#define NANOMQ_PLUGIN_H
 | 
			
		||||
 | 
			
		||||
#include "nng/nng.h"
 | 
			
		||||
#include "nng/supplemental/nanolib/conf.h"
 | 
			
		||||
#include "nng/supplemental/nanolib/log.h"
 | 
			
		||||
 | 
			
		||||
struct nano_plugin {
 | 
			
		||||
	char *path;
 | 
			
		||||
	int (*init)(void);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum hook_point {
 | 
			
		||||
	HOOK_USER_PROPERTY,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct plugin_hook {
 | 
			
		||||
	unsigned int point;
 | 
			
		||||
	int (*cb)(void *data);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern int plugin_hook_register(unsigned int point, int (*cb)(void *data));
 | 
			
		||||
extern int plugin_hook_call(unsigned int point, void *data);
 | 
			
		||||
extern int plugin_register(char *path);
 | 
			
		||||
extern void plugins_clear();
 | 
			
		||||
extern int plugin_init(struct nano_plugin *plugin);
 | 
			
		||||
 | 
			
		||||
#endif // NANOMQ_PLUGIN_H
 | 
			
		||||
							
								
								
									
										14
									
								
								VNode/_software_lib/nanomq-0.22.10/include/nanomq/process.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								VNode/_software_lib/nanomq-0.22.10/include/nanomq/process.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,14 @@
 | 
			
		||||
#ifndef PROCESS_H
 | 
			
		||||
#define PROCESS_H
 | 
			
		||||
 | 
			
		||||
#ifndef _GNU_SOURCE
 | 
			
		||||
#define _GNU_SOURCE
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
extern int process_is_alive(int pid);
 | 
			
		||||
extern int process_send_signal(int pid, int signal);
 | 
			
		||||
extern int pidgrp_send_signal(int pid, int signal);
 | 
			
		||||
extern int process_daemonize(void);
 | 
			
		||||
extern int process_create_child(int (*child_run)(void *), void *data);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -0,0 +1,71 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Created by Alvin on 2020/7/25.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef NANOMQ_PUB_HANDLER_H
 | 
			
		||||
#define NANOMQ_PUB_HANDLER_H
 | 
			
		||||
 | 
			
		||||
#include "broker.h"
 | 
			
		||||
#include <nng/mqtt/packet.h>
 | 
			
		||||
#include <nng/nng.h>
 | 
			
		||||
#include <nng/protocol/mqtt/mqtt.h>
 | 
			
		||||
 | 
			
		||||
typedef uint32_t variable_integer;
 | 
			
		||||
 | 
			
		||||
// MQTT Fixed header
 | 
			
		||||
struct fixed_header {
 | 
			
		||||
	// flag_bits
 | 
			
		||||
	uint8_t retain : 1;
 | 
			
		||||
	uint8_t qos : 2;
 | 
			
		||||
	uint8_t dup : 1;
 | 
			
		||||
	// packet_types
 | 
			
		||||
	uint8_t packet_type : 4;
 | 
			
		||||
	// remaining length
 | 
			
		||||
	uint32_t remain_len;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// MQTT Variable header
 | 
			
		||||
union variable_header {
 | 
			
		||||
	struct {
 | 
			
		||||
		uint16_t           packet_id;
 | 
			
		||||
		struct mqtt_string topic_name;
 | 
			
		||||
		property           *properties;
 | 
			
		||||
		uint32_t           prop_len;
 | 
			
		||||
	} publish;
 | 
			
		||||
 | 
			
		||||
	struct {
 | 
			
		||||
		uint16_t    packet_id;
 | 
			
		||||
		reason_code reason_code;
 | 
			
		||||
		property    *properties;
 | 
			
		||||
		uint32_t    prop_len;
 | 
			
		||||
	} pub_arrc, puback, pubrec, pubrel, pubcomp;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct mqtt_payload {
 | 
			
		||||
	uint8_t *data;
 | 
			
		||||
	uint32_t len;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct pub_packet_struct {
 | 
			
		||||
	struct fixed_header   fixed_header;
 | 
			
		||||
	union variable_header var_header;
 | 
			
		||||
	struct mqtt_payload   payload;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct pipe_content {
 | 
			
		||||
	mqtt_msg_info *msg_infos;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
bool encode_pub_message(
 | 
			
		||||
    nng_msg *dest_msg, nano_work *work, mqtt_control_packet_types cmd);
 | 
			
		||||
reason_code decode_pub_message(nano_work *work, uint8_t proto);
 | 
			
		||||
void free_pub_packet(struct pub_packet_struct *pub_packet);
 | 
			
		||||
void free_msg_infos(mqtt_msg_info *msg_infos);
 | 
			
		||||
void init_pipe_content(struct pipe_content *pipe_ct);
 | 
			
		||||
void init_pub_packet_property(struct pub_packet_struct *pub_packet);
 | 
			
		||||
bool check_msg_exp(nng_msg *msg, property *prop);
 | 
			
		||||
 | 
			
		||||
reason_code handle_pub(nano_work *work, struct pipe_content *pipe_ct,
 | 
			
		||||
    uint8_t proto, bool is_event);
 | 
			
		||||
 | 
			
		||||
#endif // NNG_PUB_HANDLER_H
 | 
			
		||||
							
								
								
									
										130
									
								
								VNode/_software_lib/nanomq-0.22.10/include/nanomq/rest_api.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										130
									
								
								VNode/_software_lib/nanomq-0.22.10/include/nanomq/rest_api.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,130 @@
 | 
			
		||||
//
 | 
			
		||||
// 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.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#ifndef REST_API_H
 | 
			
		||||
#define REST_API_H
 | 
			
		||||
 | 
			
		||||
#include "web_server.h"
 | 
			
		||||
#include "mqtt_api.h"
 | 
			
		||||
#include <ctype.h>
 | 
			
		||||
#include <nng/nng.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#define REST_URI_ROOT "/api/v4"
 | 
			
		||||
#define REST_HOST "http://0.0.0.0:%u"
 | 
			
		||||
#define REST_URL REST_HOST REST_URI_ROOT
 | 
			
		||||
 | 
			
		||||
#define getNumberValue(obj, item, key, value, rv)           \
 | 
			
		||||
	{                                                   \
 | 
			
		||||
		item = cJSON_GetObjectItem(obj, key);       \
 | 
			
		||||
		if (cJSON_IsNumber(item)) {                 \
 | 
			
		||||
			value = cJSON_GetNumberValue(item); \
 | 
			
		||||
			rv    = (0);                        \
 | 
			
		||||
		} else {                                    \
 | 
			
		||||
			rv = (-1);                          \
 | 
			
		||||
		}                                           \
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#define getBoolValue(obj, item, key, value, rv)       \
 | 
			
		||||
	{                                             \
 | 
			
		||||
		item = cJSON_GetObjectItem(obj, key); \
 | 
			
		||||
		if (cJSON_IsBool(item)) {             \
 | 
			
		||||
			value = cJSON_IsTrue(item);   \
 | 
			
		||||
			rv    = (0);                  \
 | 
			
		||||
		} else {                              \
 | 
			
		||||
			rv = (-1);                    \
 | 
			
		||||
		}                                     \
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#define getStringValue(obj, item, key, value, rv)           \
 | 
			
		||||
	{                                                   \
 | 
			
		||||
		item = cJSON_GetObjectItem(obj, key);       \
 | 
			
		||||
		if (cJSON_IsString(item)) {                 \
 | 
			
		||||
			value = cJSON_GetStringValue(item); \
 | 
			
		||||
			rv    = (0);                        \
 | 
			
		||||
		} else {                                    \
 | 
			
		||||
			rv = (-1);                          \
 | 
			
		||||
		}                                           \
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
enum result_code {
 | 
			
		||||
	SUCCEED                        = 0,
 | 
			
		||||
	RPC_ERROR                      = 101,
 | 
			
		||||
	UNKNOWN_MISTAKE                = 102,
 | 
			
		||||
	WRONG_USERNAME_OR_PASSWORD     = 103,
 | 
			
		||||
	EMPTY_USERNAME_OR_PASSWORD     = 104,
 | 
			
		||||
	USER_DOES_NOT_EXIST            = 105,
 | 
			
		||||
	ADMIN_CANNOT_BE_DELETED        = 106,
 | 
			
		||||
	MISSING_KEY_REQUEST_PARAMES    = 107,
 | 
			
		||||
	REQ_PARAM_ERROR                = 108,
 | 
			
		||||
	REQ_PARAMS_JSON_FORMAT_ILLEGAL = 109,
 | 
			
		||||
	PLUGIN_IS_ENABLED              = 110,
 | 
			
		||||
	PLUGIN_IS_CLOSED               = 111,
 | 
			
		||||
	CLIENT_IS_OFFLINE              = 112,
 | 
			
		||||
	USER_ALREADY_EXISTS            = 113,
 | 
			
		||||
	OLD_PASSWORD_IS_WRONG          = 114,
 | 
			
		||||
	ILLEGAL_SUBJECT                = 115,
 | 
			
		||||
	TOKEN_EXPIRED                  = 116,
 | 
			
		||||
	PARAMS_HOCON_FORMAT_ILLEGAL    = 117,
 | 
			
		||||
	WRITE_CONFIG_FAILED            = 118,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct http_msg {
 | 
			
		||||
	uint16_t status;
 | 
			
		||||
	int      request;
 | 
			
		||||
	size_t   content_type_len;
 | 
			
		||||
	char *   content_type;
 | 
			
		||||
	size_t   method_len;
 | 
			
		||||
	char *   method;
 | 
			
		||||
	size_t   uri_len;
 | 
			
		||||
	char *   uri;
 | 
			
		||||
	size_t   token_len;
 | 
			
		||||
	char *   token;
 | 
			
		||||
	size_t   data_len;
 | 
			
		||||
	char *   data;
 | 
			
		||||
	bool     encrypt_data;
 | 
			
		||||
} http_msg;
 | 
			
		||||
 | 
			
		||||
extern void     put_http_msg(http_msg *msg, const char *content_type,
 | 
			
		||||
        const char *method, const char *uri, const char *token, const char *data,
 | 
			
		||||
        size_t data_sz);
 | 
			
		||||
extern void     destory_http_msg(http_msg *msg);
 | 
			
		||||
extern http_msg process_request(
 | 
			
		||||
    http_msg *msg, conf_http_server *config, nng_socket *sock);
 | 
			
		||||
 | 
			
		||||
#define GET_METHOD "GET"
 | 
			
		||||
#define POST_METHOD "POST"
 | 
			
		||||
#define PUT_METHOD "PUT"
 | 
			
		||||
#define DELETE_METHOD "DELETE"
 | 
			
		||||
 | 
			
		||||
#define REQ_ENDPOINTS 1
 | 
			
		||||
#define REQ_BROKERS 2
 | 
			
		||||
#define REQ_NODES 3
 | 
			
		||||
#define REQ_SUBSCRIPTIONS 4
 | 
			
		||||
#define REQ_CLIENTS 5
 | 
			
		||||
#define REQ_LOGIN 6
 | 
			
		||||
#define REQ_LOGOUT 7
 | 
			
		||||
 | 
			
		||||
#define REQ_CTRL 10
 | 
			
		||||
#define REQ_GET_CONFIG 11
 | 
			
		||||
#define REQ_SET_CONFIG 12
 | 
			
		||||
#define REQ_TREE 13
 | 
			
		||||
 | 
			
		||||
#define cJSON_AddStringOrNullToObject(obj, name, value)            \
 | 
			
		||||
	{                                                          \
 | 
			
		||||
		if (value) {                                       \
 | 
			
		||||
			cJSON_AddStringToObject(obj, name, value); \
 | 
			
		||||
		} else {                                           \
 | 
			
		||||
			cJSON_AddNullToObject(obj, name);          \
 | 
			
		||||
		}                                                  \
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -0,0 +1,51 @@
 | 
			
		||||
#ifndef MQTT_SUBSCRIBE_HANDLE_H
 | 
			
		||||
#define MQTT_SUBSCRIBE_HANDLE_H
 | 
			
		||||
 | 
			
		||||
#include <nng/nng.h>
 | 
			
		||||
#include <nng/mqtt/packet.h>
 | 
			
		||||
 | 
			
		||||
#include "broker.h"
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
	uint32_t pid;
 | 
			
		||||
	dbtree *db;
 | 
			
		||||
}  sub_destroy_info;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Use to decode sub msg.
 | 
			
		||||
 */
 | 
			
		||||
int decode_sub_msg(nano_work *);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Use to encode an ack for sub msg
 | 
			
		||||
 */
 | 
			
		||||
int encode_suback_msg(nng_msg *, nano_work *);
 | 
			
		||||
 | 
			
		||||
int sub_ctx_handle(nano_work *);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Delete a client ctx from topic node in dbtree
 | 
			
		||||
 */
 | 
			
		||||
int sub_ctx_del(void *db, char *topic, uint32_t pid);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Free the client ctx
 | 
			
		||||
 */
 | 
			
		||||
void sub_ctx_free(client_ctx *);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * A wrap for sub ctx free
 | 
			
		||||
 */
 | 
			
		||||
void * wrap_sub_ctx_free_cb(void *arg);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Free a packet_subscribe.
 | 
			
		||||
 */
 | 
			
		||||
void sub_pkt_free(packet_subscribe *);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Delete all refs in dbtree about client ctx
 | 
			
		||||
 */
 | 
			
		||||
void destroy_sub_client(uint32_t pid, dbtree * db);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -0,0 +1,14 @@
 | 
			
		||||
#ifndef MQTT_UNSUBSCRIBE_HANDLE_H
 | 
			
		||||
#define MQTT_UNSUBSCRIBE_HANDLE_H
 | 
			
		||||
 | 
			
		||||
#include <nng/nng.h>
 | 
			
		||||
 | 
			
		||||
#include "broker.h"
 | 
			
		||||
#include <nng/mqtt/packet.h>
 | 
			
		||||
 | 
			
		||||
int  decode_unsub_msg(nano_work *);
 | 
			
		||||
int  encode_unsuback_msg(nng_msg *, nano_work *);
 | 
			
		||||
int  unsub_ctx_handle(nano_work *);
 | 
			
		||||
void unsub_pkt_free(packet_unsubscribe *);
 | 
			
		||||
 | 
			
		||||
#endif // MQTT_UNSUBSCRIBE_HANDLE_H
 | 
			
		||||
@@ -0,0 +1,5 @@
 | 
			
		||||
#define NANO_VER_MAJOR 0
 | 
			
		||||
#define NANO_VER_MINOR 22
 | 
			
		||||
#define NANO_VER_PATCH 10
 | 
			
		||||
#define NANO_VER_ID_SHORT "15"
 | 
			
		||||
 | 
			
		||||
@@ -0,0 +1,35 @@
 | 
			
		||||
//
 | 
			
		||||
// 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.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#ifndef WEB_SERVER_H
 | 
			
		||||
#define WEB_SERVER_H
 | 
			
		||||
 | 
			
		||||
#include "nng/nng.h"
 | 
			
		||||
#include "nng/supplemental/util/platform.h"
 | 
			
		||||
#include "nng/supplemental/nanolib/conf.h"
 | 
			
		||||
#include <ctype.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#define HTTP_DEFAULT_USER "admin"
 | 
			
		||||
#define HTTP_DEFAULT_PASSWORD "public"
 | 
			
		||||
#define HTTP_DEFAULT_PORT 8081
 | 
			
		||||
 | 
			
		||||
extern int  start_rest_server(conf *conf);
 | 
			
		||||
extern void stop_rest_server(void);
 | 
			
		||||
 | 
			
		||||
extern void              set_http_server_conf(conf_http_server *conf);
 | 
			
		||||
extern conf_http_server *get_http_server_conf(void);
 | 
			
		||||
 | 
			
		||||
extern void     set_global_conf(conf *config);
 | 
			
		||||
extern conf *   get_global_conf(void);
 | 
			
		||||
extern char *   get_jwt_key(void);
 | 
			
		||||
extern nng_time get_boot_time(void);
 | 
			
		||||
#endif
 | 
			
		||||
@@ -0,0 +1,13 @@
 | 
			
		||||
#ifndef WEBHOOK_INPROC_H
 | 
			
		||||
#define WEBHOOK_INPROC_H
 | 
			
		||||
 | 
			
		||||
#include "nng/supplemental/nanolib/conf.h"
 | 
			
		||||
#include "nng/nng.h"
 | 
			
		||||
 | 
			
		||||
#define HOOK_IPC_URL "ipc:///tmp/nanomq_hook.ipc"
 | 
			
		||||
#define EXTERNAL2NANO_IPC "EX2NANO"
 | 
			
		||||
 | 
			
		||||
extern int start_hook_service(conf *conf);
 | 
			
		||||
extern int stop_hook_service(void);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -0,0 +1,20 @@
 | 
			
		||||
#ifndef WEBHOOK_POST_H
 | 
			
		||||
#define WEBHOOK_POST_H
 | 
			
		||||
 | 
			
		||||
#include "webhook_inproc.h"
 | 
			
		||||
#include "broker.h"
 | 
			
		||||
 | 
			
		||||
extern int webhook_msg_publish(nng_socket *sock, conf_web_hook *hook_conf,
 | 
			
		||||
    pub_packet_struct *pub_packet, const char *username,
 | 
			
		||||
    const char *client_id);
 | 
			
		||||
extern int webhook_client_connack(nng_socket *sock, conf_web_hook *hook_conf,
 | 
			
		||||
    uint8_t proto_ver, uint16_t keepalive, uint8_t reason,
 | 
			
		||||
    const char *username, const char *client_id);
 | 
			
		||||
extern int webhook_client_disconnect(nng_socket *sock,
 | 
			
		||||
    conf_web_hook *hook_conf, uint8_t proto_ver, uint16_t keepalive,
 | 
			
		||||
    uint8_t reason, const char *username, const char *client_id);
 | 
			
		||||
extern int hook_entry(nano_work *work, uint8_t reason);
 | 
			
		||||
extern int hook_exchange_init(conf *nanomq_conf, uint64_t num_ctx);
 | 
			
		||||
extern int hook_exchange_sender_init(conf *nanomq_conf, struct work **works, uint64_t num_ctx);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -0,0 +1,33 @@
 | 
			
		||||
//
 | 
			
		||||
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
 | 
			
		||||
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
 | 
			
		||||
//
 | 
			
		||||
// 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 NNG_COMPAT_BUS_H
 | 
			
		||||
#define NNG_COMPAT_BUS_H
 | 
			
		||||
 | 
			
		||||
// This header contains interfaces that are intended to offer compatibility
 | 
			
		||||
// with nanomsg v1.0.  These are not the "preferred" interfaces for nng,
 | 
			
		||||
// and consumers should only use these if they are porting software that
 | 
			
		||||
// previously used nanomsg.  New programs should use the nng native APIs.
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// BUS sockopt level.
 | 
			
		||||
#define NN_PROTO_BUS 7
 | 
			
		||||
#define NN_BUS (NN_PROTO_BUS * 16 + 0)
 | 
			
		||||
 | 
			
		||||
// BUS has no options.
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // NNG_COMPAT_BUS_H
 | 
			
		||||
@@ -0,0 +1,31 @@
 | 
			
		||||
//
 | 
			
		||||
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
 | 
			
		||||
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
 | 
			
		||||
//
 | 
			
		||||
// 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 NNG_COMPAT_INPROC_H
 | 
			
		||||
#define NNG_COMPAT_INPROC_H
 | 
			
		||||
 | 
			
		||||
// This header contains interfaces that are intended to offer compatibility
 | 
			
		||||
// with nanomsg v1.0.  These are not the "preferred" interfaces for nng,
 | 
			
		||||
// and consumers should only use these if they are porting software that
 | 
			
		||||
// previously used nanomsg.  New programs should use the nng native APIs.
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// inproc sockopt level.
 | 
			
		||||
// There are no inproc tunables.
 | 
			
		||||
#define NN_INPROC (-1)
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // NNG_COMPAT_INPROC_H
 | 
			
		||||
@@ -0,0 +1,39 @@
 | 
			
		||||
//
 | 
			
		||||
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
 | 
			
		||||
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
 | 
			
		||||
//
 | 
			
		||||
// 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 NNG_COMPAT_IPC_H
 | 
			
		||||
#define NNG_COMPAT_IPC_H
 | 
			
		||||
 | 
			
		||||
// This header contains interfaces that are intended to offer compatibility
 | 
			
		||||
// with nanomsg v1.0.  These are not the "preferred" interfaces for nng,
 | 
			
		||||
// and consumers should only use these if they are porting software that
 | 
			
		||||
// previously used nanomsg.  New programs should use the nng native APIs.
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// IPC sockopt level.
 | 
			
		||||
#define NN_IPC (-2)
 | 
			
		||||
 | 
			
		||||
// IPC options.  Note that these are not currently supported.
 | 
			
		||||
// IPC_SEC_ATTR works quite differently in NNG, and must be
 | 
			
		||||
// configured using the new API.  The buffer sizing options are
 | 
			
		||||
// not supported at all.  None of these were ever documented, and
 | 
			
		||||
// are offered here only for source compatibility.
 | 
			
		||||
#define NN_IPC_SEC_ATTR 1
 | 
			
		||||
#define NN_IPC_OUTBUFSZ 2
 | 
			
		||||
#define NN_IPC_INBUFSZ 3
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // NNG_COMPAT_IPC_H
 | 
			
		||||
@@ -0,0 +1,284 @@
 | 
			
		||||
//
 | 
			
		||||
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
 | 
			
		||||
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
 | 
			
		||||
//
 | 
			
		||||
// 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 NNG_COMPAT_NN_H
 | 
			
		||||
#define NNG_COMPAT_NN_H
 | 
			
		||||
 | 
			
		||||
// This header contains interfaces that are intended to offer compatibility
 | 
			
		||||
// with nanomsg v1.0.  These are not the "preferred" interfaces for nng,
 | 
			
		||||
// and consumers should only use these if they are porting software that
 | 
			
		||||
// previously used nanomsg.  New programs should use the nng native APIs.
 | 
			
		||||
 | 
			
		||||
// Note that compatibility promises are limited to public portions of the
 | 
			
		||||
// nanomsg API, and specifically do NOT extend to the ABI.  Furthermore,
 | 
			
		||||
// there may be other limitations around less commonly used portions of the
 | 
			
		||||
// API; for example only SP headers may be transported in control data for
 | 
			
		||||
// messages, there is almost no compatibility offered for statistics.
 | 
			
		||||
// Error values may differ from those returned by nanomsg as well; the nng
 | 
			
		||||
// error reporting facility expresses only a subset of the possibilities of
 | 
			
		||||
// nanomsg.
 | 
			
		||||
 | 
			
		||||
// Note that unlike nanomsg, nng does not aggressively recycle socket or
 | 
			
		||||
// endpoint IDs, which means applications which made assumptions that these
 | 
			
		||||
// would be relatively small integers (e.g. to use them as array indices)
 | 
			
		||||
// may break.  (No promise about values was ever made.)
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
// clang-format gets in the way of most of this file.
 | 
			
		||||
// We turn it off, at least until it gets smarter about aligning
 | 
			
		||||
// macro definitions or we adopt enums or somesuch.
 | 
			
		||||
// clang-format off
 | 
			
		||||
 | 
			
		||||
// NNG_DECL is used on declarations to deal with scope.
 | 
			
		||||
// For building Windows DLLs, it should be the appropriate __declspec().
 | 
			
		||||
// For shared libraries with platforms that support hidden visibility,
 | 
			
		||||
// it should evaluate to __attribute__((visibility("default"))).
 | 
			
		||||
#ifndef NN_DECL
 | 
			
		||||
#if defined(_WIN32) && !defined(NNG_STATIC_LIB)
 | 
			
		||||
#if defined(NNG_SHARED_LIB)
 | 
			
		||||
#define NN_DECL		__declspec(dllexport)
 | 
			
		||||
#else
 | 
			
		||||
#define NN_DECL		__declspec(dllimport)
 | 
			
		||||
#endif // NNG_SHARED_LIB
 | 
			
		||||
#else
 | 
			
		||||
#if defined(NNG_SHARED_LIB) && defined(NNG_HIDDEN_VISIBILITY)
 | 
			
		||||
#define NN_DECL __attribute__((visibility("default")))
 | 
			
		||||
#else
 | 
			
		||||
#define NN_DECL extern
 | 
			
		||||
#endif
 | 
			
		||||
#endif // _WIN32 && !NNG_STATIC_LIB
 | 
			
		||||
#endif  // NN_DECL
 | 
			
		||||
 | 
			
		||||
#define AF_SP			1
 | 
			
		||||
#define AF_SP_RAW		2
 | 
			
		||||
 | 
			
		||||
#define NN_SOCKADDR_MAX		128
 | 
			
		||||
#define NN_SOL_SOCKET		0
 | 
			
		||||
 | 
			
		||||
// Flag for send/recv (nonblocking)
 | 
			
		||||
#define NN_DONTWAIT		1
 | 
			
		||||
 | 
			
		||||
// CMSG data type
 | 
			
		||||
#define PROTO_SP		1
 | 
			
		||||
#define SP_HDR			1
 | 
			
		||||
 | 
			
		||||
// Errnos.  Legacy nanomsg uses posix errnos where possible.
 | 
			
		||||
// If a define is not set, use add NN_ERRBASE.  nng does not
 | 
			
		||||
// return all of these values, so there may be some loss of
 | 
			
		||||
// of information for edge cases, but we don't expect that to be
 | 
			
		||||
// a problem really.
 | 
			
		||||
#define NN_ERRBASE		(0x10000000)
 | 
			
		||||
#ifndef ENOTSUP
 | 
			
		||||
#define ENOTSUP			(NN_ERRBASE+1)
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef EPROTONOSUPPORT
 | 
			
		||||
#define EPROTONOSUPPORT		(NN_ERRBASE+2)
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef ENOBUFS
 | 
			
		||||
#define ENOBUFS			(NN_ERRBASE+3)
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef ENETDOWN
 | 
			
		||||
#define ENETDOWN		(NN_ERRBASE+4)
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef EADDRINUSE
 | 
			
		||||
#define EADDRINUSE		(NN_ERRBASE+5)
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef EADDRNOTAVAIL
 | 
			
		||||
#define EADDRNOTAVAIL		(NN_ERRBASE+6)
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef ENOTSOCK
 | 
			
		||||
#define ENOTSOCK		(NN_ERRBASE+7)
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef EAGAIN
 | 
			
		||||
#define EAGAIN			(NN_ERRBASE+8)
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef EBADF
 | 
			
		||||
#define EBADF			(NN_ERRBASE+9)
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef EINVAL
 | 
			
		||||
#define EINVAL			(NN_ERRBASE+10)
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef EMFILE
 | 
			
		||||
#define EMFILE			(NN_ERRBASE+11)
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef EFAULT
 | 
			
		||||
#define EFAULT			(NN_ERRBASE+12)
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef EACCES
 | 
			
		||||
#define EACCES			(NN_ERRBASE+13)
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef ENETRESET
 | 
			
		||||
#define ENETRESET		(NN_ERRBASE+14)
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef ENETUNREACH
 | 
			
		||||
#define ENETUNREACH		(NN_ERRBASE+15)
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef EHOSTUNREACH
 | 
			
		||||
#define EHOSTUNREACH		(NN_ERRBASE+16)
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef EAFNOSUPPORT
 | 
			
		||||
#define EAFNOSUPPORT		(NN_ERRBASE+17)
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef EINPROGRESS
 | 
			
		||||
#define EINPROGRESS		(NN_ERRBASE+18)
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef EPROTO
 | 
			
		||||
#define EPROTO			(NN_ERRBASE+19)
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef ECONNREFUSED
 | 
			
		||||
#define ECONNREFUSED		(NN_ERRBASE+20)
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef ENOTCONN
 | 
			
		||||
#define ENOTCONN		(NN_ERRBASE+21)
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef EMSGSIZE
 | 
			
		||||
#define EMSGSIZE		(NN_ERRBASE+22)
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef ETIMEDOUT
 | 
			
		||||
#define ETIMEDOUT		(NN_ERRBASE+23)
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef ECONNABORTED
 | 
			
		||||
#define ECONNABORTED		(NN_ERRBASE+24)
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef ECONNRESET
 | 
			
		||||
#define ECONNRESET		(NN_ERRBASE+25)
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef ENOPROTOOPT
 | 
			
		||||
#define ENOPROTOOPT		(NN_ERRBASE+26)
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef EISCONN
 | 
			
		||||
#define EISCONN			(NN_ERRBASE+27)
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef ESOCKNOSUPPORT
 | 
			
		||||
#define ESOCKNOSPPORT		(NN_ERRBASE+28)
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef ETERM
 | 
			
		||||
#define ETERM			(NN_ERRBASE+29)
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef EFSM
 | 
			
		||||
#define EFSM			(NN_ERRBASE+30)
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef ENOENT
 | 
			
		||||
#define ENOENT			(NN_ERRBASE+31)
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef EIO
 | 
			
		||||
#define EIO			(NN_ERRBASE+32)
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef EEXIST
 | 
			
		||||
#define EEXIST			(NN_ERRBASE+33)
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef ENOSPC
 | 
			
		||||
#define ENOSPC			(NN_ERRBASE+34)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Socket options
 | 
			
		||||
#define NN_LINGER		1
 | 
			
		||||
#define NN_SNDBUF		2
 | 
			
		||||
#define NN_RCVBUF		3
 | 
			
		||||
#define NN_SNDTIMEO		4
 | 
			
		||||
#define NN_RCVTIMEO		5
 | 
			
		||||
#define NN_RECONNECT_IVL	6
 | 
			
		||||
#define NN_RECONNECT_IVL_MAX	7
 | 
			
		||||
#define NN_SNDPRIO		8
 | 
			
		||||
#define NN_RCVPRIO		9
 | 
			
		||||
#define NN_SNDFD		10
 | 
			
		||||
#define NN_RCVFD		11
 | 
			
		||||
#define NN_DOMAIN		12
 | 
			
		||||
#define NN_PROTOCOL		13
 | 
			
		||||
#define NN_IPV4ONLY		14
 | 
			
		||||
#define NN_SOCKET_NAME		15
 | 
			
		||||
#define NN_RCVMAXSIZE		16
 | 
			
		||||
#define NN_MAXTTL		17
 | 
			
		||||
 | 
			
		||||
// from this point on formatting is fine
 | 
			
		||||
// clang-format on
 | 
			
		||||
 | 
			
		||||
// Poll stuff
 | 
			
		||||
#define NN_POLLIN 1
 | 
			
		||||
#define NN_POLLOUT 2
 | 
			
		||||
struct nn_pollfd {
 | 
			
		||||
	int      fd;
 | 
			
		||||
	uint16_t events;
 | 
			
		||||
	uint16_t revents;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Magical size for allocation
 | 
			
		||||
#define NN_MSG ((size_t) -1)
 | 
			
		||||
 | 
			
		||||
struct nn_iovec {
 | 
			
		||||
	void * iov_base;
 | 
			
		||||
	size_t iov_len;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct nn_msghdr {
 | 
			
		||||
	struct nn_iovec *msg_iov;
 | 
			
		||||
	int              msg_iovlen;
 | 
			
		||||
	void *           msg_control;
 | 
			
		||||
	size_t           msg_controllen;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct nn_cmsghdr {
 | 
			
		||||
	size_t cmsg_len;
 | 
			
		||||
	int    cmsg_level;
 | 
			
		||||
	int    cmsg_type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define NN_CMSG_ALIGN(len) \
 | 
			
		||||
	(((len) + sizeof(size_t) - 1) & (size_t) ~(sizeof(size_t) - 1))
 | 
			
		||||
 | 
			
		||||
// Unlike old nanomsg, we explicitly only support the SP header as attached
 | 
			
		||||
// cmsg data.  It turns out that old nanomsg didn't really store anything
 | 
			
		||||
// useful otherwise anyway.  (One specific exception was that it stored the
 | 
			
		||||
// message type of text or binary for the websocket transport.  We don't think
 | 
			
		||||
// anyone used that in practice though.)
 | 
			
		||||
#define NN_CMSG_FIRSTHDR(mh) nn_cmsg_next((struct nn_msghdr *) (mh), NULL)
 | 
			
		||||
#define NN_CMSG_NXTHDR(mh, ch) \
 | 
			
		||||
	nn_cmsg_next((struct nn_msghdr *) (mh), (struct nn_cmsghdr *) ch)
 | 
			
		||||
#define NN_CMSG_DATA(ch) ((unsigned char *) (((struct nn_cmsghdr *) (ch)) + 1))
 | 
			
		||||
#define NN_CMSG_SPACE(len) \
 | 
			
		||||
	(NN_CMSG_ALIGN(len) + NN_CMSG_ALIGN(sizeof(struct nn_cmsghdr)))
 | 
			
		||||
#define NN_CMSG_LEN(len) (NN_CMSG_ALIGN(sizeof(struct nn_cmsghdr)) + (len))
 | 
			
		||||
 | 
			
		||||
NN_DECL struct nn_cmsghdr *nn_cmsg_next(
 | 
			
		||||
    struct nn_msghdr *, struct nn_cmsghdr *);
 | 
			
		||||
NN_DECL int nn_socket(int, int);
 | 
			
		||||
NN_DECL int nn_setsockopt(int, int, int, const void *, size_t);
 | 
			
		||||
NN_DECL int nn_getsockopt(int, int, int, void *, size_t *);
 | 
			
		||||
NN_DECL int nn_bind(int, const char *);
 | 
			
		||||
NN_DECL int nn_connect(int, const char *);
 | 
			
		||||
NN_DECL int nn_shutdown(int, int);
 | 
			
		||||
NN_DECL int nn_send(int, const void *, size_t, int);
 | 
			
		||||
NN_DECL int nn_recv(int, void *, size_t, int);
 | 
			
		||||
NN_DECL int nn_sendmsg(int, const struct nn_msghdr *, int);
 | 
			
		||||
NN_DECL int nn_recvmsg(int, struct nn_msghdr *, int);
 | 
			
		||||
NN_DECL int nn_close(int);
 | 
			
		||||
NN_DECL int nn_poll(struct nn_pollfd *, int, int);
 | 
			
		||||
NN_DECL int nn_device(int, int);
 | 
			
		||||
NN_DECL uint64_t    nn_get_statistic(int, int);
 | 
			
		||||
NN_DECL void *      nn_allocmsg(size_t, int);
 | 
			
		||||
NN_DECL void *      nn_reallocmsg(void *, size_t);
 | 
			
		||||
NN_DECL int         nn_freemsg(void *);
 | 
			
		||||
NN_DECL int         nn_errno(void);
 | 
			
		||||
NN_DECL const char *nn_strerror(int);
 | 
			
		||||
NN_DECL void        nn_term(void);
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // NNG_COMPAT_NN_H
 | 
			
		||||
@@ -0,0 +1,39 @@
 | 
			
		||||
//
 | 
			
		||||
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
 | 
			
		||||
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
 | 
			
		||||
//
 | 
			
		||||
// 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 NNG_COMPAT_PAIR_H
 | 
			
		||||
#define NNG_COMPAT_PAIR_H
 | 
			
		||||
 | 
			
		||||
// This header contains interfaces that are intended to offer compatibility
 | 
			
		||||
// with nanomsg v1.0.  These are not the "preferred" interfaces for nng,
 | 
			
		||||
// and consumers should only use these if they are porting software that
 | 
			
		||||
// previously used nanomsg.  New programs should use the nng native APIs.
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// PAIR sockopt level.
 | 
			
		||||
#define NN_PROTO_PAIR 1
 | 
			
		||||
#define NN_PAIR (NN_PROTO_PAIR * 16 + 0)
 | 
			
		||||
 | 
			
		||||
// These are technically "new", and not available in nanomsg, but
 | 
			
		||||
// offered here as a transition aid.  If you want to use the advanced
 | 
			
		||||
// PAIRv1 options (POLYAMOROUS mode) you still need to use the new API.
 | 
			
		||||
#define NN_PAIR_v0 (NN_PROTO_PAIR * 16 + 0)
 | 
			
		||||
#define NN_PAIR_V1 (NN_PROTO_PAIR * 16 + 1)
 | 
			
		||||
 | 
			
		||||
// PAIR has no options.
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // NNG_COMPAT_PAIR_H
 | 
			
		||||
@@ -0,0 +1,34 @@
 | 
			
		||||
//
 | 
			
		||||
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
 | 
			
		||||
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
 | 
			
		||||
//
 | 
			
		||||
// 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 NNG_COMPAT_PIPELINE_H
 | 
			
		||||
#define NNG_COMPAT_PIPELINE_H
 | 
			
		||||
 | 
			
		||||
// This header contains interfaces that are intended to offer compatibility
 | 
			
		||||
// with nanomsg v1.0.  These are not the "preferred" interfaces for nng,
 | 
			
		||||
// and consumers should only use these if they are porting software that
 | 
			
		||||
// previously used nanomsg.  New programs should use the nng native APIs.
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// PUSH and PULL sockopt level.
 | 
			
		||||
#define NN_PROTO_PIPELINE 5
 | 
			
		||||
#define NN_PUSH (NN_PROTO_PIPELINE * 16 + 0)
 | 
			
		||||
#define NN_PULL (NN_PROTO_PIPELINE * 16 + 1)
 | 
			
		||||
 | 
			
		||||
// PUSH and PULL have no options.
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // NNG_COMPAT_PIPELINE_H
 | 
			
		||||
@@ -0,0 +1,36 @@
 | 
			
		||||
//
 | 
			
		||||
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
 | 
			
		||||
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
 | 
			
		||||
//
 | 
			
		||||
// 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 NNG_COMPAT_PUBSUB_H
 | 
			
		||||
#define NNG_COMPAT_PUBSUB_H
 | 
			
		||||
 | 
			
		||||
// This header contains interfaces that are intended to offer compatibility
 | 
			
		||||
// with nanomsg v1.0.  These are not the "preferred" interfaces for nng,
 | 
			
		||||
// and consumers should only use these if they are porting software that
 | 
			
		||||
// previously used nanomsg.  New programs should use the nng native APIs.
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// PUB and SUB sockopt level.
 | 
			
		||||
#define NN_PROTO_PUBSUB 2
 | 
			
		||||
#define NN_PUB (NN_PROTO_PUBSUB * 16 + 0)
 | 
			
		||||
#define NN_SUB (NN_PROTO_PUBSUB * 16 + 1)
 | 
			
		||||
 | 
			
		||||
// SUB options.  (PUB has none.)
 | 
			
		||||
#define NN_SUB_SUBSCRIBE (NN_SUB * 16 + 1)
 | 
			
		||||
#define NN_SUB_UNSUBSCRIBE (NN_SUB * 16 + 2)
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // NNG_COMPAT_PUBSUB_H
 | 
			
		||||
@@ -0,0 +1,35 @@
 | 
			
		||||
//
 | 
			
		||||
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
 | 
			
		||||
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
 | 
			
		||||
//
 | 
			
		||||
// 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 NNG_COMPAT_REQREP_H
 | 
			
		||||
#define NNG_COMPAT_REQREP_H
 | 
			
		||||
 | 
			
		||||
// This header contains interfaces that are intended to offer compatibility
 | 
			
		||||
// with nanomsg v1.0.  These are not the "preferred" interfaces for nng,
 | 
			
		||||
// and consumers should only use these if they are porting software that
 | 
			
		||||
// previously used nanomsg.  New programs should use the nng native APIs.
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// REQ and REP sockopt level.
 | 
			
		||||
#define NN_PROTO_REQREP 3
 | 
			
		||||
#define NN_REQ (NN_PROTO_REQREP * 16 + 0)
 | 
			
		||||
#define NN_REP (NN_PROTO_REQREP * 16 + 1)
 | 
			
		||||
 | 
			
		||||
// REQ options.  (REP has none.)
 | 
			
		||||
#define NN_REQ_RESEND_IVL (NN_REQ * 16 + 1)
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // NNG_COMPAT_REQREP_H
 | 
			
		||||
@@ -0,0 +1,36 @@
 | 
			
		||||
//
 | 
			
		||||
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
 | 
			
		||||
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
 | 
			
		||||
//
 | 
			
		||||
// 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 NNG_COMPAT_SURVEY_H
 | 
			
		||||
#define NNG_COMPAT_SURVEY_H
 | 
			
		||||
 | 
			
		||||
// This header contains interfaces that are intended to offer compatibility
 | 
			
		||||
// with nanomsg v1.0.  These are not the "preferred" interfaces for nng,
 | 
			
		||||
// and consumers should only use these if they are porting software that
 | 
			
		||||
// previously used nanomsg.  New programs should use the nng native APIs.
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// SURVEYOR and RESPONDENT sockopt level.
 | 
			
		||||
#define NN_PROTO_SURVEY 6
 | 
			
		||||
#define NN_SURVEYOR (NN_PROTO_SURVEY * 16 + 2)
 | 
			
		||||
#define NN_RESPONDENT (NN_PROTO_SURVEY * 16 + 3)
 | 
			
		||||
 | 
			
		||||
// SURVEYOR options.  (RESPONDENT has none.)
 | 
			
		||||
 | 
			
		||||
#define NN_SURVEYOR_DEADLINE (NN_SURVEYOR * 16 + 1)
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // NNG_COMPAT_SURVEY_H
 | 
			
		||||
@@ -0,0 +1,33 @@
 | 
			
		||||
//
 | 
			
		||||
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
 | 
			
		||||
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
 | 
			
		||||
//
 | 
			
		||||
// 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 NNG_COMPAT_TCP_H
 | 
			
		||||
#define NNG_COMPAT_TCP_H
 | 
			
		||||
 | 
			
		||||
// This header contains interfaces that are intended to offer compatibility
 | 
			
		||||
// with nanomsg v1.0.  These are not the "preferred" interfaces for nng,
 | 
			
		||||
// and consumers should only use these if they are porting software that
 | 
			
		||||
// previously used nanomsg.  New programs should use the nng native APIs.
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// TCP sockopt level.
 | 
			
		||||
#define NN_TCP (-3)
 | 
			
		||||
 | 
			
		||||
// TCP options.
 | 
			
		||||
#define NN_TCP_NODELAY 1
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // NNG_COMPAT_TCP_H
 | 
			
		||||
@@ -0,0 +1,41 @@
 | 
			
		||||
//
 | 
			
		||||
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
 | 
			
		||||
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
 | 
			
		||||
//
 | 
			
		||||
// 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 NNG_COMPAT_WS_H
 | 
			
		||||
#define NNG_COMPAT_WS_H
 | 
			
		||||
 | 
			
		||||
// This header contains interfaces that are intended to offer compatibility
 | 
			
		||||
// with nanomsg v1.0.  These are not the "preferred" interfaces for nng,
 | 
			
		||||
// and consumers should only use these if they are porting software that
 | 
			
		||||
// previously used nanomsg.  New programs should use the nng native APIs.
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// WS sockopt level.
 | 
			
		||||
#define NN_WS (-4)
 | 
			
		||||
 | 
			
		||||
// WS options.
 | 
			
		||||
 | 
			
		||||
// Note that while legacy libnanomsg had *some* support for text messages,
 | 
			
		||||
// NNG only supports binary.  Binary types are required to pass protocol
 | 
			
		||||
// headers with NNG and nanomsg in any event.  This means that the NNG
 | 
			
		||||
// WebSocket support will not be compatible with some very old browsers.
 | 
			
		||||
#define NN_WS_MSG_TYPE 1
 | 
			
		||||
 | 
			
		||||
#define NN_WS_MSG_TYPE_TEXT 0x1
 | 
			
		||||
#define NN_WS_MSG_TYPE_BINARY 0x2
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // NNG_COMPAT_WS_H
 | 
			
		||||
@@ -0,0 +1,34 @@
 | 
			
		||||
#ifndef EXCHANGE_H
 | 
			
		||||
#define EXCHANGE_H
 | 
			
		||||
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include "core/nng_impl.h"
 | 
			
		||||
#include "nng/supplemental/nanolib/conf.h"
 | 
			
		||||
 | 
			
		||||
// Exchange MQ 
 | 
			
		||||
#define EXCHANGE_NAME_LEN 32
 | 
			
		||||
#define TOPIC_NAME_LEN    128
 | 
			
		||||
#define RINGBUFFER_MAX    64
 | 
			
		||||
 | 
			
		||||
typedef struct exchange_s exchange_t;
 | 
			
		||||
struct exchange_s {
 | 
			
		||||
	char name[EXCHANGE_NAME_LEN];
 | 
			
		||||
	char topic[TOPIC_NAME_LEN];
 | 
			
		||||
 | 
			
		||||
	ringBuffer_t *rbs[RINGBUFFER_MAX];
 | 
			
		||||
	unsigned int rb_count;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
NNG_DECL int exchange_client_get_msg_by_key(void *arg, uint64_t key, nni_msg **msg);
 | 
			
		||||
NNG_DECL int exchange_client_get_msgs_by_key(void *arg, uint64_t key, uint32_t count, nng_msg ***list);
 | 
			
		||||
 | 
			
		||||
NNG_DECL int exchange_client_get_msgs_fuzz(void *arg, uint64_t start, uint64_t end, uint32_t *count, nng_msg ***list);
 | 
			
		||||
 | 
			
		||||
NNG_DECL int exchange_init(exchange_t **ex, char *name, char *topic,
 | 
			
		||||
				  unsigned int *rbsCaps, char **rbsName, uint8_t *rbsFullOp, unsigned int rbsCount);
 | 
			
		||||
NNG_DECL int exchange_add_rb(exchange_t *ex, ringBuffer_t *rb);
 | 
			
		||||
NNG_DECL int exchange_release(exchange_t *ex);
 | 
			
		||||
NNG_DECL int exchange_handle_msg(exchange_t *ex, uint64_t key, void *msg, nng_aio *aio);
 | 
			
		||||
NNG_DECL int exchange_get_ringBuffer(exchange_t *ex, char *rbName, ringBuffer_t **rb);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -0,0 +1,42 @@
 | 
			
		||||
//
 | 
			
		||||
// Copyright 2023 NanoMQ Team, Inc.
 | 
			
		||||
//
 | 
			
		||||
// 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 EXCHANGE_CLIENT_H
 | 
			
		||||
#define EXCHANGE_CLIENT_H
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define nng_exchange_self                0
 | 
			
		||||
#define nng_exchange_self_name           "exchange-client"
 | 
			
		||||
#define nng_exchange_peer                0
 | 
			
		||||
#define nng_exchange_peer_name           "exchange-server"
 | 
			
		||||
#define nng_opt_exchange_add             "exchange-client-add"
 | 
			
		||||
 | 
			
		||||
#define NNG_EXCHANGE_SELF                0
 | 
			
		||||
#define NNG_EXCHANGE_SELF_NAME           "exchange-client"
 | 
			
		||||
#define NNG_EXCHANGE_PEER                0
 | 
			
		||||
#define NNG_EXCHANGE_PEER_NAME           "exchange-server"
 | 
			
		||||
#define NNG_OPT_EXCHANGE_BIND            "exchange-client-bind"
 | 
			
		||||
#define NNG_OPT_EXCHANGE_GET_EX_QUEUE    "exchange-client-get-ex-queue"
 | 
			
		||||
#define NNG_OPT_EXCHANGE_GET_RBMSGMAP    "exchange-client-get-rbmsgmap"
 | 
			
		||||
 | 
			
		||||
NNG_DECL int nng_exchange_client_open(nng_socket *sock);
 | 
			
		||||
 | 
			
		||||
#ifndef nng_exchange_open
 | 
			
		||||
#define nng_exchange_open nng_exchange_client_open
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // #define EXCHANGE_CLIENT_H
 | 
			
		||||
 | 
			
		||||
@@ -0,0 +1,23 @@
 | 
			
		||||
#ifndef PRODUCER_H
 | 
			
		||||
#define PRODUCER_H
 | 
			
		||||
 | 
			
		||||
#include<stddef.h>
 | 
			
		||||
 | 
			
		||||
typedef struct producer_s producer_t;
 | 
			
		||||
struct producer_s {
 | 
			
		||||
	/*
 | 
			
		||||
	 * return: 0: success, -1: failed
 | 
			
		||||
	 */
 | 
			
		||||
	int (*match)(void *data);
 | 
			
		||||
	/*
 | 
			
		||||
	 * return: 0: continue, -1: stop and return
 | 
			
		||||
	 */
 | 
			
		||||
	int (*target)(void *data);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int producer_init(producer_t **p,
 | 
			
		||||
				  int (*match)(void *data),
 | 
			
		||||
				  int (*target)(void *data));
 | 
			
		||||
int producer_release(producer_t *p);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -0,0 +1,54 @@
 | 
			
		||||
//
 | 
			
		||||
// Copyright 2024 NanoMQ Team, Inc. <wangwei@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.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#if defined(SUPP_ICEORYX)
 | 
			
		||||
 | 
			
		||||
#ifndef NNG_ICEORYX_SHM_H
 | 
			
		||||
#define NNG_ICEORYX_SHM_H
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// TODO
 | 
			
		||||
#include "../../../src/supplemental/iceoryx/iceoryx_api.h"
 | 
			
		||||
 | 
			
		||||
struct nng_iceoryx_suber {
 | 
			
		||||
	nano_iceoryx_suber *suber;
 | 
			
		||||
};
 | 
			
		||||
typedef struct nng_iceoryx_suber nng_iceoryx_suber;
 | 
			
		||||
 | 
			
		||||
struct nng_iceoryx_puber {
 | 
			
		||||
	nano_iceoryx_puber *puber;
 | 
			
		||||
};
 | 
			
		||||
typedef struct nng_iceoryx_puber nng_iceoryx_puber;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
NNG_DECL int nng_iceoryx_open(nng_socket *sock, const char *runtimename);
 | 
			
		||||
 | 
			
		||||
NNG_DECL int nng_iceoryx_sub(nng_socket *sock, const char *subername,
 | 
			
		||||
    const char *const service_name, const char *const instance_name,
 | 
			
		||||
    const char *const event, nng_iceoryx_suber **nsp);
 | 
			
		||||
 | 
			
		||||
NNG_DECL int nng_iceoryx_pub(nng_socket *sock, const char *pubername,
 | 
			
		||||
    const char *const service_name, const char *const instance_name,
 | 
			
		||||
    const char *const event, nng_iceoryx_puber **npp);
 | 
			
		||||
 | 
			
		||||
NNG_DECL int nng_msg_iceoryx_alloc(nng_msg **msgp, nng_iceoryx_puber *puber, size_t sz);
 | 
			
		||||
NNG_DECL int nng_msg_iceoryx_free(nng_msg *msg, nng_iceoryx_suber *suber);
 | 
			
		||||
NNG_DECL int nng_msg_iceoryx_append(nng_msg *msg, const void *data, size_t sz);
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@@ -0,0 +1,596 @@
 | 
			
		||||
//
 | 
			
		||||
// 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.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
// This file is for the MQTT client implementation.
 | 
			
		||||
// Note that while there are some similarities, MQTT is sufficiently
 | 
			
		||||
// different enough from SP that many of the APIs cannot be easily
 | 
			
		||||
// shared.
 | 
			
		||||
//
 | 
			
		||||
// At this time there is no server provided by NNG itself, although
 | 
			
		||||
// the nanomq project provides such a server (and is based on NNG.)
 | 
			
		||||
//
 | 
			
		||||
// About our semantics:
 | 
			
		||||
//
 | 
			
		||||
// 1. MQTT client sockets have a single implicit dialer, and cannot
 | 
			
		||||
//    support creation of additional dialers or listeners.
 | 
			
		||||
// 2. MQTT client sockets do support contexts; each context will
 | 
			
		||||
//    maintain its own subscriptions, and the socket will keep a
 | 
			
		||||
//    per-socket list of them and manage the full list.
 | 
			
		||||
// 3. Send sends PUBLISH messages.
 | 
			
		||||
// 4. Receive is used to receive published data from the server.
 | 
			
		||||
// 5. Most of the MQTT specific "features" are as options on the socket,
 | 
			
		||||
//    dialer, or even the message.  (For example message topics are set
 | 
			
		||||
//    as options on the message.)
 | 
			
		||||
// 6. Pipe events can be used to detect connect/disconnect events.
 | 
			
		||||
// 7. Any QoS details such as retransmit, etc. are handled under the hood.
 | 
			
		||||
//    This includes packet IDs.
 | 
			
		||||
// 8. PING and keep-alive is handled under the hood.
 | 
			
		||||
// 9. For publish actions, a separate method is used (not send/receive).
 | 
			
		||||
 | 
			
		||||
#ifndef NNG_MQTT_CLIENT_H
 | 
			
		||||
#define NNG_MQTT_CLIENT_H
 | 
			
		||||
 | 
			
		||||
#include <nng/nng.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define MQTT_PROTOCOL_NAME_v31 "MQIsdp"
 | 
			
		||||
#define MQTT_PROTOCOL_VERSION_v31 3
 | 
			
		||||
#define MQTT_PROTOCOL_NAME "MQTT"
 | 
			
		||||
#define MQTT_PROTOCOL_VERSION_v311 4
 | 
			
		||||
#define MQTT_PROTOCOL_VERSION_v5 5
 | 
			
		||||
 | 
			
		||||
// NNG_OPT_MQTT_EXPIRES is a 32-bit integer representing the expiration in
 | 
			
		||||
// seconds. This can be applied to a message.
 | 
			
		||||
// (TODO: What about session expiry?)
 | 
			
		||||
#define NNG_OPT_MQTT_EXPIRES "expires"
 | 
			
		||||
 | 
			
		||||
#define NNG_OPT_MQTT_CONNMSG "mqtt-connect-msg"
 | 
			
		||||
 | 
			
		||||
#define NNG_OPT_MQTT_CONNECT_PROPERTY "mqtt-connack-property"
 | 
			
		||||
 | 
			
		||||
#define NNG_OPT_MQTT_CONNECT_REASON "mqtt-connack-reason"
 | 
			
		||||
 | 
			
		||||
#define NNG_OPT_MQTT_RECONNECT_BACKOFF_MAX "mqtt-reconnect-backoff-max"
 | 
			
		||||
 | 
			
		||||
#define NNG_OPT_MQTT_DISCONNECT_PROPERTY "mqtt-disconnect-property"
 | 
			
		||||
 | 
			
		||||
#define NNG_OPT_MQTT_RETRY_INTERVAL "mqtt-client-retry-interval"
 | 
			
		||||
 | 
			
		||||
#define NNG_OPT_MQTT_RETRY_WAIT_TIME "mqtt-client-retry-wait-time"
 | 
			
		||||
 | 
			
		||||
#define NNG_OPT_MQTT_DISCONNECT_REASON "mqtt-disconnect-reason"
 | 
			
		||||
 | 
			
		||||
#define NNG_OPT_MQTT_SQLITE "mqtt-sqlite-option"
 | 
			
		||||
 | 
			
		||||
#define NNG_OPT_MQTT_ENABLE_SCRAM "mqtt-scram-option"
 | 
			
		||||
 | 
			
		||||
// NNG_OPT_MQTT_QOS is a byte (only lower two bits significant) representing
 | 
			
		||||
// the quality of service.  At this time, only level zero is supported.
 | 
			
		||||
// TODO: level 1 and level 2 QoS
 | 
			
		||||
#define NNG_OPT_MQTT_QOS "qos"
 | 
			
		||||
 | 
			
		||||
// NNG_OPT_MQTT_RETAIN indicates that the message should be retained on
 | 
			
		||||
// the server as the single retained message for the associated topic.
 | 
			
		||||
// This is a boolean.
 | 
			
		||||
#define NNG_OPT_MQTT_RETAIN "retain"
 | 
			
		||||
 | 
			
		||||
// NNG_OPT_MQTT_DUP indicates that the message is a duplicate. This can
 | 
			
		||||
// only be returned on a message -- this client will add this flag if
 | 
			
		||||
// sending a duplicate message (QoS 1 and 2 only).
 | 
			
		||||
#define NNG_OPT_MQTT_DUP "dup"
 | 
			
		||||
 | 
			
		||||
// NNG_OPT_MQTT_TOPIC is the message topic.  It is encoded as an "Encoded
 | 
			
		||||
// UTF-8 string" (uint16 length followed by UTF-8 data).  At the API, it
 | 
			
		||||
// is just a UTF-8 string (C style, with a terminating byte.)  Note that
 | 
			
		||||
// we do not support embedded NUL bytes in our UTF-8 strings.  Every
 | 
			
		||||
// MQTT published message must have a topic.
 | 
			
		||||
#define NNG_OPT_MQTT_TOPIC "topic"
 | 
			
		||||
 | 
			
		||||
// NNG_OPT_MQTT_REASON is a reason that can be conveyed with a message.
 | 
			
		||||
// It is a UTF-8 string.
 | 
			
		||||
#define NNG_OPT_MQTT_REASON "reason"
 | 
			
		||||
 | 
			
		||||
// NNG_OPT_MQTT_USER_PROPS is an array of user properties. These are
 | 
			
		||||
// send with the message, and used for application specific purposes.
 | 
			
		||||
// The properties are of the type nng_mqtt_user_props_t.
 | 
			
		||||
#define NNG_OPT_MQTT_USER_PROPS "user-props"
 | 
			
		||||
 | 
			
		||||
// NNG_OPT_MQTT_PAYLOAD_FORMAT is the format of the payload for a message.
 | 
			
		||||
// It can be 0, indicating binary data, or 1, indicating UTF-8.
 | 
			
		||||
#define NNG_OPT_MQTT_PAYLOAD_FORMAT "mqtt-payload-format"
 | 
			
		||||
 | 
			
		||||
// NNG_OPT_MQTT_CONTENT_TYPE is the mime type as UTF-8 for PUBLISH
 | 
			
		||||
// or Will messages.
 | 
			
		||||
#define NNG_OPT_MQTT_CONTENT_TYPE "content-type"
 | 
			
		||||
 | 
			
		||||
// The following options are reserved for MQTT v5.0 request/reply support.
 | 
			
		||||
#define NNG_OPT_MQTT_RESPONSE_TOPIC "response-topic"
 | 
			
		||||
#define NNG_OPT_MQTT_CORRELATION_DATA "correlation-data"
 | 
			
		||||
 | 
			
		||||
// NNG_OPT_MQTT_CLIENT_ID is the UTF-8 string corresponding to the client
 | 
			
		||||
// identification.  We automatically generate an initial value fo this,
 | 
			
		||||
// which is the UUID.
 | 
			
		||||
// TODO: Should applications be permitted to change this?
 | 
			
		||||
#define NNG_OPT_MQTT_CLIENT_ID "client-id" // UTF-8 string
 | 
			
		||||
 | 
			
		||||
#define NNG_OPT_MQTT_WILL_DELAY "will-delay"
 | 
			
		||||
 | 
			
		||||
// NNG_OPT_MQTT_RECEIVE_MAX is used with QoS 1 or 2 (not implemented),
 | 
			
		||||
// and indicates the level of concurrent receives it is willing to
 | 
			
		||||
// process. (TODO: Implementation note: we will need to preallocate a complete
 | 
			
		||||
// state machine (aio, plus any state) for each value of this > 0.
 | 
			
		||||
// It's not clear whether this should be tunable.)  This is read-only
 | 
			
		||||
// property on the socket, and records the value given from the server.
 | 
			
		||||
// It will be 64K if the server did not indicate a specific value.
 | 
			
		||||
#define NNG_OPT_MQTT_RECEIVE_MAX "mqtt-receive-max"
 | 
			
		||||
 | 
			
		||||
// NNG_OPT_MQTT_SESSION_EXPIRES is an nng_duration.
 | 
			
		||||
// If set to NNG_DURATION_ZERO, then the session will expire automatically
 | 
			
		||||
// when the connection is closed.
 | 
			
		||||
// If it set to NNG_DURATION_INFINITE, the session never expires.
 | 
			
		||||
// Otherwise it will be a whole number of seconds indicating the session
 | 
			
		||||
// expiry interval.
 | 
			
		||||
#define NNG_OPT_MQTT_SESSION_EXPIRES "session-expires"
 | 
			
		||||
 | 
			
		||||
#define NNG_OPT_MQTT_TOPIC_ALIAS_MAX "alias-max"
 | 
			
		||||
#define NNG_OPT_MQTT_TOPIC_ALIAS "topic-alias"
 | 
			
		||||
#define NNG_OPT_MQTT_MAX_QOS "max-qos"
 | 
			
		||||
 | 
			
		||||
// NNG_MAX_RECV_LMQ and NNG_MAX_SEND_LMQ define the length of waiting queue
 | 
			
		||||
// they are the length of nni_lmq, please be ware it affects the memory usage
 | 
			
		||||
// significantly while having heavy throughput
 | 
			
		||||
#define NNG_MAX_RECV_LMQ 64
 | 
			
		||||
#define NNG_MAX_SEND_LMQ 64
 | 
			
		||||
#define NNG_TRAN_MAX_LMQ_SIZE 128
 | 
			
		||||
 | 
			
		||||
// NNG_TLS_xxx options can be set on the client as well.
 | 
			
		||||
// E.g. NNG_OPT_TLS_CA_CERT, etc.
 | 
			
		||||
 | 
			
		||||
// TBD: Extended authentication.  I think we should skip it -- everyone
 | 
			
		||||
// should just use TLS if they need security.
 | 
			
		||||
 | 
			
		||||
// NNG_OPT_MQTT_KEEP_ALIVE is set on the client, and can be retrieved
 | 
			
		||||
// by the client.  This is an nng_duration but will always be zero or
 | 
			
		||||
// a whole number of seconds less than 65536.  If setting the value,
 | 
			
		||||
// it must be set before the client connects.  When retrieved, the
 | 
			
		||||
// server's value will be returned (if it is different from what we
 | 
			
		||||
// requested.)  If we reconnect, we will try again with the configured
 | 
			
		||||
// value rather than the value that we got from the server last time.
 | 
			
		||||
#define NNG_OPT_MQTT_KEEP_ALIVE "mqtt-keep-alive"
 | 
			
		||||
 | 
			
		||||
// NNG_OPT_MQTT_MAX_PACKET_SIZE is the maximum packet size that can
 | 
			
		||||
// be used.  It needs to be set before the client dials.
 | 
			
		||||
#define NNG_OPT_MQTT_MAX_PACKET_SIZE "mqtt-max-packet-size"
 | 
			
		||||
#define NNG_OPT_MQTT_USERNAME "username"
 | 
			
		||||
#define NNG_OPT_MQTT_PASSWORD "password"
 | 
			
		||||
 | 
			
		||||
// Message handling.  Note that topic aliases are handled by the library
 | 
			
		||||
// automatically on behalf of the consumer.
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
	nng_mqtt_msg_format_binary = 0,
 | 
			
		||||
	nng_mqtt_msg_format_utf8   = 1,
 | 
			
		||||
} nng_mqtt_msg_format_t;
 | 
			
		||||
 | 
			
		||||
/* Message types & flags */
 | 
			
		||||
#define CMD_UNKNOWN 0x00
 | 
			
		||||
#define CMD_CONNECT 0x10
 | 
			
		||||
#define CMD_CONNACK 0x20
 | 
			
		||||
#define CMD_PUBLISH 0x30	// indicates PUBLISH packet & MQTTV4 pub packet
 | 
			
		||||
#define CMD_PUBLISH_V5 0x31 // this is the flag for differing MQTTV5 from V4 V3
 | 
			
		||||
#define CMD_PUBACK 0x40
 | 
			
		||||
#define CMD_PUBREC 0x50
 | 
			
		||||
#define CMD_PUBREL 0x60
 | 
			
		||||
#define CMD_PUBCOMP 0x70
 | 
			
		||||
#define CMD_SUBSCRIBE 0x80
 | 
			
		||||
#define CMD_SUBACK 0x90
 | 
			
		||||
#define CMD_UNSUBSCRIBE 0xA0
 | 
			
		||||
#define CMD_UNSUBACK 0xB0
 | 
			
		||||
#define CMD_PINGREQ 0xC0
 | 
			
		||||
#define CMD_PINGRESP 0xD0
 | 
			
		||||
#define CMD_DISCONNECT 0xE0
 | 
			
		||||
#define CMD_AUTH_V5 0xF0
 | 
			
		||||
#define CMD_DISCONNECT_EV 0xE2
 | 
			
		||||
#define CMD_LASTWILL 0XE3
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
	NNG_MQTT_CONNECT     = 0x01,
 | 
			
		||||
	NNG_MQTT_CONNACK     = 0x02,
 | 
			
		||||
	NNG_MQTT_PUBLISH     = 0x03,
 | 
			
		||||
	NNG_MQTT_PUBACK      = 0x04,
 | 
			
		||||
	NNG_MQTT_PUBREC      = 0x05,
 | 
			
		||||
	NNG_MQTT_PUBREL      = 0x06,
 | 
			
		||||
	NNG_MQTT_PUBCOMP     = 0x07,
 | 
			
		||||
	NNG_MQTT_SUBSCRIBE   = 0x08,
 | 
			
		||||
	NNG_MQTT_SUBACK      = 0x09,
 | 
			
		||||
	NNG_MQTT_UNSUBSCRIBE = 0x0A,
 | 
			
		||||
	NNG_MQTT_UNSUBACK    = 0x0B,
 | 
			
		||||
	NNG_MQTT_PINGREQ     = 0x0C,
 | 
			
		||||
	NNG_MQTT_PINGRESP    = 0x0D,
 | 
			
		||||
	NNG_MQTT_DISCONNECT  = 0x0E,
 | 
			
		||||
	NNG_MQTT_AUTH        = 0x0F
 | 
			
		||||
} nng_mqtt_packet_type;
 | 
			
		||||
 | 
			
		||||
//TODO Enum is not fitting here
 | 
			
		||||
typedef enum {
 | 
			
		||||
	SUCCESS                                = 0,
 | 
			
		||||
	NORMAL_DISCONNECTION                   = 0,
 | 
			
		||||
	GRANTED_QOS_0                          = 0,
 | 
			
		||||
	GRANTED_QOS_1                          = 1,
 | 
			
		||||
	GRANTED_QOS_2                          = 2,
 | 
			
		||||
	DISCONNECT_WITH_WILL_MESSAGE           = 4,
 | 
			
		||||
	NO_MATCHING_SUBSCRIBERS                = 16,
 | 
			
		||||
	NO_SUBSCRIPTION_EXISTED                = 17,
 | 
			
		||||
	CONTINUE_AUTHENTICATION                = 24,
 | 
			
		||||
	RE_AUTHENTICATE                        = 25,
 | 
			
		||||
	UNSPECIFIED_ERROR                      = 128,
 | 
			
		||||
	MALFORMED_PACKET                       = 129,
 | 
			
		||||
	PROTOCOL_ERROR                         = 130,
 | 
			
		||||
	IMPLEMENTATION_SPECIFIC_ERROR          = 131,
 | 
			
		||||
	UNSUPPORTED_PROTOCOL_VERSION           = 132,
 | 
			
		||||
	CLIENT_IDENTIFIER_NOT_VALID            = 133,
 | 
			
		||||
	BAD_USER_NAME_OR_PASSWORD              = 134,
 | 
			
		||||
	NOT_AUTHORIZED                         = 135,
 | 
			
		||||
	SERVER_UNAVAILABLE                     = 136,
 | 
			
		||||
	SERVER_BUSY                            = 137,
 | 
			
		||||
	BANNED                                 = 138,
 | 
			
		||||
	SERVER_SHUTTING_DOWN                   = 139,
 | 
			
		||||
	BAD_AUTHENTICATION_METHOD              = 140,
 | 
			
		||||
	KEEP_ALIVE_TIMEOUT                     = 141,
 | 
			
		||||
	SESSION_TAKEN_OVER                     = 142,
 | 
			
		||||
	TOPIC_FILTER_INVALID                   = 143,
 | 
			
		||||
	TOPIC_NAME_INVALID                     = 144,
 | 
			
		||||
	PACKET_IDENTIFIER_IN_USE               = 145,
 | 
			
		||||
	PACKET_IDENTIFIER_NOT_FOUND            = 146,
 | 
			
		||||
	RECEIVE_MAXIMUM_EXCEEDED               = 147,
 | 
			
		||||
	TOPIC_ALIAS_INVALID                    = 148,
 | 
			
		||||
	PACKET_TOO_LARGE                       = 149,
 | 
			
		||||
	MESSAGE_RATE_TOO_HIGH                  = 150,
 | 
			
		||||
	QUOTA_EXCEEDED                         = 151,
 | 
			
		||||
	ADMINISTRATIVE_ACTION                  = 152,
 | 
			
		||||
	PAYLOAD_FORMAT_INVALID                 = 153,
 | 
			
		||||
	RETAIN_NOT_SUPPORTED                   = 154,
 | 
			
		||||
	QOS_NOT_SUPPORTED                      = 155,
 | 
			
		||||
	USE_ANOTHER_SERVER                     = 156,
 | 
			
		||||
	SERVER_MOVED                           = 157,
 | 
			
		||||
	SHARED_SUBSCRIPTIONS_NOT_SUPPORTED     = 158,
 | 
			
		||||
	CONNECTION_RATE_EXCEEDED               = 159,
 | 
			
		||||
	MAXIMUM_CONNECT_TIME                   = 160,
 | 
			
		||||
	SUBSCRIPTION_IDENTIFIERS_NOT_SUPPORTED = 161,
 | 
			
		||||
	WILDCARD_SUBSCRIPTIONS_NOT_SUPPORTED   = 162
 | 
			
		||||
 | 
			
		||||
} reason_code;
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
	PAYLOAD_FORMAT_INDICATOR          = 1,
 | 
			
		||||
	MESSAGE_EXPIRY_INTERVAL           = 2,
 | 
			
		||||
	CONTENT_TYPE                      = 3,
 | 
			
		||||
	RESPONSE_TOPIC                    = 8,
 | 
			
		||||
	CORRELATION_DATA                  = 9,
 | 
			
		||||
	SUBSCRIPTION_IDENTIFIER           = 11,
 | 
			
		||||
	SESSION_EXPIRY_INTERVAL           = 17,
 | 
			
		||||
	ASSIGNED_CLIENT_IDENTIFIER        = 18,
 | 
			
		||||
	SERVER_KEEP_ALIVE                 = 19,
 | 
			
		||||
	AUTHENTICATION_METHOD             = 21,
 | 
			
		||||
	AUTHENTICATION_DATA               = 22,
 | 
			
		||||
	REQUEST_PROBLEM_INFORMATION       = 23,
 | 
			
		||||
	WILL_DELAY_INTERVAL               = 24,
 | 
			
		||||
	REQUEST_RESPONSE_INFORMATION      = 25,
 | 
			
		||||
	RESPONSE_INFORMATION              = 26,
 | 
			
		||||
	SERVER_REFERENCE                  = 28,
 | 
			
		||||
	REASON_STRING                     = 31,
 | 
			
		||||
	RECEIVE_MAXIMUM                   = 33,
 | 
			
		||||
	TOPIC_ALIAS_MAXIMUM               = 34,
 | 
			
		||||
	TOPIC_ALIAS                       = 35,
 | 
			
		||||
	PUBLISH_MAXIMUM_QOS               = 36,
 | 
			
		||||
	RETAIN_AVAILABLE                  = 37,
 | 
			
		||||
	USER_PROPERTY                     = 38,
 | 
			
		||||
	MAXIMUM_PACKET_SIZE               = 39,
 | 
			
		||||
	WILDCARD_SUBSCRIPTION_AVAILABLE   = 40,
 | 
			
		||||
	SUBSCRIPTION_IDENTIFIER_AVAILABLE = 41,
 | 
			
		||||
	SHARED_SUBSCRIPTION_AVAILABLE     = 42
 | 
			
		||||
} properties_type;
 | 
			
		||||
 | 
			
		||||
struct mqtt_buf_t {
 | 
			
		||||
	uint32_t length;
 | 
			
		||||
	uint8_t *buf;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct mqtt_buf_t mqtt_buf;
 | 
			
		||||
typedef struct mqtt_buf_t nng_mqtt_buffer;
 | 
			
		||||
typedef struct mqtt_buf_t nng_mqtt_topic;
 | 
			
		||||
 | 
			
		||||
struct mqtt_kv_t {
 | 
			
		||||
	mqtt_buf key;
 | 
			
		||||
	mqtt_buf value;
 | 
			
		||||
};
 | 
			
		||||
typedef struct mqtt_kv_t mqtt_kv;
 | 
			
		||||
 | 
			
		||||
typedef struct mqtt_topic_qos_t {
 | 
			
		||||
	nng_mqtt_topic topic;
 | 
			
		||||
	uint8_t        qos;
 | 
			
		||||
	uint8_t        nolocal;
 | 
			
		||||
	uint8_t        rap;
 | 
			
		||||
	uint8_t        retain_handling;
 | 
			
		||||
} mqtt_topic_qos;
 | 
			
		||||
 | 
			
		||||
typedef struct mqtt_topic_qos_t nng_mqtt_topic_qos;
 | 
			
		||||
 | 
			
		||||
extern uint16_t nni_msg_get_pub_pid(nng_msg *m);
 | 
			
		||||
struct mqtt_string {
 | 
			
		||||
	char *   body;
 | 
			
		||||
	uint32_t len;
 | 
			
		||||
};
 | 
			
		||||
typedef struct mqtt_string mqtt_string;
 | 
			
		||||
 | 
			
		||||
struct mqtt_string_node {
 | 
			
		||||
	struct mqtt_string_node *next;
 | 
			
		||||
	mqtt_string *            it;
 | 
			
		||||
};
 | 
			
		||||
typedef struct mqtt_string_node mqtt_string_node;
 | 
			
		||||
 | 
			
		||||
struct mqtt_binary {
 | 
			
		||||
	uint8_t *body;
 | 
			
		||||
	uint32_t len;
 | 
			
		||||
};
 | 
			
		||||
typedef struct mqtt_binary mqtt_binary;
 | 
			
		||||
 | 
			
		||||
struct mqtt_str_pair {
 | 
			
		||||
	char *   key; // key
 | 
			
		||||
	uint32_t len_key;
 | 
			
		||||
	char *   val; // value
 | 
			
		||||
	uint32_t len_val;
 | 
			
		||||
};
 | 
			
		||||
typedef struct mqtt_str_pair mqtt_str_pair;
 | 
			
		||||
 | 
			
		||||
union Property_type {
 | 
			
		||||
	uint8_t  u8;
 | 
			
		||||
	uint16_t u16;
 | 
			
		||||
	uint32_t u32;
 | 
			
		||||
	uint32_t varint;
 | 
			
		||||
	mqtt_buf binary;
 | 
			
		||||
	mqtt_buf str;
 | 
			
		||||
	mqtt_kv  strpair;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
	U8,
 | 
			
		||||
	U16,
 | 
			
		||||
	U32,
 | 
			
		||||
	VARINT,
 | 
			
		||||
	BINARY,
 | 
			
		||||
	STR,
 | 
			
		||||
	STR_PAIR,
 | 
			
		||||
	UNKNOWN
 | 
			
		||||
} property_type_enum;
 | 
			
		||||
 | 
			
		||||
struct property_data {
 | 
			
		||||
	property_type_enum  p_type;
 | 
			
		||||
	union Property_type p_value;
 | 
			
		||||
	bool                is_copy;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct property_data property_data;
 | 
			
		||||
 | 
			
		||||
struct property {
 | 
			
		||||
	uint8_t          id;
 | 
			
		||||
	property_data    data;
 | 
			
		||||
	struct property *next;
 | 
			
		||||
};
 | 
			
		||||
typedef struct property property;
 | 
			
		||||
 | 
			
		||||
NNG_DECL int  nng_mqtt_msg_alloc(nng_msg **, size_t);
 | 
			
		||||
NNG_DECL int  nng_mqtt_msg_proto_data_alloc(nng_msg *);
 | 
			
		||||
NNG_DECL void nng_mqtt_msg_proto_data_free(nng_msg *);
 | 
			
		||||
NNG_DECL int  nng_mqtt_msg_encode(nng_msg *);
 | 
			
		||||
NNG_DECL int  nng_mqtt_msg_decode(nng_msg *);
 | 
			
		||||
NNG_DECL int  nng_mqttv5_msg_encode(nng_msg *);
 | 
			
		||||
NNG_DECL int  nng_mqttv5_msg_decode(nng_msg *);
 | 
			
		||||
NNG_DECL int  nng_mqtt_msg_validate(nng_msg *, uint8_t);
 | 
			
		||||
NNG_DECL void nng_mqtt_msg_set_packet_type(nng_msg *, nng_mqtt_packet_type);
 | 
			
		||||
NNG_DECL nng_mqtt_packet_type nng_mqtt_msg_get_packet_type(nng_msg *);
 | 
			
		||||
NNG_DECL void nng_mqtt_msg_set_bridge_bool(nng_msg *msg, bool bridged);
 | 
			
		||||
NNG_DECL bool nng_mqtt_msg_get_bridge_bool(nng_msg *msg);
 | 
			
		||||
NNG_DECL void nng_mqtt_msg_set_sub_retain_bool(nng_msg *msg, bool retain);
 | 
			
		||||
NNG_DECL bool nng_mqtt_msg_get_sub_retain_bool(nng_msg *msg);
 | 
			
		||||
NNG_DECL void nng_mqtt_msg_set_connect_proto_version(nng_msg *, uint8_t);
 | 
			
		||||
NNG_DECL void nng_mqtt_msg_set_connect_keep_alive(nng_msg *, uint16_t);
 | 
			
		||||
NNG_DECL void nng_mqtt_msg_set_connect_client_id(nng_msg *, const char *);
 | 
			
		||||
NNG_DECL void nng_mqtt_msg_set_connect_user_name(nng_msg *, const char *);
 | 
			
		||||
NNG_DECL void nng_mqtt_msg_set_connect_password(nng_msg *, const char *);
 | 
			
		||||
NNG_DECL void nng_mqtt_msg_set_connect_clean_session(nng_msg *, bool);
 | 
			
		||||
NNG_DECL void nng_mqtt_msg_set_connect_will_topic(nng_msg *, const char *);
 | 
			
		||||
NNG_DECL void nng_mqtt_msg_set_connect_will_msg(
 | 
			
		||||
    nng_msg *, uint8_t *, uint32_t);
 | 
			
		||||
NNG_DECL void nng_mqtt_msg_set_connect_will_retain(nng_msg *, bool);
 | 
			
		||||
NNG_DECL void nng_mqtt_msg_set_connect_will_qos(nng_msg *, uint8_t);
 | 
			
		||||
NNG_DECL void nng_mqtt_msg_set_connect_property(nng_msg *, property *);
 | 
			
		||||
NNG_DECL property *nng_mqtt_msg_get_connect_will_property(nng_msg *);
 | 
			
		||||
NNG_DECL void nng_mqtt_msg_set_connect_will_property(nng_msg *, property *);
 | 
			
		||||
NNG_DECL const char *nng_mqtt_msg_get_connect_user_name(nng_msg *);
 | 
			
		||||
NNG_DECL const char *nng_mqtt_msg_get_connect_password(nng_msg *);
 | 
			
		||||
NNG_DECL bool        nng_mqtt_msg_get_connect_clean_session(nng_msg *);
 | 
			
		||||
NNG_DECL uint8_t     nng_mqtt_msg_get_connect_proto_version(nng_msg *);
 | 
			
		||||
NNG_DECL uint16_t    nng_mqtt_msg_get_connect_keep_alive(nng_msg *);
 | 
			
		||||
NNG_DECL const char *nng_mqtt_msg_get_connect_client_id(nng_msg *);
 | 
			
		||||
NNG_DECL const char *nng_mqtt_msg_get_connect_will_topic(nng_msg *);
 | 
			
		||||
NNG_DECL uint8_t *nng_mqtt_msg_get_connect_will_msg(nng_msg *, uint32_t *);
 | 
			
		||||
NNG_DECL bool     nng_mqtt_msg_get_connect_will_retain(nng_msg *);
 | 
			
		||||
NNG_DECL uint8_t  nng_mqtt_msg_get_connect_will_qos(nng_msg *);
 | 
			
		||||
NNG_DECL property *nng_mqtt_msg_get_connect_property(nng_msg *);
 | 
			
		||||
 | 
			
		||||
NNG_DECL void        nng_mqtt_msg_set_connack_return_code(nng_msg *, uint8_t);
 | 
			
		||||
NNG_DECL void        nng_mqtt_msg_set_connack_flags(nng_msg *, uint8_t);
 | 
			
		||||
NNG_DECL void        nng_mqtt_msg_set_connack_property(nng_msg *, property *);
 | 
			
		||||
NNG_DECL uint8_t     nng_mqtt_msg_get_connack_return_code(nng_msg *);
 | 
			
		||||
NNG_DECL uint8_t     nng_mqtt_msg_get_connack_flags(nng_msg *);
 | 
			
		||||
NNG_DECL property   *nng_mqtt_msg_get_connack_property(nng_msg *);
 | 
			
		||||
 | 
			
		||||
NNG_DECL void        nng_mqtt_msg_set_publish_qos(nng_msg *, uint8_t);
 | 
			
		||||
NNG_DECL uint8_t     nng_mqtt_msg_get_publish_qos(nng_msg *);
 | 
			
		||||
NNG_DECL void        nng_mqtt_msg_set_publish_retain(nng_msg *, bool);
 | 
			
		||||
NNG_DECL bool        nng_mqtt_msg_get_publish_retain(nng_msg *);
 | 
			
		||||
NNG_DECL void        nng_mqtt_msg_set_publish_dup(nng_msg *, bool);
 | 
			
		||||
NNG_DECL bool        nng_mqtt_msg_get_publish_dup(nng_msg *);
 | 
			
		||||
NNG_DECL int         nng_mqtt_msg_set_publish_topic(nng_msg *, const char *);
 | 
			
		||||
NNG_DECL int         nng_mqtt_msg_set_publish_topic_len(nng_msg *msg, uint32_t len);
 | 
			
		||||
 | 
			
		||||
NNG_DECL const char *nng_mqtt_msg_get_publish_topic(nng_msg *, uint32_t *);
 | 
			
		||||
NNG_DECL int         nng_mqtt_msg_set_publish_payload(nng_msg *, uint8_t *, uint32_t);
 | 
			
		||||
NNG_DECL uint8_t    *nng_mqtt_msg_get_publish_payload(nng_msg *, uint32_t *);
 | 
			
		||||
NNG_DECL property   *nng_mqtt_msg_get_publish_property(nng_msg *);
 | 
			
		||||
NNG_DECL void        nng_mqtt_msg_set_publish_property(nng_msg *, property *);
 | 
			
		||||
 | 
			
		||||
NNG_DECL uint16_t nng_mqtt_msg_get_puback_packet_id(nng_msg *);
 | 
			
		||||
NNG_DECL property *nng_mqtt_msg_get_puback_property(nng_msg *);
 | 
			
		||||
NNG_DECL void      nng_mqtt_msg_set_puback_property(nng_msg *, property *);
 | 
			
		||||
 | 
			
		||||
NNG_DECL uint16_t nng_mqtt_msg_get_pubrec_packet_id(nng_msg *);
 | 
			
		||||
NNG_DECL property *nng_mqtt_msg_get_pubrec_property(nng_msg *);
 | 
			
		||||
NNG_DECL void      nng_mqtt_msg_set_pubrec_property(nng_msg *, property *);
 | 
			
		||||
 | 
			
		||||
NNG_DECL uint16_t nng_mqtt_msg_get_pubrel_packet_id(nng_msg *);
 | 
			
		||||
NNG_DECL property *nng_mqtt_msg_get_pubrel_property(nng_msg *);
 | 
			
		||||
NNG_DECL void      nng_mqtt_msg_set_pubrel_property(nng_msg *, property *);
 | 
			
		||||
 | 
			
		||||
NNG_DECL uint16_t nng_mqtt_msg_get_pubcomp_packet_id(nng_msg *);
 | 
			
		||||
NNG_DECL property *nng_mqtt_msg_get_pubcomp_property(nng_msg *);
 | 
			
		||||
NNG_DECL void      nng_mqtt_msg_set_pubcomp_property(nng_msg *, property *);
 | 
			
		||||
 | 
			
		||||
NNG_DECL nng_mqtt_topic_qos *nng_mqtt_msg_get_subscribe_topics(
 | 
			
		||||
    nng_msg *, uint32_t *);
 | 
			
		||||
NNG_DECL void nng_mqtt_msg_set_subscribe_topics(
 | 
			
		||||
    nng_msg *, nng_mqtt_topic_qos *, uint32_t);
 | 
			
		||||
NNG_DECL property *nng_mqtt_msg_get_subscribe_property(nng_msg *);
 | 
			
		||||
NNG_DECL void      nng_mqtt_msg_set_subscribe_property(nng_msg *, property *);
 | 
			
		||||
 | 
			
		||||
NNG_DECL void nng_mqtt_msg_set_suback_return_codes(
 | 
			
		||||
    nng_msg *, uint8_t *, uint32_t);
 | 
			
		||||
NNG_DECL uint8_t *nng_mqtt_msg_get_suback_return_codes(nng_msg *, uint32_t *);
 | 
			
		||||
NNG_DECL property *nng_mqtt_msg_get_suback_property(nng_msg *);
 | 
			
		||||
NNG_DECL void      nng_mqtt_msg_set_suback_property(nng_msg *, property *);
 | 
			
		||||
 | 
			
		||||
NNG_DECL void     nng_mqtt_msg_set_unsubscribe_topics(
 | 
			
		||||
        nng_msg *, nng_mqtt_topic *, uint32_t);
 | 
			
		||||
NNG_DECL nng_mqtt_topic *nng_mqtt_msg_get_unsubscribe_topics(
 | 
			
		||||
    nng_msg *, uint32_t *);
 | 
			
		||||
NNG_DECL property *nng_mqtt_msg_get_unsubscribe_property(nng_msg *);
 | 
			
		||||
NNG_DECL void      nng_mqtt_msg_set_unsubscribe_property(nng_msg *, property *);
 | 
			
		||||
 | 
			
		||||
NNG_DECL void nng_mqtt_msg_set_unsuback_return_codes(
 | 
			
		||||
    nng_msg *, uint8_t *, uint32_t);
 | 
			
		||||
NNG_DECL uint8_t *nng_mqtt_msg_get_unsuback_return_codes(nng_msg *, uint32_t *);
 | 
			
		||||
NNG_DECL property *nng_mqtt_msg_get_unsuback_property(nng_msg *);
 | 
			
		||||
NNG_DECL void      nng_mqtt_msg_set_unsuback_property(nng_msg *, property *);
 | 
			
		||||
 | 
			
		||||
NNG_DECL property   *nng_mqtt_msg_get_disconnect_property(nng_msg *);
 | 
			
		||||
NNG_DECL void        nng_mqtt_msg_set_disconnect_property(nng_msg *, property *);
 | 
			
		||||
 | 
			
		||||
NNG_DECL nng_mqtt_topic *nng_mqtt_topic_array_create(size_t);
 | 
			
		||||
NNG_DECL void nng_mqtt_topic_array_set(nng_mqtt_topic *, size_t, const char *);
 | 
			
		||||
NNG_DECL void nng_mqtt_topic_array_free(nng_mqtt_topic *, size_t);
 | 
			
		||||
NNG_DECL nng_mqtt_topic_qos *nng_mqtt_topic_qos_array_create(size_t);
 | 
			
		||||
NNG_DECL void nng_mqtt_topic_qos_array_set(nng_mqtt_topic_qos *, size_t,
 | 
			
		||||
           const char *, uint8_t, uint8_t, uint8_t, uint8_t);
 | 
			
		||||
NNG_DECL void nng_mqtt_topic_qos_array_free(nng_mqtt_topic_qos *, size_t);
 | 
			
		||||
NNG_DECL int  nng_mqtt_set_connect_cb(nng_socket, nng_pipe_cb, void *);
 | 
			
		||||
NNG_DECL int  nng_mqtt_set_disconnect_cb(nng_socket, nng_pipe_cb, void *);
 | 
			
		||||
NNG_DECL void nng_mqtt_msg_dump(nng_msg *, uint8_t *, uint32_t, bool);
 | 
			
		||||
 | 
			
		||||
NNG_DECL conn_param *nng_get_conn_param_from_msg(nng_msg *);
 | 
			
		||||
NNG_DECL void nng_msg_proto_set_property(nng_msg *msg, void *p);
 | 
			
		||||
NNG_DECL void nng_mqtt_msg_set_disconnect_reason_code(nng_msg *msg, uint8_t reason_code);
 | 
			
		||||
 | 
			
		||||
NNG_DECL uint32_t get_mqtt_properties_len(property *prop);
 | 
			
		||||
NNG_DECL int      mqtt_property_free(property *prop);
 | 
			
		||||
NNG_DECL void      mqtt_property_foreach(property *prop, void (*cb)(property *));
 | 
			
		||||
NNG_DECL int       mqtt_property_dup(property **dup, const property *src);
 | 
			
		||||
NNG_DECL property *mqtt_property_pub_by_will(property *will_prop);
 | 
			
		||||
NNG_DECL int mqtt_property_value_copy(property *dst, const property *src);
 | 
			
		||||
 | 
			
		||||
NNG_DECL property *mqtt_property_alloc(void);
 | 
			
		||||
NNG_DECL property *mqtt_property_set_value_u8(uint8_t prop_id, uint8_t value);
 | 
			
		||||
NNG_DECL property *mqtt_property_set_value_u16(uint8_t prop_id, uint16_t value);
 | 
			
		||||
NNG_DECL property *mqtt_property_set_value_u32(uint8_t prop_id, uint32_t value);
 | 
			
		||||
NNG_DECL property *mqtt_property_set_value_varint(uint8_t prop_id, uint32_t value);
 | 
			
		||||
NNG_DECL property *mqtt_property_set_value_binary(uint8_t prop_id, uint8_t *value, uint32_t len, bool copy_value);
 | 
			
		||||
NNG_DECL property *mqtt_property_set_value_str( uint8_t prop_id, const char *value, uint32_t len, bool copy_value);
 | 
			
		||||
NNG_DECL property *mqtt_property_set_value_strpair(uint8_t prop_id, const char *key, uint32_t key_len, const char *value, uint32_t value_len, bool copy_value);
 | 
			
		||||
 | 
			
		||||
NNG_DECL property_type_enum mqtt_property_get_value_type(uint8_t prop_id);
 | 
			
		||||
NNG_DECL property_data *mqtt_property_get_value(property *prop, uint8_t prop_id);
 | 
			
		||||
NNG_DECL void      mqtt_property_append(property *prop_list, property *last);
 | 
			
		||||
 | 
			
		||||
// Note that MQTT sockets can be connected to at most a single server.
 | 
			
		||||
// Creating the client does not connect it.
 | 
			
		||||
NNG_DECL int nng_mqtt_client_open(nng_socket *);
 | 
			
		||||
NNG_DECL int nng_mqttv5_client_open(nng_socket *);
 | 
			
		||||
 | 
			
		||||
// Note that there is a single implicit dialer for the client,
 | 
			
		||||
// and options may be set on the socket to configure dial options.
 | 
			
		||||
// Those options should be set before doing nng_dial().
 | 
			
		||||
 | 
			
		||||
// close done via nng_close().
 | 
			
		||||
 | 
			
		||||
// Question: session resumption.  Should we resume sessions under the hood
 | 
			
		||||
// as part of reconnection, or do we want to expose this to the API user?
 | 
			
		||||
// My inclination is not to expose.
 | 
			
		||||
 | 
			
		||||
// nng_dial or nng_dialer_create can be used, but this protocol only
 | 
			
		||||
// allows a single dialer to be created on the socket.
 | 
			
		||||
 | 
			
		||||
// Subscriptions are normally run synchronously from the view of the
 | 
			
		||||
// caller.  Because there is a round-trip message involved, we use
 | 
			
		||||
// a separate method instead of merely relying upon socket options.
 | 
			
		||||
// TODO: shared subscriptions.  Subscription options (retain, QoS)
 | 
			
		||||
typedef struct nng_mqtt_client nng_mqtt_client;
 | 
			
		||||
typedef void(nng_mqtt_send_cb)(nng_mqtt_client *client, nng_msg *msg, void *);
 | 
			
		||||
struct nng_mqtt_client{
 | 
			
		||||
	nng_socket sock;
 | 
			
		||||
	nng_aio   *send_aio;
 | 
			
		||||
	nng_aio   *recv_aio;
 | 
			
		||||
	void      *msgq;
 | 
			
		||||
	void      *obj; // user defined callback obj
 | 
			
		||||
	bool       async;
 | 
			
		||||
 | 
			
		||||
	nng_mqtt_send_cb *cb;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
NNG_DECL nng_mqtt_client *nng_mqtt_client_alloc(nng_socket, nng_mqtt_send_cb, bool);
 | 
			
		||||
NNG_DECL void nng_mqtt_client_free(nng_mqtt_client*, bool);
 | 
			
		||||
NNG_DECL int nng_mqtt_subscribe(nng_socket, nng_mqtt_topic_qos *, uint32_t, property *);
 | 
			
		||||
NNG_DECL int nng_mqtt_subscribe_async(nng_mqtt_client *, nng_mqtt_topic_qos *, size_t, property *);
 | 
			
		||||
NNG_DECL int nng_mqtt_unsubscribe(nng_socket, nng_mqtt_topic *, size_t, property *);
 | 
			
		||||
NNG_DECL int nng_mqtt_unsubscribe_async(nng_mqtt_client *, nng_mqtt_topic *, size_t, property *);
 | 
			
		||||
// as with other ctx based methods, we use the aio form exclusively
 | 
			
		||||
NNG_DECL int nng_mqtt_ctx_subscribe(nng_ctx *, const char *, nng_aio *, ...);
 | 
			
		||||
NNG_DECL int nng_mqtt_disconnect(nng_socket *, uint8_t, property *);
 | 
			
		||||
 | 
			
		||||
typedef struct nng_mqtt_sqlite_option nng_mqtt_sqlite_option;
 | 
			
		||||
 | 
			
		||||
#if defined(NNG_SUPP_SQLITE)
 | 
			
		||||
NNG_DECL int  nng_mqtt_alloc_sqlite_opt(nng_mqtt_sqlite_option **);
 | 
			
		||||
NNG_DECL int  nng_mqtt_free_sqlite_opt(nng_mqtt_sqlite_option *);
 | 
			
		||||
NNG_DECL void nng_mqtt_set_sqlite_conf(
 | 
			
		||||
    nng_mqtt_sqlite_option *sqlite, void *config);
 | 
			
		||||
NNG_DECL void nng_mqtt_sqlite_db_init(nng_mqtt_sqlite_option *, const char *);
 | 
			
		||||
NNG_DECL void nng_mqtt_sqlite_db_fini(nng_mqtt_sqlite_option *);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // NNG_MQTT_CLIENT_H
 | 
			
		||||
@@ -0,0 +1,40 @@
 | 
			
		||||
//
 | 
			
		||||
// Copyright 2022 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 NNG_MQTT_QUIC_CLIENT_H
 | 
			
		||||
#define NNG_MQTT_QUIC_CLIENT_H
 | 
			
		||||
 | 
			
		||||
#include <nng/nng.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
#if defined(SUPP_QUIC)
 | 
			
		||||
 | 
			
		||||
NNG_DECL int nng_mqttv5_quic_client_open(nng_socket *);
 | 
			
		||||
NNG_DECL int nng_mqtt_quic_client_open(nng_socket *);
 | 
			
		||||
 | 
			
		||||
NNG_DECL int nng_mqtt_quic_set_connect_cb(nng_socket *sock, int (*cb)(void *, void *), void *arg);
 | 
			
		||||
NNG_DECL int nng_mqtt_quic_set_msg_send_cb(nng_socket *sock, int (*cb)(void *, void *), void *arg);
 | 
			
		||||
NNG_DECL int nng_mqtt_quic_set_msg_recv_cb(nng_socket *sock, int (*cb)(void *, void *), void *arg);
 | 
			
		||||
NNG_DECL int nng_mqtt_quic_set_disconnect_cb(nng_socket *sock, int (*cb)(void *, void *), void *arg);
 | 
			
		||||
 | 
			
		||||
NNG_DECL int nng_mqttv5_quic_set_connect_cb(nng_socket *sock, int (*cb)(void *, void *), void *arg);
 | 
			
		||||
NNG_DECL int nng_mqttv5_quic_set_msg_send_cb(nng_socket *sock, int (*cb)(void *, void *), void *arg);
 | 
			
		||||
NNG_DECL int nng_mqttv5_quic_set_msg_recv_cb(nng_socket *sock, int (*cb)(void *, void *), void *arg);
 | 
			
		||||
NNG_DECL int nng_mqttv5_quic_set_disconnect_cb(nng_socket *sock, int (*cb)(void *, void *), void *arg);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // NNG_MQTT_QUIC_CLIENT_H
 | 
			
		||||
							
								
								
									
										87
									
								
								VNode/_software_lib/nanomq-0.22.10/include/nng/mqtt/packet.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								VNode/_software_lib/nanomq-0.22.10/include/nng/mqtt/packet.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,87 @@
 | 
			
		||||
// 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.
 | 
			
		||||
//
 | 
			
		||||
//
 | 
			
		||||
// The Struct to store mqtt_packet.
 | 
			
		||||
 | 
			
		||||
#ifndef NNG_MQTT_PACKET_H
 | 
			
		||||
#define NNG_MQTT_PACKET_H
 | 
			
		||||
 | 
			
		||||
#include "nng/nng.h"
 | 
			
		||||
#include "nng/mqtt/mqtt_client.h"
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
#define UPDATE_FIELD_INT(field, new_obj, old_obj) \
 | 
			
		||||
	do {                                      \
 | 
			
		||||
		new_obj->field = old_obj->field;  \
 | 
			
		||||
	} while (0)
 | 
			
		||||
 | 
			
		||||
#define UPDATE_FIELD_MQTT_STRING(field, sub_field, new_obj, old_obj)   \
 | 
			
		||||
	do {                                                           \
 | 
			
		||||
		if (new_obj->field.sub_field == NULL &&                \
 | 
			
		||||
		    old_obj->field.sub_field != NULL) {                \
 | 
			
		||||
			new_obj->field = old_obj->field;               \
 | 
			
		||||
			new_obj->field.sub_field =                     \
 | 
			
		||||
			    strdup((char *) old_obj->field.sub_field); \
 | 
			
		||||
		}                                                      \
 | 
			
		||||
	} while (0)
 | 
			
		||||
 | 
			
		||||
#define UPDATE_FIELD_MQTT_STRING_PAIR(                                  \
 | 
			
		||||
    field, sub_field1, sub_field2, new_obj, old_obj)                    \
 | 
			
		||||
	do {                                                            \
 | 
			
		||||
		if ((new_obj->field.sub_field1 == NULL &&               \
 | 
			
		||||
		        old_obj->field.sub_field1 != NULL) ||           \
 | 
			
		||||
		    (new_obj->field.sub_field2 == NULL &&               \
 | 
			
		||||
		        old_obj->field.sub_field2 != NULL)) {           \
 | 
			
		||||
			new_obj->field = old_obj->field;                \
 | 
			
		||||
			new_obj->field.sub_field1 =                     \
 | 
			
		||||
			    strdup((char *) old_obj->field.sub_field1); \
 | 
			
		||||
			new_obj->field.sub_field2 =                     \
 | 
			
		||||
			    strdup((char *) old_obj->field.sub_field2); \
 | 
			
		||||
		}                                                       \
 | 
			
		||||
	} while (0)
 | 
			
		||||
 | 
			
		||||
struct mqtt_msg_info {
 | 
			
		||||
	uint32_t pipe;
 | 
			
		||||
};
 | 
			
		||||
typedef struct mqtt_msg_info mqtt_msg_info;
 | 
			
		||||
 | 
			
		||||
struct topic_node {
 | 
			
		||||
	uint8_t qos : 2;
 | 
			
		||||
	uint8_t no_local : 1;
 | 
			
		||||
	uint8_t rap : 1;
 | 
			
		||||
	uint8_t retain_handling : 2;
 | 
			
		||||
 | 
			
		||||
	struct {
 | 
			
		||||
		char *body;
 | 
			
		||||
		int   len;
 | 
			
		||||
	} topic;
 | 
			
		||||
 | 
			
		||||
	uint8_t reason_code;
 | 
			
		||||
 | 
			
		||||
	struct topic_node *next;
 | 
			
		||||
};
 | 
			
		||||
typedef struct topic_node topic_node;
 | 
			
		||||
 | 
			
		||||
struct packet_subscribe {
 | 
			
		||||
	uint16_t    packet_id;
 | 
			
		||||
	uint32_t    prop_len;
 | 
			
		||||
	property   *properties;
 | 
			
		||||
	topic_node *node; // stored topic and option
 | 
			
		||||
};
 | 
			
		||||
typedef struct packet_subscribe packet_subscribe;
 | 
			
		||||
 | 
			
		||||
struct packet_unsubscribe {
 | 
			
		||||
	uint16_t    packet_id;
 | 
			
		||||
	uint32_t    prop_len;
 | 
			
		||||
	property   *properties;
 | 
			
		||||
	topic_node *node; // stored topic and option
 | 
			
		||||
};
 | 
			
		||||
typedef struct packet_unsubscribe packet_unsubscribe;
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -0,0 +1,30 @@
 | 
			
		||||
//
 | 
			
		||||
// Copyright 2021 Staysail Systems, Inc. <info@staysail.tech>
 | 
			
		||||
// Copyright 2017 Capitar IT Group BV <info@capitar.com>
 | 
			
		||||
//
 | 
			
		||||
// 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 NNG_TRANSPORT_MQTT_QUIC_H
 | 
			
		||||
#define NNG_TRANSPORT_MQTT_QUIC_H
 | 
			
		||||
 | 
			
		||||
#include <nng/nng.h>
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// QUIC transport.  This is used for communication over QUIC/UDP/IP.
 | 
			
		||||
 | 
			
		||||
#ifndef NNG_ELIDE_DEPRECATED
 | 
			
		||||
NNG_DECL int nng_mqtt_quic_register(void);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // NNG_TRANSPORT_MQTT_QUIC_H
 | 
			
		||||
@@ -0,0 +1,30 @@
 | 
			
		||||
//
 | 
			
		||||
// Copyright 2021 Staysail Systems, Inc. <info@staysail.tech>
 | 
			
		||||
// Copyright 2017 Capitar IT Group BV <info@capitar.com>
 | 
			
		||||
//
 | 
			
		||||
// 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 NNG_TRANSPORT_MQTT_TCP_TCP_H
 | 
			
		||||
#define NNG_TRANSPORT_MQTT_TCP_TCP_H
 | 
			
		||||
 | 
			
		||||
#include <nng/nng.h>
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// TCP transport.  This is used for communication over TCP/IP.
 | 
			
		||||
 | 
			
		||||
#ifndef NNG_ELIDE_DEPRECATED
 | 
			
		||||
NNG_DECL int nng_mqtt_tcp_register(void);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // NNG_TRANSPORT_MQTT_TCP_TCP_H
 | 
			
		||||
@@ -0,0 +1,30 @@
 | 
			
		||||
//
 | 
			
		||||
// Copyright 2021 Staysail Systems, Inc. <info@staysail.tech>
 | 
			
		||||
// Copyright 2017 Capitar IT Group BV <info@capitar.com>
 | 
			
		||||
//
 | 
			
		||||
// 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 NNG_TRANSPORT_MQTT_TLS_TLS_H
 | 
			
		||||
#define NNG_TRANSPORT_MQTT_TLS_TLS_H
 | 
			
		||||
 | 
			
		||||
#include <nng/nng.h>
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// TCP transport.  This is used for communication over TCP/IP.
 | 
			
		||||
 | 
			
		||||
#ifndef NNG_ELIDE_DEPRECATED
 | 
			
		||||
NNG_DECL int nng_mqtts_tcp_register(void);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // NNG_TRANSPORT_MQTT_TLS_TLS_H
 | 
			
		||||
							
								
								
									
										1753
									
								
								VNode/_software_lib/nanomq-0.22.10/include/nng/nng.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1753
									
								
								VNode/_software_lib/nanomq-0.22.10/include/nng/nng.h
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -0,0 +1,39 @@
 | 
			
		||||
//
 | 
			
		||||
// Copyright 2021 Staysail Systems, Inc. <info@staysail.tech>
 | 
			
		||||
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
 | 
			
		||||
//
 | 
			
		||||
// 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 NNG_PROTOCOL_BUS0_BUS_H
 | 
			
		||||
#define NNG_PROTOCOL_BUS0_BUS_H
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
NNG_DECL int nng_bus0_open(nng_socket *);
 | 
			
		||||
 | 
			
		||||
NNG_DECL int nng_bus0_open_raw(nng_socket *);
 | 
			
		||||
 | 
			
		||||
#ifndef nng_bus_open
 | 
			
		||||
#define nng_bus_open nng_bus0_open
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef nng_bus_open_raw
 | 
			
		||||
#define nng_bus_open_raw nng_bus0_open_raw
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define NNG_BUS0_SELF 0x70
 | 
			
		||||
#define NNG_BUS0_PEER 0x70
 | 
			
		||||
#define NNG_BUS0_SELF_NAME "bus"
 | 
			
		||||
#define NNG_BUS0_PEER_NAME "bus"
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // NNG_PROTOCOL_BUS0_BUS_H
 | 
			
		||||
@@ -0,0 +1,112 @@
 | 
			
		||||
//
 | 
			
		||||
// Copyright 2022 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 MQTT_PROTOCOL_H
 | 
			
		||||
#define MQTT_PROTOCOL_H
 | 
			
		||||
 | 
			
		||||
#define MQTT_PROTOCOL_NAME_v31 "MQIsdp"
 | 
			
		||||
#define MQTT_PROTOCOL_VERSION_v31 3
 | 
			
		||||
#define MQTT_PROTOCOL_NAME "MQTT"
 | 
			
		||||
#define MQTT_PROTOCOL_VERSION_v311 4
 | 
			
		||||
#define MQTT_PROTOCOL_VERSION_v5 5
 | 
			
		||||
 | 
			
		||||
/* NNG OPTs */
 | 
			
		||||
#define NANO_CONF "nano:conf"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Length defination */
 | 
			
		||||
// Maximum Packet Size of broker
 | 
			
		||||
#define NANO_MAX_RECV_PACKET_SIZE (2*1024*1024)
 | 
			
		||||
#define NANO_MIN_PACKET_LEN sizeof(uint8_t) * 8
 | 
			
		||||
#define NANO_CONNECT_PACKET_LEN sizeof(uint8_t) * 12
 | 
			
		||||
#define NANO_MIN_FIXED_HEADER_LEN sizeof(uint8_t) * 2
 | 
			
		||||
//flow control:how many QoS packet broker willing to process at same time.
 | 
			
		||||
#define NANO_MAX_QOS_PACKET 1024
 | 
			
		||||
 | 
			
		||||
#ifdef NANO_PACKET_SIZE
 | 
			
		||||
#define NNI_NANO_MAX_PACKET_SIZE sizeof(uint8_t) * NANO_PACKET_SIZE
 | 
			
		||||
#else
 | 
			
		||||
#define NNI_NANO_MAX_PACKET_SIZE sizeof(uint8_t) * 16
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Error values */
 | 
			
		||||
enum err_t {
 | 
			
		||||
	ERR_AUTH_CONTINUE      = -4,
 | 
			
		||||
	ERR_NO_SUBSCRIBERS     = -3,
 | 
			
		||||
	ERR_SUB_EXISTS         = -2,
 | 
			
		||||
	ERR_CONN_PENDING       = -1,
 | 
			
		||||
	ERR_SUCCESS            = 0,
 | 
			
		||||
	ERR_NOMEM              = 1,
 | 
			
		||||
	ERR_PROTOCOL           = 2,
 | 
			
		||||
	ERR_INVAL              = 3,
 | 
			
		||||
	ERR_NO_CONN            = 4,
 | 
			
		||||
	ERR_CONN_REFUSED       = 5,
 | 
			
		||||
	ERR_NOT_FOUND          = 6,
 | 
			
		||||
	ERR_CONN_LOST          = 7,
 | 
			
		||||
	ERR_TLS                = 8,
 | 
			
		||||
	ERR_PAYLOAD_SIZE       = 9,
 | 
			
		||||
	ERR_NOT_SUPPORTED      = 10,
 | 
			
		||||
	ERR_AUTH               = 11,
 | 
			
		||||
	ERR_ACL_DENIED         = 12,
 | 
			
		||||
	ERR_UNKNOWN            = 13,
 | 
			
		||||
	ERR_ERRNO              = 14,
 | 
			
		||||
	ERR_EAI                = 15,
 | 
			
		||||
	ERR_PROXY              = 16,
 | 
			
		||||
	ERR_PLUGIN_DEFER       = 17,
 | 
			
		||||
	ERR_MALFORMED_UTF8     = 18,
 | 
			
		||||
	ERR_KEEPALIVE          = 19,
 | 
			
		||||
	ERR_LOOKUP             = 20,
 | 
			
		||||
	ERR_MALFORMED_PACKET   = 21,
 | 
			
		||||
	ERR_DUPLICATE_PROPERTY = 22,
 | 
			
		||||
	ERR_TLS_HANDSHAKE      = 23,
 | 
			
		||||
	ERR_QOS_NOT_SUPPORTED  = 24,
 | 
			
		||||
	ERR_OVERSIZE_PACKET    = 25,
 | 
			
		||||
	ERR_OCSP               = 26,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// mqtt5 macro
 | 
			
		||||
#define NMQ_RECEIVE_MAXIMUM_EXCEEDED 0X93
 | 
			
		||||
#define NMQ_PACKET_TOO_LARGE 0x95
 | 
			
		||||
#define NMQ_UNSEPECIFY_ERROR 0X80
 | 
			
		||||
#define NMQ_SERVER_UNAVAILABLE 0x88
 | 
			
		||||
#define NMQ_SERVER_BUSY 0x89
 | 
			
		||||
#define NMQ_SERVER_SHUTTING_DOWN 0x8B
 | 
			
		||||
#define NMQ_KEEP_ALIVE_TIMEOUT 0x8D
 | 
			
		||||
#define NMQ_AUTH_SUB_ERROR 0X87
 | 
			
		||||
 | 
			
		||||
// MQTT Control Packet types
 | 
			
		||||
typedef enum {
 | 
			
		||||
	RESERVED    = 0,
 | 
			
		||||
	CONNECT     = 1,
 | 
			
		||||
	CONNACK     = 2,
 | 
			
		||||
	PUBLISH     = 3,
 | 
			
		||||
	PUBACK      = 4,
 | 
			
		||||
	PUBREC      = 5,
 | 
			
		||||
	PUBREL      = 6,
 | 
			
		||||
	PUBCOMP     = 7,
 | 
			
		||||
	SUBSCRIBE   = 8,
 | 
			
		||||
	SUBACK      = 9,
 | 
			
		||||
	UNSUBSCRIBE = 10,
 | 
			
		||||
	UNSUBACK    = 11,
 | 
			
		||||
	PINGREQ     = 12,
 | 
			
		||||
	PINGRESP    = 13,
 | 
			
		||||
	DISCONNECT  = 14,
 | 
			
		||||
	AUTH        = 15
 | 
			
		||||
} mqtt_control_packet_types;
 | 
			
		||||
 | 
			
		||||
//MQTTV5
 | 
			
		||||
typedef enum {
 | 
			
		||||
	// 0 : V4 1: V5 5: V4 to V5  4: V5 to V4
 | 
			
		||||
	MQTTV4 = 0,
 | 
			
		||||
	MQTTV5 = 1,
 | 
			
		||||
	MQTTV4_V5 = 2,
 | 
			
		||||
	MQTTV5_V4 = 3,
 | 
			
		||||
} target_prover;
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -0,0 +1,152 @@
 | 
			
		||||
 | 
			
		||||
#ifndef NNG_MQTT_H
 | 
			
		||||
#define NNG_MQTT_H
 | 
			
		||||
 | 
			
		||||
#include "nng/supplemental/nanolib/conf.h"
 | 
			
		||||
#include "nng/supplemental/nanolib/hash_table.h"
 | 
			
		||||
#include "nng/mqtt/packet.h"
 | 
			
		||||
#include "mqtt.h"
 | 
			
		||||
#include "nng/supplemental/util/platform.h"
 | 
			
		||||
#include "nng/nng.h"
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
#define PRIu64 "I64u"
 | 
			
		||||
#define PRIu64_FORMAT "%I64u"
 | 
			
		||||
#else
 | 
			
		||||
#include <inttypes.h>
 | 
			
		||||
#define PRIu64_FORMAT "%" PRIu64
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Do not change to %lu! just suppress the warning of the compiler!
 | 
			
		||||
#define DISCONNECT_MSG          \
 | 
			
		||||
	"{\"username\":\"%s\"," \
 | 
			
		||||
	"\"ts\":" PRIu64_FORMAT ",\"reason_code\":\"%x\",\"client_id\":\"%s\",\"IPv4\":\"%s\"}"
 | 
			
		||||
 | 
			
		||||
#define CONNECT_MSG                                                           \
 | 
			
		||||
	"{\"username\":\"%s\", "                                              \
 | 
			
		||||
	"\"ts\":" PRIu64_FORMAT ",\"proto_name\":\"%s\",\"keepalive\":%d,\"return_code\":" \
 | 
			
		||||
	"\"%x\",\"proto_ver\":%d,\"client_id\":\"%s\",\"clean_start\":%d, \"IPv4\":\"%s\"}"
 | 
			
		||||
 | 
			
		||||
#define DISCONNECT_TOPIC "$SYS/brokers/disconnected"
 | 
			
		||||
 | 
			
		||||
#define CONNECT_TOPIC "$SYS/brokers/connected"
 | 
			
		||||
 | 
			
		||||
//Strip off and return the QoS bits
 | 
			
		||||
#define NANO_NNI_LMQ_GET_QOS_BITS(msg) ((size_t) (msg) &0x03)
 | 
			
		||||
 | 
			
		||||
// strip off and return the msg pointer
 | 
			
		||||
#define NANO_NNI_LMQ_GET_MSG_POINTER(msg) \
 | 
			
		||||
	((nng_msg *) ((size_t) (msg) & (~0x03)))
 | 
			
		||||
 | 
			
		||||
// packed QoS bits to the least two significant bits of msg pointer
 | 
			
		||||
#define NANO_NNI_LMQ_PACKED_MSG_QOS(msg, qos) \
 | 
			
		||||
	((nng_msg *) ((size_t) (msg) | ((qos) &0x03)))
 | 
			
		||||
 | 
			
		||||
// Variables & Structs
 | 
			
		||||
typedef struct pub_extra pub_extra;
 | 
			
		||||
 | 
			
		||||
// int hex_to_oct(char *str);
 | 
			
		||||
// uint32_t htoi(char *str);
 | 
			
		||||
 | 
			
		||||
NNG_DECL pub_extra *pub_extra_alloc(pub_extra *);
 | 
			
		||||
NNG_DECL void       pub_extra_free(pub_extra *);
 | 
			
		||||
NNG_DECL uint8_t    pub_extra_get_qos(pub_extra *);
 | 
			
		||||
NNG_DECL uint16_t   pub_extra_get_packet_id(pub_extra *);
 | 
			
		||||
NNG_DECL void       pub_extra_set_qos(pub_extra *, uint8_t);
 | 
			
		||||
NNG_DECL void      *pub_extra_get_msg(pub_extra *);
 | 
			
		||||
NNG_DECL void       pub_extra_set_msg(pub_extra *, void *);
 | 
			
		||||
NNG_DECL void       pub_extra_set_packet_id(pub_extra *, uint16_t);
 | 
			
		||||
 | 
			
		||||
// MQTT CONNECT
 | 
			
		||||
NNG_DECL int32_t conn_handler(uint8_t *packet, conn_param *conn_param, size_t max);
 | 
			
		||||
NNG_DECL int     conn_param_alloc(conn_param **cparam);
 | 
			
		||||
NNG_DECL void    conn_param_free(conn_param *cparam);
 | 
			
		||||
NNG_DECL void    conn_param_clone(conn_param *cparam);
 | 
			
		||||
NNG_DECL int     ws_msg_adaptor(uint8_t *packet, nng_msg *dst);
 | 
			
		||||
 | 
			
		||||
// parser
 | 
			
		||||
NNG_DECL uint8_t put_var_integer(uint8_t *dest, uint32_t value);
 | 
			
		||||
 | 
			
		||||
NNG_DECL uint32_t get_var_integer(const uint8_t *buf, uint8_t *pos);
 | 
			
		||||
 | 
			
		||||
NNG_DECL int32_t get_utf8_str(
 | 
			
		||||
    char **dest, const uint8_t *src, uint32_t *pos, size_t max);
 | 
			
		||||
NNG_DECL uint8_t *copy_utf8_str(
 | 
			
		||||
    const uint8_t *src, uint32_t *pos, int *str_len);
 | 
			
		||||
NNG_DECL uint8_t *copyn_utf8_str(
 | 
			
		||||
    const uint8_t *src, uint32_t *pos, int *str_len, int limit);
 | 
			
		||||
 | 
			
		||||
// NNG_DECL char *convert_to_utf8(char *src, char *format, size_t *len);
 | 
			
		||||
NNG_DECL uint8_t *copyn_str(
 | 
			
		||||
    const uint8_t *src, uint32_t *pos, int *str_len, int limit);
 | 
			
		||||
 | 
			
		||||
NNG_DECL int utf8_check(const char *str, size_t length);
 | 
			
		||||
 | 
			
		||||
NNG_DECL uint16_t get_variable_binary(uint8_t **dest, const uint8_t *src);
 | 
			
		||||
 | 
			
		||||
NNG_DECL uint32_t DJBHash(char *str);
 | 
			
		||||
NNG_DECL uint32_t DJBHashn(char *str, uint16_t len);
 | 
			
		||||
NNG_DECL uint64_t DJBHash64(char *str);
 | 
			
		||||
NNG_DECL uint64_t DJBHash64n(uint8_t* str, uint32_t len);
 | 
			
		||||
NNG_DECL uint32_t fnv1a_hashn(char *str, size_t n);
 | 
			
		||||
NNG_DECL uint8_t  crc_hashn(char *str, size_t n);
 | 
			
		||||
NNG_DECL uint32_t crc32_hashn(char *str, size_t n);
 | 
			
		||||
NNG_DECL uint32_t crc32c_hashn(char *str, size_t n);
 | 
			
		||||
NNG_DECL uint8_t  verify_connect(conn_param *cparam, conf *conf);
 | 
			
		||||
 | 
			
		||||
// repack
 | 
			
		||||
NNG_DECL void nano_msg_set_dup(nng_msg *msg);
 | 
			
		||||
NNG_DECL nng_msg *nano_pubmsg_composer(nng_msg **, uint8_t retain, uint8_t qos,
 | 
			
		||||
    mqtt_string *payload, mqtt_string *topic, uint8_t proto_ver,
 | 
			
		||||
    nng_time time);
 | 
			
		||||
NNG_DECL nng_msg *nano_dismsg_composer(
 | 
			
		||||
    reason_code code, char *rstr, uint8_t *ref, property *prop);
 | 
			
		||||
NNG_DECL nng_msg *nano_msg_notify_disconnect(conn_param *cparam, uint8_t code);
 | 
			
		||||
NNG_DECL nng_msg *nano_msg_notify_connect(conn_param *cparam, uint8_t code);
 | 
			
		||||
NNG_DECL nano_pipe_db *nano_msg_get_subtopic(
 | 
			
		||||
    nng_msg *msg, nano_pipe_db *root, conn_param *cparam);
 | 
			
		||||
NNG_DECL void nano_msg_free_pipedb(nano_pipe_db *db);
 | 
			
		||||
NNG_DECL void nano_msg_ubsub_free(nano_pipe_db *db);
 | 
			
		||||
NNG_DECL void nmq_connack_encode(
 | 
			
		||||
    nng_msg *msg, conn_param *cparam, uint8_t reason);
 | 
			
		||||
NNG_DECL void nmq_connack_session(nng_msg *msg, bool session);
 | 
			
		||||
// TODO : check duplicated declaration
 | 
			
		||||
NNG_DECL reason_code check_properties(property *prop, nng_msg *msg);
 | 
			
		||||
NNG_DECL property *decode_buf_properties(uint8_t *packet, uint32_t packet_len,
 | 
			
		||||
    uint32_t *pos, uint32_t *len, bool copy_value);
 | 
			
		||||
NNG_DECL property *decode_properties(
 | 
			
		||||
    nng_msg *msg, uint32_t *pos, uint32_t *len, bool copy_value);
 | 
			
		||||
NNG_DECL int      encode_properties(nng_msg *msg, property *prop, uint8_t cmd);
 | 
			
		||||
NNG_DECL int      property_free(property *prop);
 | 
			
		||||
NNG_DECL property_data *property_get_value(property *prop, uint8_t prop_id);
 | 
			
		||||
NNG_DECL void      property_foreach(property *prop, void (*cb)(property *));
 | 
			
		||||
NNG_DECL int       property_dup(property **dup, const property *src);
 | 
			
		||||
NNG_DECL property *property_pub_by_will(property *will_prop);
 | 
			
		||||
 | 
			
		||||
NNG_DECL property          *property_alloc(void);
 | 
			
		||||
NNG_DECL property_type_enum property_get_value_type(uint8_t prop_id);
 | 
			
		||||
NNG_DECL property *property_set_value_u8(uint8_t prop_id, uint8_t value);
 | 
			
		||||
NNG_DECL property *property_set_value_u16(uint8_t prop_id, uint16_t value);
 | 
			
		||||
NNG_DECL property *property_set_value_u32(uint8_t prop_id, uint32_t value);
 | 
			
		||||
NNG_DECL property *property_set_value_varint(uint8_t prop_id, uint32_t value);
 | 
			
		||||
NNG_DECL property *property_set_value_binary(
 | 
			
		||||
    uint8_t prop_id, uint8_t *value, uint32_t len, bool copy_value);
 | 
			
		||||
NNG_DECL property *property_set_value_str(
 | 
			
		||||
    uint8_t prop_id, const char *value, uint32_t len, bool copy_value);
 | 
			
		||||
NNG_DECL property *property_set_value_strpair(uint8_t prop_id, const char *key,
 | 
			
		||||
    uint32_t key_len, const char *value, uint32_t value_len, bool copy_value);
 | 
			
		||||
NNG_DECL void      property_append(property *prop_list, property *last);
 | 
			
		||||
 | 
			
		||||
NNG_DECL int  nmq_subtopic_decode(nng_msg *msg, uint8_t ver, topic_queue **ptq);
 | 
			
		||||
NNG_DECL int  nmq_subinfo_decode(nng_msg *msg, void *l, uint8_t ver);
 | 
			
		||||
NNG_DECL int  nmq_unsubinfo_decode(nng_msg *msg, void *l, uint8_t ver);
 | 
			
		||||
NNG_DECL bool topic_filter(const char *origin, const char *input);
 | 
			
		||||
NNG_DECL bool topic_filtern(const char *origin, const char *input, size_t n);
 | 
			
		||||
 | 
			
		||||
NNG_DECL int nmq_auth_http_connect(conn_param *cparam, conf_auth_http *conf);
 | 
			
		||||
 | 
			
		||||
NNG_DECL int nmq_auth_http_sub_pub(
 | 
			
		||||
    conn_param *cparam, bool is_sub, topic_queue *topics, conf_auth_http *conf);
 | 
			
		||||
 | 
			
		||||
#endif // NNG_MQTT_H
 | 
			
		||||
@@ -0,0 +1,35 @@
 | 
			
		||||
//
 | 
			
		||||
// 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.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#ifndef NNG_PROTOCOL_MQTT_BROKER_H
 | 
			
		||||
#define NNG_PROTOCOL_MQTT_BROKER_H
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
NNG_DECL int nng_nmq_tcp0_open(nng_socket *);
 | 
			
		||||
 | 
			
		||||
#ifndef nng_nmq_tcp_open
 | 
			
		||||
#define nng_nmq_tcp_open nng_nmq_tcp0_open
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define NNG_NMQ_TCP_SELF 0x31
 | 
			
		||||
#define NNG_NMQ_TCP_PEER 0x30
 | 
			
		||||
#define NNG_NMQ_TCP_SELF_NAME "nmq_broker"
 | 
			
		||||
#define NNG_NMQ_TCP_PEER_NAME "nmq_client"
 | 
			
		||||
 | 
			
		||||
#define NMQ_OPT_MQTT_PIPES "mqtt-clients-pipes"
 | 
			
		||||
#define NMQ_OPT_MQTT_QOS_DB "mqtt-clients-qos-db"
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // NNG_PROTOCOL_MQTT_BROKER_H
 | 
			
		||||
@@ -0,0 +1,34 @@
 | 
			
		||||
//
 | 
			
		||||
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
 | 
			
		||||
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
 | 
			
		||||
//
 | 
			
		||||
// 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 NNG_PROTOCOL_PAIR0_PAIR_H
 | 
			
		||||
#define NNG_PROTOCOL_PAIR0_PAIR_H
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
NNG_DECL int nng_pair0_open(nng_socket *);
 | 
			
		||||
 | 
			
		||||
NNG_DECL int nng_pair0_open_raw(nng_socket *);
 | 
			
		||||
 | 
			
		||||
#ifndef nng_pair_open
 | 
			
		||||
#define nng_pair_open nng_pair0_open
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef nng_pair_open_raw
 | 
			
		||||
#define nng_pair_open_raw nng_pair0_open_raw
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // NNG_PROTOCOL_PAIR0_PAIR_H
 | 
			
		||||
@@ -0,0 +1,40 @@
 | 
			
		||||
//
 | 
			
		||||
// Copyright 2020 Staysail Systems, Inc. <info@staysail.tech>
 | 
			
		||||
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
 | 
			
		||||
//
 | 
			
		||||
// 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 NNG_PROTOCOL_PAIR1_PAIR_H
 | 
			
		||||
#define NNG_PROTOCOL_PAIR1_PAIR_H
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
NNG_DECL int nng_pair1_open(nng_socket *);
 | 
			
		||||
NNG_DECL int nng_pair1_open_raw(nng_socket *);
 | 
			
		||||
NNG_DECL int nng_pair1_open_poly(nng_socket *);
 | 
			
		||||
 | 
			
		||||
#ifndef nng_pair_open
 | 
			
		||||
#define nng_pair_open nng_pair1_open
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef nng_pair_open_raw
 | 
			
		||||
#define nng_pair_open_raw nng_pair1_open_raw
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define NNG_OPT_PAIR1_POLY "pair1:polyamorous"
 | 
			
		||||
#define NNG_PAIR1_SELF 0x11
 | 
			
		||||
#define NNG_PAIR1_PEER 0x11
 | 
			
		||||
#define NNG_PAIR1_SELF_NAME "pair1"
 | 
			
		||||
#define NNG_PAIR1_PEER_NAME "pair1"
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // NNG_PROTOCOL_PAIR1_PAIR_H
 | 
			
		||||
@@ -0,0 +1,33 @@
 | 
			
		||||
//
 | 
			
		||||
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
 | 
			
		||||
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
 | 
			
		||||
//
 | 
			
		||||
// 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 NNG_PROTOCOL_PIPELINE0_PULL_H
 | 
			
		||||
#define NNG_PROTOCOL_PIPELINE0_PULL_H
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
NNG_DECL int nng_pull0_open(nng_socket *);
 | 
			
		||||
NNG_DECL int nng_pull0_open_raw(nng_socket *);
 | 
			
		||||
 | 
			
		||||
#ifndef nng_pull_open
 | 
			
		||||
#define nng_pull_open nng_pull0_open
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef nng_pull_open_raw
 | 
			
		||||
#define nng_pull_open_raw nng_pull0_open_raw
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // NNG_PROTOCOL_PIPELINE0_PULL_H
 | 
			
		||||
@@ -0,0 +1,33 @@
 | 
			
		||||
//
 | 
			
		||||
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
 | 
			
		||||
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
 | 
			
		||||
//
 | 
			
		||||
// 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 NNG_PROTOCOL_PIPELINE0_PUSH_H
 | 
			
		||||
#define NNG_PROTOCOL_PIPELINE0_PUSH_H
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
NNG_DECL int nng_push0_open(nng_socket *);
 | 
			
		||||
NNG_DECL int nng_push0_open_raw(nng_socket *);
 | 
			
		||||
 | 
			
		||||
#ifndef nng_push_open
 | 
			
		||||
#define nng_push_open nng_push0_open
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef nng_push_open_raw
 | 
			
		||||
#define nng_push_open_raw nng_push0_open_raw
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // NNG_PROTOCOL_PIPELINE0_PUSH_H
 | 
			
		||||
@@ -0,0 +1,33 @@
 | 
			
		||||
//
 | 
			
		||||
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
 | 
			
		||||
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
 | 
			
		||||
//
 | 
			
		||||
// 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 NNG_PROTOCOL_PUBSUB0_PUB_H
 | 
			
		||||
#define NNG_PROTOCOL_PUBSUB0_PUB_H
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
NNG_DECL int nng_pub0_open(nng_socket *);
 | 
			
		||||
NNG_DECL int nng_pub0_open_raw(nng_socket *);
 | 
			
		||||
 | 
			
		||||
#ifndef nng_pub_open
 | 
			
		||||
#define nng_pub_open nng_pub0_open
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef nng_pub_open_raw
 | 
			
		||||
#define nng_pub_open_raw nng_pub0_open_raw
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // NNG_PROTOCOL_PUBSUB0_PUB_H
 | 
			
		||||
@@ -0,0 +1,39 @@
 | 
			
		||||
//
 | 
			
		||||
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
 | 
			
		||||
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
 | 
			
		||||
//
 | 
			
		||||
// 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 NNG_PROTOCOL_PUBSUB0_SUB_H
 | 
			
		||||
#define NNG_PROTOCOL_PUBSUB0_SUB_H
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
NNG_DECL int nng_sub0_open(nng_socket *);
 | 
			
		||||
 | 
			
		||||
NNG_DECL int nng_sub0_open_raw(nng_socket *);
 | 
			
		||||
 | 
			
		||||
#ifndef nng_sub_open
 | 
			
		||||
#define nng_sub_open nng_sub0_open
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef nng_sub_open_raw
 | 
			
		||||
#define nng_sub_open_raw nng_sub0_open_raw
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define NNG_OPT_SUB_SUBSCRIBE "sub:subscribe"
 | 
			
		||||
#define NNG_OPT_SUB_UNSUBSCRIBE "sub:unsubscribe"
 | 
			
		||||
 | 
			
		||||
#define NNG_OPT_SUB_PREFNEW "sub:prefnew"
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // NNG_PROTOCOL_PUBSUB0_SUB_H
 | 
			
		||||
@@ -0,0 +1,38 @@
 | 
			
		||||
//
 | 
			
		||||
// Copyright 2020 Staysail Systems, Inc. <info@staysail.tech>
 | 
			
		||||
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
 | 
			
		||||
//
 | 
			
		||||
// 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 NNG_PROTOCOL_REQREP0_REP_H
 | 
			
		||||
#define NNG_PROTOCOL_REQREP0_REP_H
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
NNG_DECL int nng_rep0_open(nng_socket *);
 | 
			
		||||
NNG_DECL int nng_rep0_open_raw(nng_socket *);
 | 
			
		||||
 | 
			
		||||
#ifndef nng_rep_open
 | 
			
		||||
#define nng_rep_open nng_rep0_open
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef nng_rep_open_raw
 | 
			
		||||
#define nng_rep_open_raw nng_rep0_open_raw
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define NNG_REP0_SELF 0x31
 | 
			
		||||
#define NNG_REP0_PEER 0x30
 | 
			
		||||
#define NNG_REP0_SELF_NAME "rep"
 | 
			
		||||
#define NNG_REP0_PEER_NAME "req"
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // NNG_PROTOCOL_REQREP0_REP_H
 | 
			
		||||
@@ -0,0 +1,40 @@
 | 
			
		||||
//
 | 
			
		||||
// Copyright 2020 Staysail Systems, Inc. <info@staysail.tech>
 | 
			
		||||
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
 | 
			
		||||
//
 | 
			
		||||
// 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 NNG_PROTOCOL_REQREP0_REQ_H
 | 
			
		||||
#define NNG_PROTOCOL_REQREP0_REQ_H
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
NNG_DECL int nng_req0_open(nng_socket *);
 | 
			
		||||
NNG_DECL int nng_req0_open_raw(nng_socket *);
 | 
			
		||||
 | 
			
		||||
#ifndef nng_req_open
 | 
			
		||||
#define nng_req_open nng_req0_open
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef nng_req_open_raw
 | 
			
		||||
#define nng_req_open_raw nng_req0_open_raw
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define NNG_REQ0_SELF 0x30
 | 
			
		||||
#define NNG_REQ0_PEER 0x31
 | 
			
		||||
#define NNG_REQ0_SELF_NAME "req"
 | 
			
		||||
#define NNG_REQ0_PEER_NAME "rep"
 | 
			
		||||
 | 
			
		||||
#define NNG_OPT_REQ_RESENDTIME "req:resend-time"
 | 
			
		||||
#define NNG_OPT_REQ_RESENDTICK "req:resend-tick"
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // NNG_PROTOCOL_REQREP0_REQ_H
 | 
			
		||||
@@ -0,0 +1,38 @@
 | 
			
		||||
//
 | 
			
		||||
// Copyright 2020 Staysail Systems, Inc. <info@staysail.tech>
 | 
			
		||||
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
 | 
			
		||||
//
 | 
			
		||||
// 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 NNG_PROTOCOL_SURVEY0_RESPOND_H
 | 
			
		||||
#define NNG_PROTOCOL_SURVEY0_RESPOND_H
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
NNG_DECL int nng_respondent0_open(nng_socket *);
 | 
			
		||||
NNG_DECL int nng_respondent0_open_raw(nng_socket *);
 | 
			
		||||
 | 
			
		||||
#ifndef nng_respondent_open
 | 
			
		||||
#define nng_respondent_open nng_respondent0_open
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef nng_respondent_open_raw
 | 
			
		||||
#define nng_respondent_open_raw nng_respondent0_open_raw
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define NNG_RESPONDENT0_SELF 0x63
 | 
			
		||||
#define NNG_RESPONDENT0_PEER 0x62
 | 
			
		||||
#define NNG_RESPONDENT0_SELF_NAME "respondent"
 | 
			
		||||
#define NNG_RESPONDENT0_PEER_NAME "surveyor"
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // NNG_PROTOCOL_SURVEY0_RESPOND_H
 | 
			
		||||
@@ -0,0 +1,40 @@
 | 
			
		||||
//
 | 
			
		||||
// Copyright 2020 Staysail Systems, Inc. <info@staysail.tech>
 | 
			
		||||
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
 | 
			
		||||
//
 | 
			
		||||
// 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 NNG_PROTOCOL_SURVEY0_SURVEY_H
 | 
			
		||||
#define NNG_PROTOCOL_SURVEY0_SURVEY_H
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
NNG_DECL int nng_surveyor0_open(nng_socket *);
 | 
			
		||||
NNG_DECL int nng_surveyor0_open_raw(nng_socket *);
 | 
			
		||||
 | 
			
		||||
#ifndef nng_surveyor_open
 | 
			
		||||
#define nng_surveyor_open nng_surveyor0_open
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef nng_surveyor_open_raw
 | 
			
		||||
#define nng_surveyor_open_raw nng_surveyor0_open_raw
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define NNG_SURVEYOR0_SELF 0x62
 | 
			
		||||
#define NNG_SURVEYOR0_PEER 0x63
 | 
			
		||||
#define NNG_SURVEYOR0_SELF_NAME "surveyor"
 | 
			
		||||
#define NNG_SURVEYOR0_PEER_NAME "respondent"
 | 
			
		||||
 | 
			
		||||
#define NNG_OPT_SURVEYOR_SURVEYTIME "surveyor:survey-time"
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // NNG_PROTOCOL_SURVEY0_SURVEY_H
 | 
			
		||||
@@ -0,0 +1,539 @@
 | 
			
		||||
//
 | 
			
		||||
// Copyright 2020 Staysail Systems, Inc. <info@staysail.tech>
 | 
			
		||||
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
 | 
			
		||||
// Copyright 2020 Dirac Research <robert.bielik@dirac.com>
 | 
			
		||||
//
 | 
			
		||||
// 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 NNG_SUPPLEMENTAL_HTTP_HTTP_H
 | 
			
		||||
#define NNG_SUPPLEMENTAL_HTTP_HTTP_H
 | 
			
		||||
 | 
			
		||||
// HTTP API.  Only present if HTTP support compiled into the library.
 | 
			
		||||
// Functions will return NNG_ENOTSUP (or NULL or 0 as appropriate)
 | 
			
		||||
// if the library lacks support for HTTP.
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
struct nng_tls_config;
 | 
			
		||||
 | 
			
		||||
// HTTP status codes.  This list is not exhaustive.
 | 
			
		||||
enum nng_http_status {
 | 
			
		||||
	NNG_HTTP_STATUS_CONTINUE                 = 100,
 | 
			
		||||
	NNG_HTTP_STATUS_SWITCHING                = 101,
 | 
			
		||||
	NNG_HTTP_STATUS_PROCESSING               = 102,
 | 
			
		||||
	NNG_HTTP_STATUS_OK                       = 200,
 | 
			
		||||
	NNG_HTTP_STATUS_CREATED                  = 201,
 | 
			
		||||
	NNG_HTTP_STATUS_ACCEPTED                 = 202,
 | 
			
		||||
	NNG_HTTP_STATUS_NOT_AUTHORITATIVE        = 203,
 | 
			
		||||
	NNG_HTTP_STATUS_NO_CONTENT               = 204,
 | 
			
		||||
	NNG_HTTP_STATUS_RESET_CONTENT            = 205,
 | 
			
		||||
	NNG_HTTP_STATUS_PARTIAL_CONTENT          = 206,
 | 
			
		||||
	NNG_HTTP_STATUS_MULTI_STATUS             = 207,
 | 
			
		||||
	NNG_HTTP_STATUS_ALREADY_REPORTED         = 208,
 | 
			
		||||
	NNG_HTTP_STATUS_IM_USED                  = 226,
 | 
			
		||||
	NNG_HTTP_STATUS_MULTIPLE_CHOICES         = 300,
 | 
			
		||||
	NNG_HTTP_STATUS_STATUS_MOVED_PERMANENTLY = 301,
 | 
			
		||||
	NNG_HTTP_STATUS_FOUND                    = 302,
 | 
			
		||||
	NNG_HTTP_STATUS_SEE_OTHER                = 303,
 | 
			
		||||
	NNG_HTTP_STATUS_NOT_MODIFIED             = 304,
 | 
			
		||||
	NNG_HTTP_STATUS_USE_PROXY                = 305,
 | 
			
		||||
	NNG_HTTP_STATUS_TEMPORARY_REDIRECT       = 307,
 | 
			
		||||
	NNG_HTTP_STATUS_PERMANENT_REDIRECT       = 308,
 | 
			
		||||
	NNG_HTTP_STATUS_BAD_REQUEST              = 400,
 | 
			
		||||
	NNG_HTTP_STATUS_UNAUTHORIZED             = 401,
 | 
			
		||||
	NNG_HTTP_STATUS_PAYMENT_REQUIRED         = 402,
 | 
			
		||||
	NNG_HTTP_STATUS_FORBIDDEN                = 403,
 | 
			
		||||
	NNG_HTTP_STATUS_NOT_FOUND                = 404,
 | 
			
		||||
	NNG_HTTP_STATUS_METHOD_NOT_ALLOWED       = 405,
 | 
			
		||||
	NNG_HTTP_STATUS_NOT_ACCEPTABLE           = 406,
 | 
			
		||||
	NNG_HTTP_STATUS_PROXY_AUTH_REQUIRED      = 407,
 | 
			
		||||
	NNG_HTTP_STATUS_REQUEST_TIMEOUT          = 408,
 | 
			
		||||
	NNG_HTTP_STATUS_CONFLICT                 = 409,
 | 
			
		||||
	NNG_HTTP_STATUS_GONE                     = 410,
 | 
			
		||||
	NNG_HTTP_STATUS_LENGTH_REQUIRED          = 411,
 | 
			
		||||
	NNG_HTTP_STATUS_PRECONDITION_FAILED      = 412,
 | 
			
		||||
	NNG_HTTP_STATUS_PAYLOAD_TOO_LARGE        = 413,
 | 
			
		||||
	NNG_HTTP_STATUS_ENTITY_TOO_LONG          = 414,
 | 
			
		||||
	NNG_HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE   = 415,
 | 
			
		||||
	NNG_HTTP_STATUS_RANGE_NOT_SATISFIABLE    = 416,
 | 
			
		||||
	NNG_HTTP_STATUS_EXPECTATION_FAILED       = 417,
 | 
			
		||||
	NNG_HTTP_STATUS_TEAPOT                   = 418,
 | 
			
		||||
	NNG_HTTP_STATUS_UNPROCESSABLE_ENTITY     = 422,
 | 
			
		||||
	NNG_HTTP_STATUS_LOCKED                   = 423,
 | 
			
		||||
	NNG_HTTP_STATUS_FAILED_DEPENDENCY        = 424,
 | 
			
		||||
	NNG_HTTP_STATUS_UPGRADE_REQUIRED         = 426,
 | 
			
		||||
	NNG_HTTP_STATUS_PRECONDITION_REQUIRED    = 428,
 | 
			
		||||
	NNG_HTTP_STATUS_TOO_MANY_REQUESTS        = 429,
 | 
			
		||||
	NNG_HTTP_STATUS_HEADERS_TOO_LARGE        = 431,
 | 
			
		||||
	NNG_HTTP_STATUS_UNAVAIL_LEGAL_REASONS    = 451,
 | 
			
		||||
	NNG_HTTP_STATUS_INTERNAL_SERVER_ERROR    = 500,
 | 
			
		||||
	NNG_HTTP_STATUS_NOT_IMPLEMENTED          = 501,
 | 
			
		||||
	NNG_HTTP_STATUS_BAD_GATEWAY              = 502,
 | 
			
		||||
	NNG_HTTP_STATUS_SERVICE_UNAVAILABLE      = 503,
 | 
			
		||||
	NNG_HTTP_STATUS_GATEWAY_TIMEOUT          = 504,
 | 
			
		||||
	NNG_HTTP_STATUS_HTTP_VERSION_NOT_SUPP    = 505,
 | 
			
		||||
	NNG_HTTP_STATUS_VARIANT_ALSO_NEGOTIATES  = 506,
 | 
			
		||||
	NNG_HTTP_STATUS_INSUFFICIENT_STORAGE     = 507,
 | 
			
		||||
	NNG_HTTP_STATUS_LOOP_DETECTED            = 508,
 | 
			
		||||
	NNG_HTTP_STATUS_NOT_EXTENDED             = 510,
 | 
			
		||||
	NNG_HTTP_STATUS_NETWORK_AUTH_REQUIRED    = 511,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// nng_http_req represents an HTTP request.
 | 
			
		||||
typedef struct nng_http_req nng_http_req;
 | 
			
		||||
 | 
			
		||||
// nng_http_req_alloc creates a vanilla HTTP request object.  The object is
 | 
			
		||||
// initialized with the given URL object for an HTTP/1.1 GET request by
 | 
			
		||||
// default. It also adds the Host: header required for HTTP/1.1.  If the
 | 
			
		||||
// url is NULL, then the uri and Host: header are uninitialized, and will
 | 
			
		||||
// need to be set explicitly.
 | 
			
		||||
NNG_DECL int nng_http_req_alloc(nng_http_req **, const nng_url *);
 | 
			
		||||
 | 
			
		||||
// nng_http_req_free frees an HTTP request object.
 | 
			
		||||
NNG_DECL void nng_http_req_free(nng_http_req *);
 | 
			
		||||
 | 
			
		||||
// nng_http_req_get_method returns the method.
 | 
			
		||||
NNG_DECL const char *nng_http_req_get_method(nng_http_req *);
 | 
			
		||||
 | 
			
		||||
// nng_http_req_get_version returns the version, usually HTTP/1.1.
 | 
			
		||||
NNG_DECL const char *nng_http_req_get_version(nng_http_req *);
 | 
			
		||||
 | 
			
		||||
// nng_http_req_get_uri returns the "abs-uri", which is URL without
 | 
			
		||||
// the scheme, host, or port.
 | 
			
		||||
NNG_DECL const char *nng_http_req_get_uri(nng_http_req *);
 | 
			
		||||
 | 
			
		||||
// nng_http_req_set_header sets an HTTP header, replacing any previous value
 | 
			
		||||
// that might have been present.
 | 
			
		||||
NNG_DECL int nng_http_req_set_header(
 | 
			
		||||
    nng_http_req *, const char *, const char *);
 | 
			
		||||
 | 
			
		||||
// nng_http_req_add_header adds an HTTP header, without disrupting any other
 | 
			
		||||
// with the same name that might have been present.
 | 
			
		||||
NNG_DECL int nng_http_req_add_header(
 | 
			
		||||
    nng_http_req *, const char *, const char *);
 | 
			
		||||
 | 
			
		||||
// nng_http_req_del_header deletes all occurrences of a named header.
 | 
			
		||||
NNG_DECL int nng_http_req_del_header(nng_http_req *, const char *);
 | 
			
		||||
 | 
			
		||||
// nng_http_req_get_header looks up a header with the named, returns NULL
 | 
			
		||||
// if not found.
 | 
			
		||||
NNG_DECL const char *nng_http_req_get_header(nng_http_req *, const char *);
 | 
			
		||||
 | 
			
		||||
// nng_http_req_set_method is used to change the method of a request.
 | 
			
		||||
// The method should be an upper case HTTP method, like POST, or DELETE.
 | 
			
		||||
// Null sets the default ("GET").
 | 
			
		||||
NNG_DECL int nng_http_req_set_method(nng_http_req *, const char *);
 | 
			
		||||
 | 
			
		||||
// nng_http_req_set_version is used to change the version of a request.
 | 
			
		||||
// Normally the version is "HTTP/1.1".  Note that the framework does
 | 
			
		||||
// not support HTTP/2 at all.  Null sets the default ("HTTP/1.1").
 | 
			
		||||
NNG_DECL int nng_http_req_set_version(nng_http_req *, const char *);
 | 
			
		||||
 | 
			
		||||
// nng_http_req_set_uri is used to change the URI of a request.  This
 | 
			
		||||
// should be an "abs-uri", that is a path, plus query and fragment if
 | 
			
		||||
// needed.  The scheme, host, and port don't belong here.  The URI should
 | 
			
		||||
// start with a leading '/' per HTTP.
 | 
			
		||||
NNG_DECL int nng_http_req_set_uri(nng_http_req *, const char *);
 | 
			
		||||
 | 
			
		||||
// nng_http_req_set_data adds entity data to the request.  The
 | 
			
		||||
// data object must persist (so only really useful for static data).
 | 
			
		||||
// The content-length header is updated as well, but the caller should
 | 
			
		||||
// probably set the content-type header.
 | 
			
		||||
NNG_DECL int nng_http_req_set_data(nng_http_req *, const void *, size_t);
 | 
			
		||||
 | 
			
		||||
// nng_http_req_copy_data adds entity data to the response. A private
 | 
			
		||||
// copy of the data is made (will be freed with the request).
 | 
			
		||||
// The content-length header is updated as well, but the caller should
 | 
			
		||||
// probably set the content-type header.
 | 
			
		||||
NNG_DECL int nng_http_req_copy_data(nng_http_req *, const void *, size_t);
 | 
			
		||||
 | 
			
		||||
// nng_http_req_get_data gets the data for the response.
 | 
			
		||||
NNG_DECL void nng_http_req_get_data(nng_http_req *, void **, size_t *);
 | 
			
		||||
 | 
			
		||||
// nng_http_res represents an HTTP response.
 | 
			
		||||
typedef struct nng_http_res nng_http_res;
 | 
			
		||||
 | 
			
		||||
// nng_http_res_alloc creates a vanilla HTTP response object.  The object is
 | 
			
		||||
// initialized for an HTTP/1.1 200 OK response by default.
 | 
			
		||||
NNG_DECL int nng_http_res_alloc(nng_http_res **);
 | 
			
		||||
 | 
			
		||||
// nng_http_res_alloc_error creates an error HTTP response object.  The object
 | 
			
		||||
// is initialized for an HTTP/1.1 response, and contains an associated
 | 
			
		||||
// generic HTML error page.
 | 
			
		||||
NNG_DECL int nng_http_res_alloc_error(nng_http_res **, uint16_t);
 | 
			
		||||
 | 
			
		||||
// nng_http_res_free frees an HTTP response object.
 | 
			
		||||
NNG_DECL void nng_http_res_free(nng_http_res *);
 | 
			
		||||
 | 
			
		||||
// nng_http_res_get_status returns the HTTP status code from the server.
 | 
			
		||||
NNG_DECL uint16_t nng_http_res_get_status(nng_http_res *);
 | 
			
		||||
 | 
			
		||||
// nng_http_res_set_status sets the HTTP status code.
 | 
			
		||||
NNG_DECL int nng_http_res_set_status(nng_http_res *, uint16_t);
 | 
			
		||||
 | 
			
		||||
// nng_http_res_get_reason returns the human readable status message
 | 
			
		||||
// that the server responds (or responded) with.
 | 
			
		||||
NNG_DECL const char *nng_http_res_get_reason(nng_http_res *);
 | 
			
		||||
 | 
			
		||||
// nng_http_res_set_reason sets the human readable status message.
 | 
			
		||||
// NULL means that a default reason is used based on the status code.
 | 
			
		||||
NNG_DECL int nng_http_res_set_reason(nng_http_res *, const char *);
 | 
			
		||||
 | 
			
		||||
// nng_http_res_set_header sets an HTTP header, replacing any previous value
 | 
			
		||||
// that might have been present.
 | 
			
		||||
NNG_DECL int nng_http_res_set_header(
 | 
			
		||||
    nng_http_res *, const char *, const char *);
 | 
			
		||||
 | 
			
		||||
// nng_http_res_add_header adds an HTTP header, without disrupting any other
 | 
			
		||||
// with the same name that might have been present.
 | 
			
		||||
NNG_DECL int nng_http_res_add_header(
 | 
			
		||||
    nng_http_res *, const char *, const char *);
 | 
			
		||||
 | 
			
		||||
// nng_http_res_del_header deletes all occurrences of a named header.
 | 
			
		||||
NNG_DECL int nng_http_res_del_header(nng_http_res *, const char *);
 | 
			
		||||
 | 
			
		||||
// nng_http_res_get_header looks up a header with the named, returns NULL
 | 
			
		||||
// if not found.
 | 
			
		||||
NNG_DECL const char *nng_http_res_get_header(nng_http_res *, const char *);
 | 
			
		||||
 | 
			
		||||
// nng_http_res_set_version is used to change the version of a response.
 | 
			
		||||
// Normally the version is "HTTP/1.1".  Note that the framework does
 | 
			
		||||
// not support HTTP/2 at all.  NULL sets the default ("HTTP/1.1").
 | 
			
		||||
NNG_DECL int nng_http_res_set_version(nng_http_res *, const char *);
 | 
			
		||||
 | 
			
		||||
// nng_http_res_get_version returns the version, usually HTTP/1.1.
 | 
			
		||||
NNG_DECL const char *nng_http_res_get_version(nng_http_res *);
 | 
			
		||||
 | 
			
		||||
// nng_http_res_get_data gets the data for the response.
 | 
			
		||||
NNG_DECL void nng_http_res_get_data(nng_http_res *, void **, size_t *);
 | 
			
		||||
 | 
			
		||||
// nng_http_res_set_data adds entity data to the response.  The
 | 
			
		||||
// data object must persist (so only really useful for static data).
 | 
			
		||||
// The content-length header is updated as well, but the caller should
 | 
			
		||||
// probably set the content-type header.
 | 
			
		||||
NNG_DECL int nng_http_res_set_data(nng_http_res *, const void *, size_t);
 | 
			
		||||
 | 
			
		||||
// nng_http_res_copy_data adds entity data to the response. A private
 | 
			
		||||
// copy of the data is made (will be freed with the request).
 | 
			
		||||
// The content-length header is updated as well, but the caller should
 | 
			
		||||
// probably set the content-type header.
 | 
			
		||||
NNG_DECL int nng_http_res_copy_data(nng_http_res *, const void *, size_t);
 | 
			
		||||
 | 
			
		||||
// An nng_http_conn represents an underlying "connection".  It may be
 | 
			
		||||
// a TCP channel, or a TLS channel, but the main thing is that this is
 | 
			
		||||
// normally only used for exchanging HTTP requests and responses.
 | 
			
		||||
typedef struct nng_http_conn nng_http_conn;
 | 
			
		||||
 | 
			
		||||
// nng_http_conn_close closes the underlying channel.  Applications should
 | 
			
		||||
// not use this channel after this operation is performed.
 | 
			
		||||
NNG_DECL void nng_http_conn_close(nng_http_conn *);
 | 
			
		||||
 | 
			
		||||
// nng_http_conn_read attempts to read data from the connection.  This
 | 
			
		||||
// completes as soon as at least one byte is read; it does not wait
 | 
			
		||||
// for the entire aio to be filled.
 | 
			
		||||
NNG_DECL void nng_http_conn_read(nng_http_conn *, nng_aio *);
 | 
			
		||||
 | 
			
		||||
// nng_http_conn_read_all is like nng_http_conn_read, but it does not
 | 
			
		||||
// finish until either all the requested data is read, or an error occurs.
 | 
			
		||||
NNG_DECL void nng_http_conn_read_all(nng_http_conn *, nng_aio *);
 | 
			
		||||
 | 
			
		||||
// nng_http_conn_write attempts to write data, but it can write less
 | 
			
		||||
// than the amount requested. (It completes as soon as at least one
 | 
			
		||||
// byte is written.)
 | 
			
		||||
NNG_DECL void nng_http_conn_write(nng_http_conn *, nng_aio *);
 | 
			
		||||
 | 
			
		||||
// nng_http_conn_write_all is like nng_http_conn_write, but it does not
 | 
			
		||||
// finish until either all the requested data is written, or an error occurs.
 | 
			
		||||
NNG_DECL void nng_http_conn_write_all(nng_http_conn *, nng_aio *);
 | 
			
		||||
 | 
			
		||||
// nng_http_conn_write_req writes the entire request.  It will also write any
 | 
			
		||||
// data that has been attached.
 | 
			
		||||
NNG_DECL void nng_http_conn_write_req(
 | 
			
		||||
    nng_http_conn *, nng_http_req *, nng_aio *);
 | 
			
		||||
 | 
			
		||||
// nng_http_conn_write_res writes the entire response.  It will also write any
 | 
			
		||||
// data that has been attached.
 | 
			
		||||
NNG_DECL void nng_http_conn_write_res(
 | 
			
		||||
    nng_http_conn *, nng_http_res *, nng_aio *);
 | 
			
		||||
 | 
			
		||||
// nng_http_conn_read_req reads an entire request, EXCEPT for any entity
 | 
			
		||||
// data.  The caller is responsible for processing the headers in the request
 | 
			
		||||
// and reading any submitted entity data itself.
 | 
			
		||||
NNG_DECL void nng_http_conn_read_req(
 | 
			
		||||
    nng_http_conn *, nng_http_req *, nng_aio *);
 | 
			
		||||
 | 
			
		||||
// nng_http_conn_read_res reads an entire response, EXCEPT for any entity
 | 
			
		||||
// data.  The caller is responsible for processing the headers in the response
 | 
			
		||||
// and reading any submitted entity data itself.
 | 
			
		||||
NNG_DECL void nng_http_conn_read_res(
 | 
			
		||||
    nng_http_conn *, nng_http_res *, nng_aio *);
 | 
			
		||||
 | 
			
		||||
// nng_http_req_reset resets the request to an initially allocated state.
 | 
			
		||||
NNG_DECL void nng_http_req_reset(nng_http_req *);
 | 
			
		||||
 | 
			
		||||
// nng_http_res_reset resets the response to an initially allocated state.
 | 
			
		||||
NNG_DECL void nng_http_res_reset(nng_http_res *);
 | 
			
		||||
 | 
			
		||||
// nng_http_handler is a handler used on the server side to handle HTTP
 | 
			
		||||
// requests coming into a specific URL.
 | 
			
		||||
typedef struct nng_http_handler nng_http_handler;
 | 
			
		||||
 | 
			
		||||
// nng_http_handler_alloc creates a server handler object, for the supplied
 | 
			
		||||
// absolute URI (path only) with the callback.  By default the handler
 | 
			
		||||
// is assumed to handle only GET requests (and implictly HEAD requests
 | 
			
		||||
// as well.)
 | 
			
		||||
//
 | 
			
		||||
// Note that methods which modify a handler cannot be called while the handler
 | 
			
		||||
// is registered with the server, and that a handler can only be registered
 | 
			
		||||
// once per server.
 | 
			
		||||
//
 | 
			
		||||
// The callback function will receive the following arguments (via
 | 
			
		||||
// nng_aio_get_input(): nng_http_request *, nng_http_handler *, and
 | 
			
		||||
// nng_http_conn *.  The first is a request object, for convenience.
 | 
			
		||||
// The second is the handler, from which the callback can obtain any other
 | 
			
		||||
// data it has set.  The final is the http connection, which can be used
 | 
			
		||||
// to hijack the session.
 | 
			
		||||
//
 | 
			
		||||
// Upon completion, the handler should store an nng_http_res * as the
 | 
			
		||||
// first output using nng_aio_set_output.  If it does not do so, or supplies
 | 
			
		||||
// NULL, then it must send a response itself.
 | 
			
		||||
//
 | 
			
		||||
// The callback should complete with a result of 0 in most circumstances.
 | 
			
		||||
// If it completes with an error, then the connection is terminated, after
 | 
			
		||||
// possibly sending a 500 error response to the client.
 | 
			
		||||
NNG_DECL int nng_http_handler_alloc(
 | 
			
		||||
    nng_http_handler **, const char *, void (*)(nng_aio *));
 | 
			
		||||
 | 
			
		||||
// nng_http_handler_free frees the handler. This actually just drops a
 | 
			
		||||
// reference count on the handler, as it may be in use by an existing
 | 
			
		||||
// server.  The server will also call this when it is destroyed.
 | 
			
		||||
NNG_DECL void nng_http_handler_free(nng_http_handler *);
 | 
			
		||||
 | 
			
		||||
// nng_http_handler_alloc_file creates a "file" based handler, that
 | 
			
		||||
// serves up static content from the given file path.  The content-type
 | 
			
		||||
// supplied is determined from the file name using a simple built-in map.
 | 
			
		||||
NNG_DECL int nng_http_handler_alloc_file(
 | 
			
		||||
    nng_http_handler **, const char *, const char *);
 | 
			
		||||
 | 
			
		||||
// nng_http_handler_alloc_static creates a static-content handler.
 | 
			
		||||
// The last argument is the content-type, which may be NULL (in which case
 | 
			
		||||
// "application/octet-stream" is assumed.)
 | 
			
		||||
NNG_DECL int nng_http_handler_alloc_static(
 | 
			
		||||
    nng_http_handler **, const char *, const void *, size_t, const char *);
 | 
			
		||||
 | 
			
		||||
// nng_http_handler_alloc_redirect creates an HTTP redirect handler.
 | 
			
		||||
// The status is given, along with the new URL.  If the status is 0,
 | 
			
		||||
// then 301 will be used instead.
 | 
			
		||||
NNG_DECL int nng_http_handler_alloc_redirect(
 | 
			
		||||
    nng_http_handler **, const char *, uint16_t, const char *);
 | 
			
		||||
 | 
			
		||||
// nng_http_handler_alloc_file creates a "directory" based handler, that
 | 
			
		||||
// serves up static content from the given directory tree.  Directories
 | 
			
		||||
// that contain an index.html or index.htm file use that file for the
 | 
			
		||||
// directory content, otherwise a suitable error page is returned (the server
 | 
			
		||||
// does not generate index pages automatically.)  The content-type for
 | 
			
		||||
// files is determined from the file name using a simple built-in map.
 | 
			
		||||
NNG_DECL int nng_http_handler_alloc_directory(
 | 
			
		||||
    nng_http_handler **, const char *, const char *);
 | 
			
		||||
 | 
			
		||||
// nng_http_handler_set_method sets the method that the handler will be
 | 
			
		||||
// called for.  By default this is GET.  If NULL is supplied for the
 | 
			
		||||
// method, then the handler is executed regardless of method, and must
 | 
			
		||||
// inspect the method itself.
 | 
			
		||||
NNG_DECL int nng_http_handler_set_method(nng_http_handler *, const char *);
 | 
			
		||||
 | 
			
		||||
// nng_http_handler_set_host sets the Host: that the handler will be
 | 
			
		||||
// called for (to allow for virtual hosts).  If the value is NULL (the
 | 
			
		||||
// default, then the Host: header is not considered when matching the
 | 
			
		||||
// handler.)  Note that the Host: header must match *exactly* (except
 | 
			
		||||
// that case is not considered.)
 | 
			
		||||
NNG_DECL int nng_http_handler_set_host(nng_http_handler *, const char *);
 | 
			
		||||
 | 
			
		||||
// nng_http_handler_collect_body is used to indicate the server should
 | 
			
		||||
// check for, and process, data sent by the client, which will be attached
 | 
			
		||||
// to the request.  If this is false, then the handler will need to check
 | 
			
		||||
// for and process any content data.  By default the server will accept
 | 
			
		||||
// up to 1MB.  If the client attempts to send more data than requested,
 | 
			
		||||
// then a 400 Bad Request will be sent back to the client.  To set an
 | 
			
		||||
// unlimited value, use (size_t)-1.  To preclude the client from sending
 | 
			
		||||
// *any* data, use 0.  (The static and file handlers use 0 by default.)
 | 
			
		||||
NNG_DECL int nng_http_handler_collect_body(nng_http_handler *, bool, size_t);
 | 
			
		||||
 | 
			
		||||
// nng_http_handler_set_tree indicates that the handler is being registered
 | 
			
		||||
// for a hierarchical tree, rather than just a single path, so it will be
 | 
			
		||||
// called for all child paths supplied.  By default the handler is only
 | 
			
		||||
// called for an exact path match.
 | 
			
		||||
NNG_DECL int nng_http_handler_set_tree(nng_http_handler *);
 | 
			
		||||
 | 
			
		||||
// nng_http_handler_set_tree_exclusive indicates that the handler is being
 | 
			
		||||
// registered for a heirarchical tree *exclusively*, rather than just a single
 | 
			
		||||
// path, so it will be called for all child paths supplied. By default the
 | 
			
		||||
// handler is only called for an exact path match. Exclusive means that any
 | 
			
		||||
// other handler on a conflicting path will induce an address conflict error
 | 
			
		||||
// when added to a server.
 | 
			
		||||
NNG_DECL int nng_http_handler_set_tree_exclusive(nng_http_handler *);
 | 
			
		||||
 | 
			
		||||
// nng_http_handler_set_data is used to store additional data, along with
 | 
			
		||||
// a possible clean up routine.  (The clean up is a custom de-allocator and
 | 
			
		||||
// will be called with the supplied data as an argument, when the handler
 | 
			
		||||
// is being de-allocated.)
 | 
			
		||||
NNG_DECL int nng_http_handler_set_data(
 | 
			
		||||
    nng_http_handler *, void *, void (*)(void *));
 | 
			
		||||
 | 
			
		||||
// nng_http_handler_get_data returns the data that was previously stored.
 | 
			
		||||
NNG_DECL void *nng_http_handler_get_data(nng_http_handler *);
 | 
			
		||||
 | 
			
		||||
// nng_http_server is a handle to an HTTP server instance.  Servers
 | 
			
		||||
// only serve a single port / address at this time.
 | 
			
		||||
 | 
			
		||||
typedef struct nng_http_server nng_http_server;
 | 
			
		||||
 | 
			
		||||
// nng_http_server_hold gets a server structure, using the address determined
 | 
			
		||||
// from the URL.  If a server already exists, then a hold is placed on it, and
 | 
			
		||||
// that instance is returned.  If no such server exists, then a new instance
 | 
			
		||||
// is created.
 | 
			
		||||
NNG_DECL int nng_http_server_hold(nng_http_server **, const nng_url *);
 | 
			
		||||
 | 
			
		||||
// nng_http_server_release releases the hold on the server.  If this is the
 | 
			
		||||
// last instance of the server, then it is shutdown and resources are freed.
 | 
			
		||||
NNG_DECL void nng_http_server_release(nng_http_server *);
 | 
			
		||||
 | 
			
		||||
// nng_http_server_start starts the server handling HTTP.  Once this is
 | 
			
		||||
// called, it will not be possible to change certain parameters (such as
 | 
			
		||||
// any TLS configuration).
 | 
			
		||||
NNG_DECL int nng_http_server_start(nng_http_server *);
 | 
			
		||||
 | 
			
		||||
// nng_http_server_stop stops the server.  No new client connections are
 | 
			
		||||
// accepted after this returns.  Once a server is stopped fully, the
 | 
			
		||||
// instance will no longer be returned by nng_http_server_hold, as the
 | 
			
		||||
// server may not be reused.
 | 
			
		||||
NNG_DECL void nng_http_server_stop(nng_http_server *);
 | 
			
		||||
 | 
			
		||||
// nng_http_server_add_handler registers a handler on the server.
 | 
			
		||||
// This function will return NNG_EADDRINUSE if a conflicting handler
 | 
			
		||||
// is already registered (i.e. a handler with the same value for Host,
 | 
			
		||||
// Method, and URL.)
 | 
			
		||||
NNG_DECL int nng_http_server_add_handler(
 | 
			
		||||
    nng_http_server *, nng_http_handler *);
 | 
			
		||||
 | 
			
		||||
// nni_http_del_handler removes the given handler.  The caller is
 | 
			
		||||
// responsible for finalizing it afterwards.  If the handler was not found
 | 
			
		||||
// (not registered), NNG_ENOENT is returned.  In this case it is unsafe
 | 
			
		||||
// to make assumptions about the validity of the handler.
 | 
			
		||||
NNG_DECL int nng_http_server_del_handler(
 | 
			
		||||
    nng_http_server *, nng_http_handler *);
 | 
			
		||||
 | 
			
		||||
// nng_http_server_set_tls adds a TLS configuration to the server,
 | 
			
		||||
// and enables the use of it.  This returns NNG_EBUSY if the server is
 | 
			
		||||
// already started.   This wipes out the entire TLS configuration on the
 | 
			
		||||
// server client, so the caller must have configured it reasonably.
 | 
			
		||||
// This API is not recommended unless the caller needs complete control
 | 
			
		||||
// over the TLS configuration.
 | 
			
		||||
NNG_DECL int nng_http_server_set_tls(
 | 
			
		||||
    nng_http_server *, struct nng_tls_config *);
 | 
			
		||||
 | 
			
		||||
// nng_http_server_get_tls obtains the TLS configuration if one is present,
 | 
			
		||||
// or returns NNG_EINVAL.  The TLS configuration is invalidated if the
 | 
			
		||||
// nng_http_server_set_tls function is called, so be careful.
 | 
			
		||||
NNG_DECL int nng_http_server_get_tls(
 | 
			
		||||
    nng_http_server *, struct nng_tls_config **);
 | 
			
		||||
 | 
			
		||||
// nng_http_server_get_addr obtains the address with which the server was
 | 
			
		||||
// initialized or returns NNG_EINVAL. Useful for instance when the port has
 | 
			
		||||
// been automatically assigned.
 | 
			
		||||
NNG_DECL int nng_http_server_get_addr(nng_http_server *, nng_sockaddr *);
 | 
			
		||||
 | 
			
		||||
// nng_http_server_set_error_page sets a custom error page (HTML) content
 | 
			
		||||
// to be sent for the given error code.  This is used when the error is
 | 
			
		||||
// generated internally by the framework, or when the application returns
 | 
			
		||||
// the response back to the server via the handler's aio, and the response
 | 
			
		||||
// was allocated with nng_http_res_alloc_error.  If the response was not
 | 
			
		||||
// allocated this way, or the application writes the response itself instead
 | 
			
		||||
// of letting the server do so, then this setting will be ignored.
 | 
			
		||||
NNG_DECL int nng_http_server_set_error_page(
 | 
			
		||||
    nng_http_server *, uint16_t, const char *);
 | 
			
		||||
 | 
			
		||||
// nng_http_server_set_error_file works like nng_http_server_error_page,
 | 
			
		||||
// except that the content is loaded from the named file path.  The contents
 | 
			
		||||
// are loaded at the time this function is called, so this function should be
 | 
			
		||||
// called anytime the contents of the named file have changed.
 | 
			
		||||
NNG_DECL int nng_http_server_set_error_file(
 | 
			
		||||
    nng_http_server *, uint16_t, const char *);
 | 
			
		||||
 | 
			
		||||
// nng_http_server_res_error takes replaces the body of the response with
 | 
			
		||||
// a custom error page previously set for the server, using the status
 | 
			
		||||
// of the response.  The response must have the status set first using
 | 
			
		||||
// nng_http_res_set_status or implicitly via nng_http_res_alloc_error.
 | 
			
		||||
NNG_DECL int nng_http_server_res_error(nng_http_server *, nng_http_res *);
 | 
			
		||||
 | 
			
		||||
// nng_http_hijack is intended to be called by a handler that wishes to
 | 
			
		||||
// take over the processing of the HTTP session -- usually to change protocols
 | 
			
		||||
// (such as in the case of websocket).  The caller is responsible for the
 | 
			
		||||
// final disposal of the associated nng_http_conn.  Also, this completely
 | 
			
		||||
// disassociates the http session from the server, so the server may be
 | 
			
		||||
// stopped or destroyed without affecting the hijacked session.  Note also
 | 
			
		||||
// that the hijacker will need to issue any HTTP reply itself.  Finally,
 | 
			
		||||
// when a session is hijacked, the caller is also responsible for disposing
 | 
			
		||||
// of the request structure.  (Some hijackers may keep the request for
 | 
			
		||||
// further processing.)
 | 
			
		||||
 | 
			
		||||
NNG_DECL int nng_http_hijack(nng_http_conn *);
 | 
			
		||||
 | 
			
		||||
// nng_http_client represents a "client" object.  Clients can be used
 | 
			
		||||
// to create HTTP connections.  At present, connections are not cached
 | 
			
		||||
// or reused, but that could change in the future.
 | 
			
		||||
typedef struct nng_http_client nng_http_client;
 | 
			
		||||
 | 
			
		||||
// nng_http_client_alloc allocates a client object, associated with
 | 
			
		||||
// the given URL.
 | 
			
		||||
NNG_DECL int nng_http_client_alloc(nng_http_client **, const nng_url *);
 | 
			
		||||
 | 
			
		||||
// nng_http_client_free frees the client.  Connections created by the
 | 
			
		||||
// the client are not necessarily closed.
 | 
			
		||||
NNG_DECL void nng_http_client_free(nng_http_client *);
 | 
			
		||||
 | 
			
		||||
// nng_http_client_set_tls sets the TLS configuration.  This wipes out
 | 
			
		||||
// the entire TLS configuration on the client, so the caller must have
 | 
			
		||||
// configured it reasonably.  This API is not recommended unless the
 | 
			
		||||
// caller needs complete control over the TLS configuration.
 | 
			
		||||
NNG_DECL int nng_http_client_set_tls(
 | 
			
		||||
    nng_http_client *, struct nng_tls_config *);
 | 
			
		||||
 | 
			
		||||
// nng_http_client_get_tls obtains the TLS configuration if one is present,
 | 
			
		||||
// or returns NNG_EINVAL.  The supplied TLS configuration object may
 | 
			
		||||
// be invalidated by any future calls to nni_http_client_set_tls.
 | 
			
		||||
NNG_DECL int nng_http_client_get_tls(
 | 
			
		||||
    nng_http_client *, struct nng_tls_config **);
 | 
			
		||||
 | 
			
		||||
// nng_http_client_connect establishes a new connection with the server
 | 
			
		||||
// named in the URL used when the client was created.  Once the connection
 | 
			
		||||
// is established, the associated nng_http_conn object pointer is returned
 | 
			
		||||
// in the first (index 0) output for the aio.
 | 
			
		||||
NNG_DECL void nng_http_client_connect(nng_http_client *, nng_aio *);
 | 
			
		||||
 | 
			
		||||
// nng_http_conn_transact is used to perform a round-trip exchange (i.e. a
 | 
			
		||||
// single HTTP transaction).  It will not automatically close the connection,
 | 
			
		||||
// unless some kind of significant error occurs.  The caller should close
 | 
			
		||||
// the connection if the aio does not complete successfully.
 | 
			
		||||
NNG_DECL void nng_http_conn_transact(
 | 
			
		||||
    nng_http_conn *, nng_http_req *, nng_http_res *, nng_aio *);
 | 
			
		||||
 | 
			
		||||
// nng_http_client_transact is used to execute a single transaction to a
 | 
			
		||||
// server. The connection is opened, and will be closed when the transaction is
 | 
			
		||||
// complete.
 | 
			
		||||
NNG_DECL void nng_http_client_transact(
 | 
			
		||||
    nng_http_client *, nng_http_req *, nng_http_res *, nng_aio *);
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // NNG_H
 | 
			
		||||
@@ -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
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -0,0 +1,222 @@
 | 
			
		||||
//
 | 
			
		||||
// Copyright 2024 Staysail Systems, Inc. <info@staysail.tech>
 | 
			
		||||
//
 | 
			
		||||
// 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.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
// This file is used to enable external TLS "engines", so
 | 
			
		||||
// that third party TLS libraries can be plugged in
 | 
			
		||||
 | 
			
		||||
#ifndef NNG_SUPPLEMENTAL_TLS_ENGINE_H
 | 
			
		||||
#define NNG_SUPPLEMENTAL_TLS_ENGINE_H
 | 
			
		||||
 | 
			
		||||
#include <nng/supplemental/tls/tls.h>
 | 
			
		||||
 | 
			
		||||
// Locking theory statement for TLS engines.  The engine is assumed
 | 
			
		||||
// operate only from the context of threads called by the common
 | 
			
		||||
// framework.  That is to say, the callbacks made by the engine
 | 
			
		||||
// should always be on a thread that has context from the framework
 | 
			
		||||
// calling into the engine.  This means that the lower level send
 | 
			
		||||
// and receive functions can assume that they have lock ownership
 | 
			
		||||
// inherited on the stack.
 | 
			
		||||
 | 
			
		||||
// nng_tls_engine_conn represents the engine-specific private
 | 
			
		||||
// state for a TLS connection.  It is provided here for type
 | 
			
		||||
// safety.  Engine implementations should provide the structure
 | 
			
		||||
// definition locally.
 | 
			
		||||
typedef struct nng_tls_engine_conn nng_tls_engine_conn;
 | 
			
		||||
 | 
			
		||||
// nng_tls_engine_config represents the engine-specific private
 | 
			
		||||
// state for the TLS configuration.  It is provided here for type
 | 
			
		||||
// safety.  Engine implementations should provide the structure
 | 
			
		||||
// definition locally.
 | 
			
		||||
typedef struct nng_tls_engine_config nng_tls_engine_config;
 | 
			
		||||
 | 
			
		||||
typedef struct nng_tls_engine_conn_ops_s {
 | 
			
		||||
	// size is the size of the engine's per-connection state.
 | 
			
		||||
	// The framework will allocate this on behalf of the engine.
 | 
			
		||||
	// Typically this will be sizeof (struct nng_tls_engine_conn).
 | 
			
		||||
	size_t size;
 | 
			
		||||
 | 
			
		||||
	// init is used to initialize a connection object.
 | 
			
		||||
	// The passed in connection state will be aligned naturally,
 | 
			
		||||
	// and zeroed.  On success this returns 0, else an NNG error code.
 | 
			
		||||
	int (*init)(nng_tls_engine_conn *, void *, nng_tls_engine_config *);
 | 
			
		||||
 | 
			
		||||
	// fini destroys a connection object.  This will
 | 
			
		||||
	// be called only when no other external use of the connection
 | 
			
		||||
	// object exists, and only on fully initialed connection objects.
 | 
			
		||||
	void (*fini)(nng_tls_engine_conn *);
 | 
			
		||||
 | 
			
		||||
	// close closes the connection object, but should not
 | 
			
		||||
	// deallocate any memory.  It may also issue a TLS close-notify.
 | 
			
		||||
	void (*close)(nng_tls_engine_conn *);
 | 
			
		||||
 | 
			
		||||
	// handshake attempts to complete the SSL handshake phase.
 | 
			
		||||
	// It returns zero on success, or an error if one occurred.
 | 
			
		||||
	// The value NNG_EAGAIN should be returned if underlying I/O
 | 
			
		||||
	// is required to be completed first.  The framework will
 | 
			
		||||
	// ensure that the handshake completes before sending any data
 | 
			
		||||
	// down.
 | 
			
		||||
	int (*handshake)(nng_tls_engine_conn *);
 | 
			
		||||
 | 
			
		||||
	// recv attempts to read data (decrypted) from the connection.
 | 
			
		||||
	// It returns 0 on success, otherwise an error.  The implementation
 | 
			
		||||
	// should return NNG_EAGAIN if I/O to the underlying stream is
 | 
			
		||||
	// required to complete the operation.  On success, the count
 | 
			
		||||
	// is updated to reflect the number of bytes actually received.
 | 
			
		||||
	int (*recv)(nng_tls_engine_conn *, uint8_t *, size_t *);
 | 
			
		||||
 | 
			
		||||
	// send attempts to write data to the underlying connection.
 | 
			
		||||
	// It returns zero on success, otherwise an error. The implementation
 | 
			
		||||
	// should return NNG_EAGAIN if I/O to the underlying stream is
 | 
			
		||||
	// required to complete the operation.  On success, the count
 | 
			
		||||
	// is updated to reflect the number of bytes actually sent.
 | 
			
		||||
	int (*send)(nng_tls_engine_conn *, const uint8_t *, size_t *);
 | 
			
		||||
 | 
			
		||||
	// verified returns true if the connection is fully
 | 
			
		||||
	// TLS verified, false otherwise.
 | 
			
		||||
	bool (*verified)(nng_tls_engine_conn *);
 | 
			
		||||
 | 
			
		||||
	// peer_cn returns the common name of the peer
 | 
			
		||||
	// The return string needs to be freed.
 | 
			
		||||
	char *(*peer_cn)(nng_tls_engine_conn *);
 | 
			
		||||
 | 
			
		||||
	// peer_alt_names returns the subject alternative names.
 | 
			
		||||
	// The return string list and its strings need to be freed.
 | 
			
		||||
	char **(*peer_alt_names)(nng_tls_engine_conn *);
 | 
			
		||||
} nng_tls_engine_conn_ops;
 | 
			
		||||
 | 
			
		||||
typedef struct nng_tls_engine_config_ops_s {
 | 
			
		||||
	// size is the size of the engine's configuration object.
 | 
			
		||||
	// The framework will allocate this on behalf of the engine.
 | 
			
		||||
	// Typically this will be sizeof (struct nng_tls_engine_config).
 | 
			
		||||
	size_t size;
 | 
			
		||||
 | 
			
		||||
	// init prepares the configuration object object.
 | 
			
		||||
	// The mode indicates whether the object should be
 | 
			
		||||
	// initialized for use as a TLS server or client.
 | 
			
		||||
	// The config passed in will be aligned on a 64-bit boundary,
 | 
			
		||||
	// and will be initialized to zero.  On success this returns
 | 
			
		||||
	// 0, else an NNG error code.
 | 
			
		||||
	int (*init)(nng_tls_engine_config *, nng_tls_mode);
 | 
			
		||||
 | 
			
		||||
	// fini is used to tear down the configuration object.
 | 
			
		||||
	// This will only be called on objects that have been properly
 | 
			
		||||
	// initialized with nte_config_init.
 | 
			
		||||
	void (*fini)(nng_tls_engine_config *);
 | 
			
		||||
 | 
			
		||||
	// server is used to set the server name.  This can be used in SNI,
 | 
			
		||||
	// and will also be used on the client to validate the identity.
 | 
			
		||||
	// If this is not set, then no verification will be performed.
 | 
			
		||||
	int (*server)(nng_tls_engine_config *, const char *);
 | 
			
		||||
 | 
			
		||||
	// auth is used to configure the authentication mode.  Values:
 | 
			
		||||
	// NNG_AUTH_MODE_NONE
 | 
			
		||||
	//   No validation of the peer is performed.  Public facing
 | 
			
		||||
	//   servers often use this.
 | 
			
		||||
	// NNG_AUTH_MODE_OPTIONAL
 | 
			
		||||
	//   The peer's identity is validated if a certificate is presented.
 | 
			
		||||
	//   This is typically useful on servers.
 | 
			
		||||
	// NNG_AUTH_MODE_REQUIRED
 | 
			
		||||
	//   The peer's certificate must be present and is verified.
 | 
			
		||||
	//   This is standard for the client, and on servers it is used
 | 
			
		||||
	//   when client (mutual) authentication is needed.
 | 
			
		||||
	int (*auth)(nng_tls_engine_config *, nng_tls_auth_mode);
 | 
			
		||||
 | 
			
		||||
	// ca_chain sets the configuration authorities that will be
 | 
			
		||||
	// used to validate peers.  An optional CRL is supplied as well.
 | 
			
		||||
	// Both values are C strings (NUL terminated) containing
 | 
			
		||||
	// PEM data.  There may be multiple PEM blocks.  The
 | 
			
		||||
	// CRL may be NULL if not needed.
 | 
			
		||||
	int (*ca_chain)(nng_tls_engine_config *, const char *, const char *);
 | 
			
		||||
 | 
			
		||||
	// own_cert configures our identity -- the certificate containing
 | 
			
		||||
	// our public key, our private key (which might be encrypted), and
 | 
			
		||||
	// potentially a password used to decrypt the private key.
 | 
			
		||||
	// All of these are C strings.  The cert may actually be a chain
 | 
			
		||||
	// which will be presented to our peer.   This function may be
 | 
			
		||||
	// called multiple times to register different keys with different
 | 
			
		||||
	// parameters on a server.  (For example, once for RSA parameters,
 | 
			
		||||
	// and again later with EC parameters.)  The certificate and the
 | 
			
		||||
	// private key may be presented in the same file.  The implementation
 | 
			
		||||
	// is responsible for parsing out the relevant data.  If the password
 | 
			
		||||
	// is NULL, then the key file should be unencrypted.  The supplied
 | 
			
		||||
	// password may be ignored if the key is not encrypted.  Not all
 | 
			
		||||
	// engine implementations need support encryption of the key.
 | 
			
		||||
	int (*own_cert)(
 | 
			
		||||
	    nng_tls_engine_config *, const char *, const char *, const char *);
 | 
			
		||||
 | 
			
		||||
	// psk configures a PSK identity and key.  This can be called
 | 
			
		||||
	// once for clients, or multiple times for servers.  However, not all
 | 
			
		||||
	// implementations support multiple PSKs for a server.
 | 
			
		||||
	int (*psk)(
 | 
			
		||||
	    nng_tls_engine_config *, const char *, const uint8_t *, size_t);
 | 
			
		||||
 | 
			
		||||
	// version configures the minimum and maximum TLS versions.  The
 | 
			
		||||
	// engine should default to supporting TLS1.0 through 1.2, and
 | 
			
		||||
	// optionally 1.3 if it can.  The engine should restrict the
 | 
			
		||||
	// the requested range to what it can support -- if no version
 | 
			
		||||
	// within the range is supported (such as if NNG_TLS_1_3 is
 | 
			
		||||
	// specified for both min and max, and the engine lacks support
 | 
			
		||||
	// for v1.3, then NNG_ENOTSUP should be returned.
 | 
			
		||||
	int (*version)(
 | 
			
		||||
	    nng_tls_engine_config *, nng_tls_version, nng_tls_version);
 | 
			
		||||
} nng_tls_engine_config_ops;
 | 
			
		||||
 | 
			
		||||
typedef enum nng_tls_engine_version_e {
 | 
			
		||||
	NNG_TLS_ENGINE_V0      = 0,
 | 
			
		||||
	NNG_TLS_ENGINE_V1      = 1, // adds FIPS, TLS 1.3 support
 | 
			
		||||
	NNG_TLS_ENGINE_V2      = 2, // adds PSK support
 | 
			
		||||
	NNG_TLS_ENGINE_VERSION = NNG_TLS_ENGINE_V2,
 | 
			
		||||
} nng_tls_engine_version;
 | 
			
		||||
 | 
			
		||||
typedef struct nng_tls_engine_s {
 | 
			
		||||
	// _version is the engine version.  This for now must
 | 
			
		||||
	// be NNG_TLS_ENGINE_VERSION.  If the version does not match
 | 
			
		||||
	// then registration of the engine will fail.
 | 
			
		||||
	nng_tls_engine_version version;
 | 
			
		||||
 | 
			
		||||
	// config_ops is the operations for TLS configuration objects.
 | 
			
		||||
	nng_tls_engine_config_ops *config_ops;
 | 
			
		||||
 | 
			
		||||
	// conn_ops is the operations for TLS connections (stream-oriented).
 | 
			
		||||
	nng_tls_engine_conn_ops *conn_ops;
 | 
			
		||||
 | 
			
		||||
	// name contains the name of the engine, for example "wolfSSL".
 | 
			
		||||
	// It is acceptable to append a version number as well.
 | 
			
		||||
	const char *name;
 | 
			
		||||
 | 
			
		||||
	// description contains a human readable description.  This can
 | 
			
		||||
	// supply information about the backing library, for example
 | 
			
		||||
	// "mbed TLS v2.7"
 | 
			
		||||
	const char *description;
 | 
			
		||||
 | 
			
		||||
	// fips_mode is true if the engine is in FIPS mode.
 | 
			
		||||
	// It is expected that this will be enabled either at compile
 | 
			
		||||
	// time, or via environment variables at engine initialization.
 | 
			
		||||
	// FIPS mode cannot be changed once the engine is registered.
 | 
			
		||||
	bool fips_mode;
 | 
			
		||||
} nng_tls_engine;
 | 
			
		||||
 | 
			
		||||
NNG_DECL int nng_tls_engine_register(const nng_tls_engine *);
 | 
			
		||||
 | 
			
		||||
// nng_tls_engine_send is called by the engine to send data over the
 | 
			
		||||
// underlying connection.  It returns zero on success, NNG_EAGAIN if
 | 
			
		||||
// the operation can't be completed yet (the transport is busy and cannot
 | 
			
		||||
// accept more data yet), or some other error.  On success the count is
 | 
			
		||||
// updated with the number of bytes actually sent.  The first argument
 | 
			
		||||
// is the context structure passed in when starting the engine.
 | 
			
		||||
NNG_DECL int nng_tls_engine_send(void *, const uint8_t *, size_t *);
 | 
			
		||||
 | 
			
		||||
// nng_tls_engine_recv is called byu the engine to receive data over
 | 
			
		||||
// the underlying connection.  It returns zero on success, NNG_EAGAIN
 | 
			
		||||
// if the operation can't be completed yet (there is no data available
 | 
			
		||||
// for reading), or some other error.  On success the count is updated
 | 
			
		||||
// with the number of bytes actually received.
 | 
			
		||||
NNG_DECL int nng_tls_engine_recv(void *, uint8_t *, size_t *);
 | 
			
		||||
 | 
			
		||||
#endif // NNG_SUPPLEMENTAL_TLS_ENGINE_H
 | 
			
		||||
@@ -0,0 +1,152 @@
 | 
			
		||||
//
 | 
			
		||||
// Copyright 2024 Staysail Systems, Inc. <info@staysail.tech>
 | 
			
		||||
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
 | 
			
		||||
//
 | 
			
		||||
// 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 NNG_SUPPLEMENTAL_TLS_TLS_H
 | 
			
		||||
#define NNG_SUPPLEMENTAL_TLS_TLS_H
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
#include <nng/nng.h>
 | 
			
		||||
 | 
			
		||||
// Note that TLS functions may be stubbed out if TLS is not enabled in
 | 
			
		||||
// the build.
 | 
			
		||||
 | 
			
		||||
// For some transports, we need TLS configuration, including certificates
 | 
			
		||||
// and so forth.  A TLS configuration cannot be changed once it is in use.
 | 
			
		||||
typedef struct nng_tls_config nng_tls_config;
 | 
			
		||||
 | 
			
		||||
typedef enum nng_tls_mode {
 | 
			
		||||
	NNG_TLS_MODE_CLIENT = 0,
 | 
			
		||||
	NNG_TLS_MODE_SERVER = 1,
 | 
			
		||||
} nng_tls_mode;
 | 
			
		||||
 | 
			
		||||
typedef enum nng_tls_auth_mode {
 | 
			
		||||
	NNG_TLS_AUTH_MODE_NONE     = 0, // No verification is performed
 | 
			
		||||
	NNG_TLS_AUTH_MODE_OPTIONAL = 1, // Verify cert if presented
 | 
			
		||||
	NNG_TLS_AUTH_MODE_REQUIRED = 2, // Verify cert, close if invalid
 | 
			
		||||
} nng_tls_auth_mode;
 | 
			
		||||
 | 
			
		||||
// TLS version numbers.  We encode the major number and minor number
 | 
			
		||||
// as separate byte fields.  No support for SSL 3.0 or earlier -- older
 | 
			
		||||
// versions are known to be insecure and should not be used.
 | 
			
		||||
// When possible applications should restrict themselves to TLS 1.2 or better.
 | 
			
		||||
typedef enum nng_tls_version {
 | 
			
		||||
	NNG_TLS_1_0 = 0x301,
 | 
			
		||||
	NNG_TLS_1_1 = 0x302,
 | 
			
		||||
	NNG_TLS_1_2 = 0x303,
 | 
			
		||||
	NNG_TLS_1_3 = 0x304
 | 
			
		||||
} nng_tls_version;
 | 
			
		||||
 | 
			
		||||
// nng_tls_config_alloc creates a TLS configuration using
 | 
			
		||||
// reasonable defaults.  This configuration can be shared
 | 
			
		||||
// with multiple pipes or services/servers.
 | 
			
		||||
NNG_DECL int nng_tls_config_alloc(nng_tls_config **, nng_tls_mode);
 | 
			
		||||
 | 
			
		||||
// nng_tls_config_hold increments the reference count on the TLS
 | 
			
		||||
// configuration object.  The hold can be dropped by calling
 | 
			
		||||
// nng_tls_config_free later.
 | 
			
		||||
NNG_DECL void nng_tls_config_hold(nng_tls_config *);
 | 
			
		||||
 | 
			
		||||
// nng_tls_config_free drops the reference count on the TLS
 | 
			
		||||
// configuration object, and if zero, deallocates it.
 | 
			
		||||
NNG_DECL void nng_tls_config_free(nng_tls_config *);
 | 
			
		||||
 | 
			
		||||
// nng_tls_config_server_name sets the server name.  This is
 | 
			
		||||
// called by clients to set the name that the server supplied
 | 
			
		||||
// certificate should be matched against.  This can also cause
 | 
			
		||||
// the SNI to be sent to the server to tell it which cert to
 | 
			
		||||
// use if it supports more than one.
 | 
			
		||||
NNG_DECL int nng_tls_config_server_name(nng_tls_config *, const char *);
 | 
			
		||||
 | 
			
		||||
// nng_tls_config_ca_cert configures one or more CAs used for validation
 | 
			
		||||
// of peer certificates.  Multiple CAs (and their chains) may be configured
 | 
			
		||||
// by either calling this multiple times, or by specifying a list of
 | 
			
		||||
// certificates as concatenated data.  The final argument is an optional CRL
 | 
			
		||||
// (revocation list) for the CA, also in PEM.  Both PEM strings are ASCIIZ
 | 
			
		||||
// format (except that the CRL may be NULL).
 | 
			
		||||
NNG_DECL int nng_tls_config_ca_chain(
 | 
			
		||||
    nng_tls_config *, const char *, const char *);
 | 
			
		||||
 | 
			
		||||
// nng_tls_config_own_cert is used to load our own certificate and public
 | 
			
		||||
// key.  For servers, this may be called more than once to configure multiple
 | 
			
		||||
// different keys, for example with different algorithms depending on what
 | 
			
		||||
// the peer supports. On the client, only a single option is available.
 | 
			
		||||
// The first two arguments are the cert (or validation chain) and the
 | 
			
		||||
// key as PEM format ASCIIZ strings.  The final argument is an optional
 | 
			
		||||
// password and may be NULL.
 | 
			
		||||
NNG_DECL int nng_tls_config_own_cert(
 | 
			
		||||
    nng_tls_config *, const char *, const char *, const char *);
 | 
			
		||||
 | 
			
		||||
// nng_tls_config_key is used to pass our own private key.
 | 
			
		||||
NNG_DECL int nng_tls_config_key(nng_tls_config *, const uint8_t *, size_t);
 | 
			
		||||
 | 
			
		||||
// nng_tls_config_pass is used to pass a password used to decrypt
 | 
			
		||||
// private keys that are encrypted.
 | 
			
		||||
NNG_DECL int nng_tls_config_pass(nng_tls_config *, const char *);
 | 
			
		||||
 | 
			
		||||
// nng_tls_config_auth_mode is used to configure the authentication mode use.
 | 
			
		||||
// The default is that servers have this off (i.e. no client authentication)
 | 
			
		||||
// and clients have it on (they verify the server), which matches typical
 | 
			
		||||
// practice.
 | 
			
		||||
NNG_DECL int nng_tls_config_auth_mode(nng_tls_config *, nng_tls_auth_mode);
 | 
			
		||||
 | 
			
		||||
// nng_tls_config_ca_file is used to pass a CA chain and optional CRL
 | 
			
		||||
// via the filesystem.  If CRL data is present, it must be contained
 | 
			
		||||
// in the file, along with the CA certificate data.  The format is PEM.
 | 
			
		||||
// The path name must be a legal file name.
 | 
			
		||||
NNG_DECL int nng_tls_config_ca_file(nng_tls_config *, const char *);
 | 
			
		||||
 | 
			
		||||
// nng_tls_config_cert_key_file is used to pass our own certificate and
 | 
			
		||||
// private key data via the filesystem.  Both the key and certificate
 | 
			
		||||
// must be present as PEM blocks in the same file.  A password is used to
 | 
			
		||||
// decrypt the private key if it is encrypted and the password supplied is not
 | 
			
		||||
// NULL. This may be called multiple times on servers, but only once on a
 | 
			
		||||
// client. (Servers can support multiple different certificates and keys for
 | 
			
		||||
// different cryptographic algorithms.  Clients only get one.)
 | 
			
		||||
NNG_DECL int nng_tls_config_cert_key_file(
 | 
			
		||||
    nng_tls_config *, const char *, const char *);
 | 
			
		||||
 | 
			
		||||
// nng_tls_config_psk_identity is used to pass TLS PSK parameters.  The
 | 
			
		||||
// identity, and an associated key.  Clients can only do this once.
 | 
			
		||||
// Servers can do it multiple times, potentially, to provide for different
 | 
			
		||||
// keys for different client identities.  There is no way to remove these
 | 
			
		||||
// from a configuration.
 | 
			
		||||
NNG_DECL int nng_tls_config_psk(
 | 
			
		||||
    nng_tls_config *, const char *, const uint8_t *, size_t);
 | 
			
		||||
 | 
			
		||||
// Configure supported TLS version.  By default we usually restrict
 | 
			
		||||
// ourselves to TLS 1.2 and newer.  We do not support older versions.
 | 
			
		||||
// If the implementation cannot support any version (for example if
 | 
			
		||||
// the minimum requested is 1.3 but the TLS implementation lacks support
 | 
			
		||||
// for TLS 1.3) then NNG_ENOTSUP will be returned.
 | 
			
		||||
NNG_DECL int nng_tls_config_version(
 | 
			
		||||
    nng_tls_config *, nng_tls_version, nng_tls_version);
 | 
			
		||||
 | 
			
		||||
// nng_tls_engine_name returns the "name" of the TLS engine.  If no
 | 
			
		||||
// TLS engine support is enabled, then "none" is returned.
 | 
			
		||||
NNG_DECL const char *nng_tls_engine_name(void);
 | 
			
		||||
 | 
			
		||||
// nng_tls_engine_description returns the "description" of the TLS engine.
 | 
			
		||||
// If no TLS engine support is enabled, then an empty string is returned.
 | 
			
		||||
NNG_DECL const char *nng_tls_engine_description(void);
 | 
			
		||||
 | 
			
		||||
// nng_tls_engine_fips_mode returns true if the engine is in FIPS 140-2 mode.
 | 
			
		||||
NNG_DECL bool nng_tls_engine_fips_mode(void);
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // NNG_SUPPLEMENTAL_TLS_TLS_H
 | 
			
		||||
@@ -0,0 +1,42 @@
 | 
			
		||||
//
 | 
			
		||||
// Copyright 2024 Staysail Systems, Inc. <info@staysail.tech>
 | 
			
		||||
//
 | 
			
		||||
// 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 NNG_SUPPLEMENTAL_UTIL_IDHASH_H
 | 
			
		||||
#define NNG_SUPPLEMENTAL_UTIL_IDHASH_H
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <nng/nng.h>
 | 
			
		||||
 | 
			
		||||
typedef struct nng_id_map_s nng_id_map;
 | 
			
		||||
 | 
			
		||||
#define NNG_MAP_RANDOM 1
 | 
			
		||||
 | 
			
		||||
// For NanoNNG
 | 
			
		||||
NNG_DECL void  nng_id_map_foreach(
 | 
			
		||||
     nng_id_map *map, void (*)(void *, void *));
 | 
			
		||||
NNG_DECL void nng_id_map_foreach2(nng_id_map *map,
 | 
			
		||||
    void (*)(void *, void *, void *), void *);
 | 
			
		||||
 | 
			
		||||
NNG_DECL int nng_id_map_alloc(
 | 
			
		||||
    nng_id_map **map, uint64_t lo, uint64_t hi, int flags);
 | 
			
		||||
NNG_DECL void  nng_id_map_free(nng_id_map *map);
 | 
			
		||||
NNG_DECL void *nng_id_get(nng_id_map *, uint64_t);
 | 
			
		||||
NNG_DECL int   nng_id_set(nng_id_map *, uint64_t, void *);
 | 
			
		||||
NNG_DECL int   nng_id_alloc(nng_id_map *, uint64_t *, void *);
 | 
			
		||||
NNG_DECL int   nng_id_remove(nng_id_map *, uint64_t);
 | 
			
		||||
NNG_DECL bool  nng_id_visit(nng_id_map *, uint64_t *, void **, uint32_t *);
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // NNG_SUPPLEMENTAL_IDHASH_IDHASH_H
 | 
			
		||||
@@ -0,0 +1,50 @@
 | 
			
		||||
//
 | 
			
		||||
// Copyright 2024 Staysail Systems, Inc. <info@staysail.tech>
 | 
			
		||||
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
 | 
			
		||||
//
 | 
			
		||||
// 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 NNG_SUPPLEMENTAL_UTIL_OPTIONS_H
 | 
			
		||||
#define NNG_SUPPLEMENTAL_UTIL_OPTIONS_H
 | 
			
		||||
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
 | 
			
		||||
#include <nng/nng.h>
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// This is a relatively simple "options parsing" library, used to
 | 
			
		||||
// parse command line options.  We would use getopt(3), but there are
 | 
			
		||||
// two problems with getopt(3).  First, it isn't available on all
 | 
			
		||||
// platforms (especially Win32), and second, it doesn't support long
 | 
			
		||||
// options.  We *exclusively* support long options.  POSIX style
 | 
			
		||||
// short option clustering is *NOT* supported.
 | 
			
		||||
 | 
			
		||||
struct nng_optspec {
 | 
			
		||||
	const char *o_name;  // Long style name (may be NULL for short only)
 | 
			
		||||
	int         o_short; // Short option (no clustering!)
 | 
			
		||||
	int         o_val;   // Value stored on a good parse (>0)
 | 
			
		||||
	bool        o_arg;   // Option takes an argument if true
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct nng_optspec nng_optspec;
 | 
			
		||||
 | 
			
		||||
// Call with *optidx set to 1 to start parsing for a standard program.
 | 
			
		||||
// The val will store the value of the matched "o_val", optarg will be
 | 
			
		||||
// set to match the option string, and optidx will be increment appropriately.
 | 
			
		||||
// Returns -1 when the end of options is reached, 0 on success, or
 | 
			
		||||
// NNG_EINVAL if the option parse is invalid for any reason.
 | 
			
		||||
NNG_DECL int nng_opts_parse(int argc, char *const *argv,
 | 
			
		||||
    const nng_optspec *opts, int *val, char **optarg, int *optidx);
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // NNG_SUPPLEMENTAL_UTIL_OPTIONS_H
 | 
			
		||||
@@ -0,0 +1,119 @@
 | 
			
		||||
//
 | 
			
		||||
// Copyright 2024 Staysail Systems, Inc. <info@staysail.tech>
 | 
			
		||||
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
 | 
			
		||||
//
 | 
			
		||||
// 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 NNG_SUPPLEMENTAL_UTIL_PLATFORM_H
 | 
			
		||||
#define NNG_SUPPLEMENTAL_UTIL_PLATFORM_H
 | 
			
		||||
 | 
			
		||||
// The declarations in this file are provided to assist with application
 | 
			
		||||
// portability.  Conceptually these APIs are based on work we have already
 | 
			
		||||
// done for NNG internals, and we find that they are useful in building
 | 
			
		||||
// portable applications.
 | 
			
		||||
 | 
			
		||||
// If it is more natural to use native system APIs like pthreads or C11
 | 
			
		||||
// APIs or Windows APIs, then by all means please feel free to simply
 | 
			
		||||
// ignore this.
 | 
			
		||||
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
#include <nng/nng.h>
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Return unix timestamp (milliseconds) .
 | 
			
		||||
NNG_DECL nng_time nng_timestamp(void);
 | 
			
		||||
 | 
			
		||||
// Get current process Id.
 | 
			
		||||
NNG_DECL int nng_getpid();
 | 
			
		||||
 | 
			
		||||
// nng_rwlock is a rwlock. TODO more comments
 | 
			
		||||
typedef struct nng_rwlock nng_rwlock;
 | 
			
		||||
NNG_DECL int  nng_rwlock_alloc(nng_rwlock **);
 | 
			
		||||
NNG_DECL void nng_rwlock_free(nng_rwlock *);
 | 
			
		||||
NNG_DECL void nng_rwlock_rdlock(nng_rwlock *);
 | 
			
		||||
NNG_DECL void nng_rwlock_rwlock(nng_rwlock *);
 | 
			
		||||
NNG_DECL void nng_rwlock_unlock(nng_rwlock *);
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Atomics support.  This will evolve over time.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
// nng_atomic_flag supports only test-and-set and reset operations.
 | 
			
		||||
// This can be implemented without locks on any reasonable system, and
 | 
			
		||||
// it corresponds to C11 atomic flag.
 | 
			
		||||
typedef struct nni_atomic_flag nng_atomic_flag;
 | 
			
		||||
 | 
			
		||||
NNG_DECL bool nng_atomic_flag_test_and_set(nng_atomic_flag *);
 | 
			
		||||
NNG_DECL void nng_atomic_flag_reset(nng_atomic_flag *);
 | 
			
		||||
 | 
			
		||||
// nng_atomic_bool is for boolean flags that need to be checked without
 | 
			
		||||
// changing their value.  This might require a lock on some systems.
 | 
			
		||||
typedef struct nni_atomic_bool nng_atomic_bool;
 | 
			
		||||
 | 
			
		||||
NNG_DECL int  nng_atomic_alloc_bool(nng_atomic_bool **v);
 | 
			
		||||
NNG_DECL void nng_atomic_free_bool(nng_atomic_bool *v);
 | 
			
		||||
NNG_DECL void nng_atomic_set_bool(nng_atomic_bool *, bool);
 | 
			
		||||
NNG_DECL bool nng_atomic_get_bool(nng_atomic_bool *);
 | 
			
		||||
NNG_DECL bool nng_atomic_swap_bool(nng_atomic_bool *, bool);
 | 
			
		||||
 | 
			
		||||
typedef struct nni_atomic_u64 nng_atomic_u64;
 | 
			
		||||
 | 
			
		||||
NNG_DECL int      nng_atomic_alloc64(nng_atomic_u64 **v);
 | 
			
		||||
NNG_DECL void     nng_atomic_free64(nng_atomic_u64 *v);
 | 
			
		||||
NNG_DECL void     nng_atomic_add64(nng_atomic_u64 *, uint64_t);
 | 
			
		||||
NNG_DECL void     nng_atomic_sub64(nng_atomic_u64 *, uint64_t);
 | 
			
		||||
NNG_DECL uint64_t nng_atomic_get64(nng_atomic_u64 *);
 | 
			
		||||
NNG_DECL void     nng_atomic_set64(nng_atomic_u64 *, uint64_t);
 | 
			
		||||
NNG_DECL uint64_t nng_atomic_swap64(nng_atomic_u64 *, uint64_t);
 | 
			
		||||
NNG_DECL uint64_t nng_atomic_dec64_nv(nng_atomic_u64 *);
 | 
			
		||||
NNG_DECL void     nng_atomic_inc64(nng_atomic_u64 *);
 | 
			
		||||
 | 
			
		||||
// nng_atomic_cas64 is a compare and swap.  The second argument is the
 | 
			
		||||
// value to compare against, and the third is the new value. Returns
 | 
			
		||||
// true if the value was set.
 | 
			
		||||
NNG_DECL bool nng_atomic_cas64(nng_atomic_u64 *, uint64_t, uint64_t);
 | 
			
		||||
 | 
			
		||||
// In a lot of circumstances, we want a simple atomic reference count,
 | 
			
		||||
// or atomic tunable values for integers like queue lengths or TTLs.
 | 
			
		||||
// These native integer forms should be preferred over the 64 bit versions
 | 
			
		||||
// unless larger bit sizes are truly needed.  They will be more efficient
 | 
			
		||||
// on many platforms.
 | 
			
		||||
typedef struct nni_atomic_int nng_atomic_int;
 | 
			
		||||
 | 
			
		||||
NNG_DECL int  nng_atomic_alloc(nng_atomic_int **v);
 | 
			
		||||
NNG_DECL void nng_atomic_free(nng_atomic_int *v);
 | 
			
		||||
NNG_DECL void nng_atomic_add(nng_atomic_int *, int);
 | 
			
		||||
NNG_DECL void nng_atomic_sub(nng_atomic_int *, int);
 | 
			
		||||
NNG_DECL int  nng_atomic_get(nng_atomic_int *);
 | 
			
		||||
NNG_DECL void nng_atomic_set(nng_atomic_int *, int);
 | 
			
		||||
NNG_DECL int  nng_atomic_swap(nng_atomic_int *, int);
 | 
			
		||||
NNG_DECL int  nng_atomic_dec_nv(nng_atomic_int *);
 | 
			
		||||
NNG_DECL void nng_atomic_dec(nng_atomic_int *);
 | 
			
		||||
NNG_DECL void nng_atomic_inc(nng_atomic_int *);
 | 
			
		||||
 | 
			
		||||
// nng_atomic_cas is a compare and swap.  The second argument is the
 | 
			
		||||
// value to compare against, and the third is the new value. Returns
 | 
			
		||||
// true if the value was set.
 | 
			
		||||
NNG_DECL bool nng_atomic_cas(nng_atomic_int *, int, int);
 | 
			
		||||
 | 
			
		||||
// atomic pointers.  We only support a few operations.
 | 
			
		||||
typedef struct nni_atomic_ptr nng_atomic_ptr;
 | 
			
		||||
NNG_DECL int                  nng_atomic_alloc_ptr(nng_atomic_ptr **v);
 | 
			
		||||
NNG_DECL void                 nng_atomic_free_ptr(nng_atomic_ptr *v);
 | 
			
		||||
NNG_DECL void                 nng_atomic_set_ptr(nng_atomic_ptr *, void *);
 | 
			
		||||
NNG_DECL void *               nng_atomic_get_ptr(nng_atomic_ptr *);
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // NNG_SUPPLEMENTAL_UTIL_PLATFORM_H
 | 
			
		||||
@@ -0,0 +1,29 @@
 | 
			
		||||
//
 | 
			
		||||
// Copyright 2021 Staysail Systems, Inc. <info@staysail.tech>
 | 
			
		||||
// Copyright 2017 Capitar IT Group BV <info@capitar.com>
 | 
			
		||||
//
 | 
			
		||||
// 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 NNG_TRANSPORT_INPROC_INPROC_H
 | 
			
		||||
#define NNG_TRANSPORT_INPROC_INPROC_H
 | 
			
		||||
 | 
			
		||||
#include <nng/nng.h>
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// inproc transport.  This is used for intra-process communication.
 | 
			
		||||
#ifndef NNG_ELIDE_DEPRECATED
 | 
			
		||||
NNG_DECL int nng_inproc_register(void);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // NNG_TRANSPORT_INPROC_INPROC_H
 | 
			
		||||
@@ -0,0 +1,31 @@
 | 
			
		||||
//
 | 
			
		||||
// Copyright 2021 Staysail Systems, Inc. <info@staysail.tech>
 | 
			
		||||
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
 | 
			
		||||
//
 | 
			
		||||
// 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 NNG_TRANSPORT_IPC_IPC_H
 | 
			
		||||
#define NNG_TRANSPORT_IPC_IPC_H
 | 
			
		||||
 | 
			
		||||
#include <nng/nng.h>
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// ipc transport.  This is used for inter-process communication on
 | 
			
		||||
// the same host computer.
 | 
			
		||||
 | 
			
		||||
#ifndef NNG_ELIDE_DEPRECATED
 | 
			
		||||
NNG_DECL int nng_ipc_register(void);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // NNG_TRANSPORT_IPC_IPC_H
 | 
			
		||||
@@ -0,0 +1,30 @@
 | 
			
		||||
//
 | 
			
		||||
// Copyright 2021 Staysail Systems, Inc. <info@staysail.tech>
 | 
			
		||||
// Copyright 2017 Capitar IT Group BV <info@capitar.com>
 | 
			
		||||
//
 | 
			
		||||
// 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 NNG_TRANSPORT_MQTT_BROKER_TCP_TCP_H
 | 
			
		||||
#define NNG_TRANSPORT_MQTT_BROKER_TCP_TCP_H
 | 
			
		||||
 | 
			
		||||
#include <nng/nng.h>
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// TCP transport.  This is used for communication over TCP/IP.
 | 
			
		||||
 | 
			
		||||
#ifndef NNG_ELIDE_DEPRECATED
 | 
			
		||||
NNG_DECL int nmq_mqtt_tcp_register(void);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // NNG_TRANSPORT_MQTT_TCP_TCP_H
 | 
			
		||||
@@ -0,0 +1,30 @@
 | 
			
		||||
//
 | 
			
		||||
// Copyright 2021 Staysail Systems, Inc. <info@staysail.tech>
 | 
			
		||||
// Copyright 2017 Capitar IT Group BV <info@capitar.com>
 | 
			
		||||
//
 | 
			
		||||
// 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 NNG_TRANSPORT_MQTT_BROKER_TLS_TCP_H
 | 
			
		||||
#define NNG_TRANSPORT_MQTT_BROKER_TLS_TCP_H
 | 
			
		||||
 | 
			
		||||
#include <nng/nng.h>
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// TLS transport.  This is used for communication over TLS.
 | 
			
		||||
 | 
			
		||||
#ifndef NNG_ELIDE_DEPRECATED
 | 
			
		||||
NNG_DECL int nmq_mqtt_tls_register(void);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // NNG_TRANSPORT_MQTT_BROKER_TLS_TCP_H
 | 
			
		||||
@@ -0,0 +1,35 @@
 | 
			
		||||
//
 | 
			
		||||
// Copyright 2021 Staysail Systems, Inc. <info@staysail.tech>
 | 
			
		||||
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
 | 
			
		||||
//
 | 
			
		||||
// 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 NNG_TRANSPORT_WS_WEBSOCKET_H
 | 
			
		||||
#define NNG_TRANSPORT_WS_WEBSOCKET_H
 | 
			
		||||
 | 
			
		||||
#include <nng/nng.h>
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// WebSocket transport.  This is used for communication via WebSocket.
 | 
			
		||||
 | 
			
		||||
// These aliases are for WSS naming consistency.
 | 
			
		||||
#define NNG_OPT_WSS_REQUEST_HEADERS NNG_OPT_WS_REQUEST_HEADERS
 | 
			
		||||
#define NNG_OPT_WSS_RESPONSE_HEADERS NNG_OPT_WS_RESPONSE_HEADERS
 | 
			
		||||
 | 
			
		||||
#ifndef NNG_ELIDE_DEPRECATED
 | 
			
		||||
NNG_DECL int nng_nmq_ws_register(void);
 | 
			
		||||
NNG_DECL int nng_nmq_wss_register(void);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // NNG_TRANSPORT_WS_WEBSOCKET_H
 | 
			
		||||
@@ -0,0 +1,30 @@
 | 
			
		||||
//
 | 
			
		||||
// Copyright 2021 Staysail Systems, Inc. <info@staysail.tech>
 | 
			
		||||
// Copyright 2017 Capitar IT Group BV <info@capitar.com>
 | 
			
		||||
//
 | 
			
		||||
// 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 NNG_TRANSPORT_TCP_TCP_H
 | 
			
		||||
#define NNG_TRANSPORT_TCP_TCP_H
 | 
			
		||||
 | 
			
		||||
#include <nng/nng.h>
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// TCP transport.  This is used for communication over TCP/IP.
 | 
			
		||||
 | 
			
		||||
#ifndef NNG_ELIDE_DEPRECATED
 | 
			
		||||
NNG_DECL int nng_tcp_register(void);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // NNG_TRANSPORT_TCP_TCP_H
 | 
			
		||||
@@ -0,0 +1,30 @@
 | 
			
		||||
//
 | 
			
		||||
// Copyright 2019 Staysail Systems, Inc. <info@staysail.tech>
 | 
			
		||||
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
 | 
			
		||||
//
 | 
			
		||||
// 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 NNG_TRANSPORT_TLS_TLS_H
 | 
			
		||||
#define NNG_TRANSPORT_TLS_TLS_H
 | 
			
		||||
 | 
			
		||||
#include <nng/nng.h>
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// TLS transport.  This is used for communication via TLS v1.2 over TCP/IP.
 | 
			
		||||
 | 
			
		||||
#ifndef NNG_ELIDE_DEPRECATED
 | 
			
		||||
NNG_DECL int nng_tls_register(void);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // NNG_TRANSPORT_TLS_TLS_H
 | 
			
		||||
@@ -0,0 +1,35 @@
 | 
			
		||||
//
 | 
			
		||||
// Copyright 2021 Staysail Systems, Inc. <info@staysail.tech>
 | 
			
		||||
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
 | 
			
		||||
//
 | 
			
		||||
// 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 NNG_TRANSPORT_WS_WEBSOCKET_H
 | 
			
		||||
#define NNG_TRANSPORT_WS_WEBSOCKET_H
 | 
			
		||||
 | 
			
		||||
#include <nng/nng.h>
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// WebSocket transport.  This is used for communication via WebSocket.
 | 
			
		||||
 | 
			
		||||
// These aliases are for WSS naming consistency.
 | 
			
		||||
#define NNG_OPT_WSS_REQUEST_HEADERS NNG_OPT_WS_REQUEST_HEADERS
 | 
			
		||||
#define NNG_OPT_WSS_RESPONSE_HEADERS NNG_OPT_WS_RESPONSE_HEADERS
 | 
			
		||||
 | 
			
		||||
#ifndef NNG_ELIDE_DEPRECATED
 | 
			
		||||
NNG_DECL int nng_ws_register(void);
 | 
			
		||||
NNG_DECL int nng_wss_register(void);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // NNG_TRANSPORT_WS_WEBSOCKET_H
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user