2014-05-07 22:27:00 +00:00
|
|
|
/*
|
2018-04-11 14:24:29 +00:00
|
|
|
Copyright (c) 2009-2018 Roger Light <roger@atchoo.org>
|
2014-05-07 22:27:00 +00:00
|
|
|
|
|
|
|
All rights reserved. This program and the accompanying materials
|
|
|
|
are made available under the terms of the Eclipse Public License v1.0
|
|
|
|
and Eclipse Distribution License v1.0 which accompany this distribution.
|
|
|
|
|
|
|
|
The Eclipse Public License is available at
|
|
|
|
http://www.eclipse.org/legal/epl-v10.html
|
|
|
|
and the Eclipse Distribution License is available at
|
|
|
|
http://www.eclipse.org/org/documents/edl-v10.php.
|
|
|
|
|
|
|
|
Contributors:
|
|
|
|
Roger Light - initial implementation and documentation.
|
2017-07-27 17:43:09 +00:00
|
|
|
Tatsuzo Osawa - Add epoll.
|
2014-05-07 22:27:00 +00:00
|
|
|
*/
|
|
|
|
|
2017-03-06 21:19:53 +00:00
|
|
|
#ifndef MOSQUITTO_BROKER_INTERNAL_H
|
|
|
|
#define MOSQUITTO_BROKER_INTERNAL_H
|
2014-05-07 22:27:00 +00:00
|
|
|
|
2015-04-29 20:37:47 +00:00
|
|
|
#include "config.h"
|
2014-05-07 22:27:00 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
|
2015-12-19 01:21:17 +00:00
|
|
|
#ifdef WITH_WEBSOCKETS
|
|
|
|
# include <libwebsockets.h>
|
|
|
|
|
|
|
|
# if defined(LWS_LIBRARY_VERSION_NUMBER)
|
|
|
|
# define libwebsocket_callback_on_writable(A, B) lws_callback_on_writable((B))
|
|
|
|
# define libwebsocket_service(A, B) lws_service((A), (B))
|
|
|
|
# define libwebsocket_create_context(A) lws_create_context((A))
|
|
|
|
# define libwebsocket_context_destroy(A) lws_context_destroy((A))
|
|
|
|
# define libwebsocket_write(A, B, C, D) lws_write((A), (B), (C), (D))
|
|
|
|
# define libwebsocket_get_socket_fd(A) lws_get_socket_fd((A))
|
|
|
|
# define libwebsockets_return_http_status(A, B, C, D) lws_return_http_status((B), (C), (D))
|
2017-03-06 21:19:53 +00:00
|
|
|
# define libwebsockets_get_protocol(A) lws_get_protocol((A))
|
2015-12-19 01:21:17 +00:00
|
|
|
# define libwebsocket_context lws_context
|
|
|
|
# define libwebsocket_protocols lws_protocols
|
|
|
|
# define libwebsocket_callback_reasons lws_callback_reasons
|
|
|
|
# define libwebsocket lws
|
2018-08-14 16:20:22 +00:00
|
|
|
# else
|
|
|
|
# define lws_pollfd pollfd
|
|
|
|
# define lws_service_fd(A, B) libwebsocket_service_fd((A), (B))
|
|
|
|
# define lws_pollargs libwebsocket_pollargs
|
2015-12-19 01:21:17 +00:00
|
|
|
# endif
|
|
|
|
#endif
|
|
|
|
|
2015-04-29 20:37:47 +00:00
|
|
|
#include "mosquitto_internal.h"
|
2016-07-08 21:04:39 +00:00
|
|
|
#include "mosquitto_broker.h"
|
2015-04-29 20:37:47 +00:00
|
|
|
#include "mosquitto_plugin.h"
|
|
|
|
#include "mosquitto.h"
|
2014-05-07 22:27:00 +00:00
|
|
|
#include "tls_mosq.h"
|
|
|
|
#include "uthash.h"
|
|
|
|
|
2015-04-19 21:10:59 +00:00
|
|
|
#define uhpa_malloc(size) mosquitto__malloc(size)
|
|
|
|
#define uhpa_free(ptr) mosquitto__free(ptr)
|
2015-04-01 08:35:40 +00:00
|
|
|
#include "uhpa.h"
|
|
|
|
|
2014-05-07 22:27:00 +00:00
|
|
|
#ifndef __GNUC__
|
|
|
|
#define __attribute__(attrib)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Log destinations */
|
|
|
|
#define MQTT3_LOG_NONE 0x00
|
|
|
|
#define MQTT3_LOG_SYSLOG 0x01
|
|
|
|
#define MQTT3_LOG_FILE 0x02
|
|
|
|
#define MQTT3_LOG_STDOUT 0x04
|
|
|
|
#define MQTT3_LOG_STDERR 0x08
|
|
|
|
#define MQTT3_LOG_TOPIC 0x10
|
|
|
|
#define MQTT3_LOG_ALL 0xFF
|
|
|
|
|
2014-06-29 22:16:10 +00:00
|
|
|
#define WEBSOCKET_CLIENT -2
|
|
|
|
|
2015-04-01 08:35:40 +00:00
|
|
|
/* ========================================
|
|
|
|
* UHPA data types
|
|
|
|
* ======================================== */
|
2015-04-04 22:58:18 +00:00
|
|
|
|
|
|
|
/* See uhpa.h
|
|
|
|
*
|
|
|
|
* The idea here is that there is potentially a lot of wasted space (and time)
|
|
|
|
* in malloc calls for frequent, small heap allocations. This can happen if
|
|
|
|
* small payloads are used by clients or if individual topic elements are
|
|
|
|
* small.
|
|
|
|
*
|
|
|
|
* In both cases, a struct is used that includes a void* or char* pointer to
|
|
|
|
* point to the dynamically allocated memory used. To allocate and store a
|
|
|
|
* single byte needs the size of the pointer (8 bytes on a 64 bit
|
|
|
|
* architecture), the malloc overhead and the memory allocated itself (which
|
|
|
|
* will often be larger than the memory requested, on 64 bit Linux this can be
|
|
|
|
* a minimum of 24 bytes). To allocate and store 1 byte of heap memory we need
|
|
|
|
* in this example 32 bytes.
|
|
|
|
*
|
|
|
|
* UHPA uses a union to either store data in an array, or to allocate memory on
|
|
|
|
* the heap, depending on the size of the data being stored (this does mean
|
|
|
|
* that the size of the data must always be known). Setting the size of the
|
|
|
|
* array changes the point at which heap allocation starts. Using the example
|
|
|
|
* above, this means that an array size of 32 bytes should not result in any
|
|
|
|
* wasted space, and should be quicker as well. Certainly in the case of topic
|
|
|
|
* elements (e.g. "bar" out of "foo/bar/baz") it is likely that an array size
|
|
|
|
* of 32 bytes will mean that the majority of heap allocations are removed.
|
|
|
|
*
|
2015-04-11 20:17:16 +00:00
|
|
|
* You can change the size of MOSQ_PAYLOAD_UNION_SIZE and
|
|
|
|
* MOSQ_TOPIC_ELEMENT_UNION_SIZE to change the size of the uhpa array used for
|
|
|
|
* the payload (i.e. the published part of a message) and for topic elements
|
|
|
|
* (e.g. "foo", "bar" or "baz" in the topic "foo/bar/baz"), and so control the
|
|
|
|
* heap allocation threshold for these data types. You should look at your
|
2015-04-04 22:58:18 +00:00
|
|
|
* application to decide what values to set, but don't set them too high
|
|
|
|
* otherwise your overall memory usage will increase.
|
|
|
|
*
|
|
|
|
* You could use something like heaptrack
|
|
|
|
* http://milianw.de/blog/heaptrack-a-heap-memory-profiler-for-linux to
|
|
|
|
* profile heap allocations.
|
|
|
|
*
|
|
|
|
* I would suggest that values for MOSQ_PAYLOAD_UNION_SIZE and
|
|
|
|
* MOSQ_TOPIC_UNION_SIZE that are equivalent to
|
|
|
|
* sizeof(void*)+malloc_usable_size(malloc(1)) are a safe value that should
|
|
|
|
* reduce calls to malloc without increasing memory usage at all.
|
|
|
|
*/
|
2015-04-01 08:35:40 +00:00
|
|
|
#define MOSQ_PAYLOAD_UNION_SIZE 8
|
|
|
|
typedef union {
|
|
|
|
void *ptr;
|
|
|
|
char array[MOSQ_PAYLOAD_UNION_SIZE];
|
|
|
|
} mosquitto__payload_uhpa;
|
2015-04-05 09:02:16 +00:00
|
|
|
#define UHPA_ALLOC_PAYLOAD(A) UHPA_ALLOC((A)->payload, (A)->payloadlen)
|
|
|
|
#define UHPA_ACCESS_PAYLOAD(A) UHPA_ACCESS((A)->payload, (A)->payloadlen)
|
|
|
|
#define UHPA_FREE_PAYLOAD(A) UHPA_FREE((A)->payload, (A)->payloadlen)
|
2015-06-28 15:59:03 +00:00
|
|
|
#define UHPA_MOVE_PAYLOAD(DEST, SRC) UHPA_MOVE((DEST)->payload, (SRC)->payload, (SRC)->payloadlen)
|
2015-04-04 20:15:27 +00:00
|
|
|
|
2015-04-11 20:17:16 +00:00
|
|
|
#define MOSQ_TOPIC_ELEMENT_UNION_SIZE 8
|
2015-04-04 20:15:27 +00:00
|
|
|
typedef union {
|
|
|
|
char *ptr;
|
2015-04-11 20:17:16 +00:00
|
|
|
char array[MOSQ_TOPIC_ELEMENT_UNION_SIZE];
|
|
|
|
} mosquitto__topic_element_uhpa;
|
2015-04-04 20:15:27 +00:00
|
|
|
#define UHPA_ALLOC_TOPIC(A) UHPA_ALLOC((A)->topic, (A)->topic_len+1)
|
|
|
|
#define UHPA_ACCESS_TOPIC(A) UHPA_ACCESS((A)->topic, (A)->topic_len+1)
|
|
|
|
#define UHPA_FREE_TOPIC(A) UHPA_FREE((A)->topic, (A)->topic_len+1)
|
2015-06-28 15:59:03 +00:00
|
|
|
#define UHPA_MOVE_TOPIC(DEST, SRC) UHPA_MOVE((DEST)->topic, (SRC)->topic, (SRC)->topic_len+1)
|
2015-04-04 20:15:27 +00:00
|
|
|
|
2015-04-01 08:35:40 +00:00
|
|
|
/* ========================================
|
|
|
|
* End UHPA data types
|
|
|
|
* ======================================== */
|
|
|
|
|
2014-05-07 22:27:00 +00:00
|
|
|
typedef uint64_t dbid_t;
|
|
|
|
|
2018-03-26 14:23:00 +00:00
|
|
|
typedef int (*FUNC_auth_plugin_init_v3)(void **, struct mosquitto_opt *, int);
|
|
|
|
typedef int (*FUNC_auth_plugin_cleanup_v3)(void *, struct mosquitto_opt *, int);
|
|
|
|
typedef int (*FUNC_auth_plugin_security_init_v3)(void *, struct mosquitto_opt *, int, bool);
|
|
|
|
typedef int (*FUNC_auth_plugin_security_cleanup_v3)(void *, struct mosquitto_opt *, int, bool);
|
|
|
|
typedef int (*FUNC_auth_plugin_acl_check_v3)(void *, int, const struct mosquitto *, struct mosquitto_acl_msg *);
|
|
|
|
typedef int (*FUNC_auth_plugin_unpwd_check_v3)(void *, const struct mosquitto *, const char *, const char *);
|
|
|
|
typedef int (*FUNC_auth_plugin_psk_key_get_v3)(void *, const struct mosquitto *, const char *, const char *, char *, int);
|
|
|
|
|
|
|
|
typedef int (*FUNC_auth_plugin_init_v2)(void **, struct mosquitto_auth_opt *, int);
|
|
|
|
typedef int (*FUNC_auth_plugin_cleanup_v2)(void *, struct mosquitto_auth_opt *, int);
|
|
|
|
typedef int (*FUNC_auth_plugin_security_init_v2)(void *, struct mosquitto_auth_opt *, int, bool);
|
|
|
|
typedef int (*FUNC_auth_plugin_security_cleanup_v2)(void *, struct mosquitto_auth_opt *, int, bool);
|
|
|
|
typedef int (*FUNC_auth_plugin_acl_check_v2)(void *, const char *, const char *, const char *, int);
|
|
|
|
typedef int (*FUNC_auth_plugin_unpwd_check_v2)(void *, const char *, const char *);
|
|
|
|
typedef int (*FUNC_auth_plugin_psk_key_get_v2)(void *, const char *, const char *, char *, int);
|
|
|
|
|
|
|
|
struct mosquitto__auth_plugin{
|
|
|
|
void *lib;
|
|
|
|
void *user_data;
|
|
|
|
int (*plugin_version)(void);
|
|
|
|
|
|
|
|
FUNC_auth_plugin_init_v3 plugin_init_v3;
|
|
|
|
FUNC_auth_plugin_cleanup_v3 plugin_cleanup_v3;
|
|
|
|
FUNC_auth_plugin_security_init_v3 security_init_v3;
|
|
|
|
FUNC_auth_plugin_security_cleanup_v3 security_cleanup_v3;
|
|
|
|
FUNC_auth_plugin_acl_check_v3 acl_check_v3;
|
|
|
|
FUNC_auth_plugin_unpwd_check_v3 unpwd_check_v3;
|
|
|
|
FUNC_auth_plugin_psk_key_get_v3 psk_key_get_v3;
|
|
|
|
|
|
|
|
FUNC_auth_plugin_init_v2 plugin_init_v2;
|
|
|
|
FUNC_auth_plugin_cleanup_v2 plugin_cleanup_v2;
|
|
|
|
FUNC_auth_plugin_security_init_v2 security_init_v2;
|
|
|
|
FUNC_auth_plugin_security_cleanup_v2 security_cleanup_v2;
|
|
|
|
FUNC_auth_plugin_acl_check_v2 acl_check_v2;
|
|
|
|
FUNC_auth_plugin_unpwd_check_v2 unpwd_check_v2;
|
|
|
|
FUNC_auth_plugin_psk_key_get_v2 psk_key_get_v2;
|
|
|
|
int version;
|
|
|
|
};
|
|
|
|
|
2018-03-13 17:44:33 +00:00
|
|
|
struct mosquitto__auth_plugin_config
|
|
|
|
{
|
|
|
|
char *path;
|
|
|
|
struct mosquitto_opt *options;
|
|
|
|
int option_count;
|
|
|
|
bool deny_special_chars;
|
2018-03-26 14:23:00 +00:00
|
|
|
|
|
|
|
struct mosquitto__auth_plugin plugin;
|
2018-03-13 17:44:33 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct mosquitto__security_options {
|
2018-03-15 14:29:07 +00:00
|
|
|
/* Any options that get added here also need considering
|
|
|
|
* in config__read() with regards whether allow_anonymous
|
|
|
|
* should be disabled when these options are set.
|
|
|
|
*/
|
2018-05-01 21:36:13 +00:00
|
|
|
struct mosquitto__acl_user *acl_list;
|
|
|
|
struct mosquitto__acl *acl_patterns;
|
2018-03-13 17:44:33 +00:00
|
|
|
char *password_file;
|
|
|
|
char *psk_file;
|
2018-05-01 21:36:13 +00:00
|
|
|
char *acl_file;
|
2018-03-25 20:49:14 +00:00
|
|
|
struct mosquitto__auth_plugin_config *auth_plugin_configs;
|
|
|
|
int auth_plugin_config_count;
|
2018-08-02 16:06:21 +00:00
|
|
|
int8_t allow_anonymous;
|
2018-03-18 21:23:50 +00:00
|
|
|
bool allow_zero_length_clientid;
|
2018-03-18 21:07:04 +00:00
|
|
|
char *auto_id_prefix;
|
|
|
|
int auto_id_prefix_len;
|
2018-03-13 17:44:33 +00:00
|
|
|
};
|
|
|
|
|
2015-05-16 18:03:12 +00:00
|
|
|
struct mosquitto__listener {
|
2014-05-07 22:27:00 +00:00
|
|
|
int fd;
|
|
|
|
uint16_t port;
|
2017-08-11 23:25:59 +00:00
|
|
|
char *host;
|
2014-05-07 22:27:00 +00:00
|
|
|
int max_connections;
|
|
|
|
char *mount_point;
|
2015-03-29 09:43:08 +00:00
|
|
|
mosq_sock_t *socks;
|
2014-05-07 22:27:00 +00:00
|
|
|
int sock_count;
|
|
|
|
int client_count;
|
2014-05-18 21:40:20 +00:00
|
|
|
enum mosquitto_protocol protocol;
|
2014-07-01 23:09:50 +00:00
|
|
|
bool use_username_as_clientid;
|
2014-05-07 22:27:00 +00:00
|
|
|
#ifdef WITH_TLS
|
|
|
|
char *cafile;
|
|
|
|
char *capath;
|
|
|
|
char *certfile;
|
|
|
|
char *keyfile;
|
|
|
|
char *ciphers;
|
|
|
|
char *psk_hint;
|
|
|
|
SSL_CTX *ssl_ctx;
|
|
|
|
char *crlfile;
|
|
|
|
bool use_identity_as_username;
|
2015-06-05 11:33:07 +00:00
|
|
|
bool use_subject_as_username;
|
2017-08-11 23:25:59 +00:00
|
|
|
bool require_certificate;
|
2014-05-07 22:27:00 +00:00
|
|
|
char *tls_version;
|
|
|
|
#endif
|
2014-05-18 21:40:20 +00:00
|
|
|
#ifdef WITH_WEBSOCKETS
|
|
|
|
struct libwebsocket_context *ws_context;
|
2014-09-08 17:21:53 +00:00
|
|
|
char *http_dir;
|
2014-09-17 20:50:08 +00:00
|
|
|
struct libwebsocket_protocols *ws_protocol;
|
2014-05-18 21:40:20 +00:00
|
|
|
#endif
|
2018-03-13 17:44:33 +00:00
|
|
|
struct mosquitto__security_options security_options;
|
|
|
|
struct mosquitto__unpwd *unpwd;
|
2018-03-15 21:39:42 +00:00
|
|
|
struct mosquitto__unpwd *psk_id;
|
2015-06-29 21:22:28 +00:00
|
|
|
};
|
|
|
|
|
2015-05-16 18:03:12 +00:00
|
|
|
struct mosquitto__config {
|
2014-05-07 22:27:00 +00:00
|
|
|
bool allow_duplicate_messages;
|
|
|
|
int autosave_interval;
|
|
|
|
bool autosave_on_changes;
|
|
|
|
char *clientid_prefixes;
|
|
|
|
bool connection_messages;
|
|
|
|
bool daemon;
|
2015-05-16 18:03:12 +00:00
|
|
|
struct mosquitto__listener default_listener;
|
|
|
|
struct mosquitto__listener *listeners;
|
2014-05-07 22:27:00 +00:00
|
|
|
int listener_count;
|
|
|
|
int log_dest;
|
2014-11-02 21:49:33 +00:00
|
|
|
int log_facility;
|
2014-05-07 22:27:00 +00:00
|
|
|
int log_type;
|
|
|
|
bool log_timestamp;
|
|
|
|
char *log_file;
|
|
|
|
FILE *log_fptr;
|
2015-03-08 21:00:15 +00:00
|
|
|
uint32_t message_size_limit;
|
2014-05-07 22:27:00 +00:00
|
|
|
bool persistence;
|
|
|
|
char *persistence_location;
|
|
|
|
char *persistence_file;
|
|
|
|
char *persistence_filepath;
|
|
|
|
time_t persistent_client_expiration;
|
|
|
|
char *pid_file;
|
|
|
|
bool queue_qos0_messages;
|
2018-03-08 22:03:25 +00:00
|
|
|
bool per_listener_settings;
|
2018-02-14 23:51:16 +00:00
|
|
|
bool set_tcp_nodelay;
|
2014-05-07 22:27:00 +00:00
|
|
|
int sys_interval;
|
|
|
|
bool upgrade_outgoing_qos;
|
|
|
|
char *user;
|
2015-02-13 22:57:49 +00:00
|
|
|
#ifdef WITH_WEBSOCKETS
|
|
|
|
int websockets_log_level;
|
2015-03-27 20:50:16 +00:00
|
|
|
bool have_websockets_listener;
|
2015-02-13 22:57:49 +00:00
|
|
|
#endif
|
2014-05-07 22:27:00 +00:00
|
|
|
#ifdef WITH_BRIDGE
|
2015-05-16 18:03:12 +00:00
|
|
|
struct mosquitto__bridge *bridges;
|
2014-05-07 22:27:00 +00:00
|
|
|
int bridge_count;
|
|
|
|
#endif
|
2018-03-13 17:44:33 +00:00
|
|
|
struct mosquitto__security_options security_options;
|
2014-05-07 22:27:00 +00:00
|
|
|
};
|
|
|
|
|
2015-04-19 21:10:59 +00:00
|
|
|
struct mosquitto__subleaf {
|
|
|
|
struct mosquitto__subleaf *prev;
|
|
|
|
struct mosquitto__subleaf *next;
|
2014-05-07 22:27:00 +00:00
|
|
|
struct mosquitto *context;
|
|
|
|
int qos;
|
|
|
|
};
|
|
|
|
|
2015-04-19 21:10:59 +00:00
|
|
|
struct mosquitto__subhier {
|
2016-07-19 14:05:53 +00:00
|
|
|
UT_hash_handle hh;
|
2015-09-03 16:46:55 +00:00
|
|
|
struct mosquitto__subhier *parent;
|
2015-04-19 21:10:59 +00:00
|
|
|
struct mosquitto__subhier *children;
|
|
|
|
struct mosquitto__subleaf *subs;
|
2014-05-07 22:27:00 +00:00
|
|
|
struct mosquitto_msg_store *retained;
|
2015-04-11 20:17:16 +00:00
|
|
|
mosquitto__topic_element_uhpa topic;
|
2015-04-04 20:15:27 +00:00
|
|
|
uint16_t topic_len;
|
2014-05-07 22:27:00 +00:00
|
|
|
};
|
|
|
|
|
2014-11-18 19:12:08 +00:00
|
|
|
struct mosquitto_msg_store_load{
|
2014-11-17 22:54:39 +00:00
|
|
|
UT_hash_handle hh;
|
2014-05-07 22:27:00 +00:00
|
|
|
dbid_t db_id;
|
2014-11-18 19:12:08 +00:00
|
|
|
struct mosquitto_msg_store *store;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct mosquitto_msg_store{
|
|
|
|
struct mosquitto_msg_store *next;
|
|
|
|
struct mosquitto_msg_store *prev;
|
|
|
|
dbid_t db_id;
|
2014-05-07 22:27:00 +00:00
|
|
|
char *source_id;
|
|
|
|
char **dest_ids;
|
|
|
|
int dest_id_count;
|
2014-11-18 07:42:49 +00:00
|
|
|
int ref_count;
|
2015-04-11 20:17:16 +00:00
|
|
|
char* topic;
|
2015-04-01 08:35:40 +00:00
|
|
|
mosquitto__payload_uhpa payload;
|
2014-11-18 07:42:49 +00:00
|
|
|
uint32_t payloadlen;
|
2014-05-07 22:27:00 +00:00
|
|
|
uint16_t source_mid;
|
2014-11-18 07:42:49 +00:00
|
|
|
uint16_t mid;
|
|
|
|
uint8_t qos;
|
|
|
|
bool retain;
|
2014-05-07 22:27:00 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct mosquitto_client_msg{
|
|
|
|
struct mosquitto_client_msg *next;
|
|
|
|
struct mosquitto_msg_store *store;
|
2014-11-18 07:42:49 +00:00
|
|
|
time_t timestamp;
|
2014-05-07 22:27:00 +00:00
|
|
|
uint16_t mid;
|
2014-11-18 07:42:49 +00:00
|
|
|
uint8_t qos;
|
2014-05-07 22:27:00 +00:00
|
|
|
bool retain;
|
|
|
|
enum mosquitto_msg_direction direction;
|
|
|
|
enum mosquitto_msg_state state;
|
|
|
|
bool dup;
|
|
|
|
};
|
|
|
|
|
2015-04-19 21:10:59 +00:00
|
|
|
struct mosquitto__unpwd{
|
2014-05-07 22:27:00 +00:00
|
|
|
char *username;
|
|
|
|
char *password;
|
|
|
|
#ifdef WITH_TLS
|
|
|
|
unsigned int password_len;
|
|
|
|
unsigned int salt_len;
|
2014-11-18 07:42:49 +00:00
|
|
|
unsigned char *salt;
|
2014-05-07 22:27:00 +00:00
|
|
|
#endif
|
|
|
|
UT_hash_handle hh;
|
|
|
|
};
|
|
|
|
|
2015-04-19 21:10:59 +00:00
|
|
|
struct mosquitto__acl{
|
|
|
|
struct mosquitto__acl *next;
|
2014-05-07 22:27:00 +00:00
|
|
|
char *topic;
|
|
|
|
int access;
|
2014-05-08 22:03:15 +00:00
|
|
|
int ucount;
|
|
|
|
int ccount;
|
2014-05-07 22:27:00 +00:00
|
|
|
};
|
|
|
|
|
2015-04-19 21:10:59 +00:00
|
|
|
struct mosquitto__acl_user{
|
|
|
|
struct mosquitto__acl_user *next;
|
2014-05-07 22:27:00 +00:00
|
|
|
char *username;
|
2015-04-19 21:10:59 +00:00
|
|
|
struct mosquitto__acl *acl;
|
2014-05-07 22:27:00 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct mosquitto_db{
|
|
|
|
dbid_t last_db_id;
|
2016-07-19 14:05:53 +00:00
|
|
|
struct mosquitto__subhier *subs;
|
2015-04-19 21:10:59 +00:00
|
|
|
struct mosquitto__unpwd *unpwd;
|
|
|
|
struct mosquitto__unpwd *psk_id;
|
2014-06-23 16:57:35 +00:00
|
|
|
struct mosquitto *contexts_by_id;
|
|
|
|
struct mosquitto *contexts_by_sock;
|
|
|
|
struct mosquitto *contexts_for_free;
|
2014-11-18 23:34:54 +00:00
|
|
|
#ifdef WITH_BRIDGE
|
|
|
|
struct mosquitto **bridges;
|
|
|
|
#endif
|
2015-04-19 21:10:59 +00:00
|
|
|
struct clientid__index_hash *clientid_index_hash;
|
2014-05-07 22:27:00 +00:00
|
|
|
struct mosquitto_msg_store *msg_store;
|
2014-11-18 19:12:08 +00:00
|
|
|
struct mosquitto_msg_store_load *msg_store_load;
|
2014-11-18 23:34:54 +00:00
|
|
|
#ifdef WITH_BRIDGE
|
|
|
|
int bridge_count;
|
|
|
|
#endif
|
2014-05-07 22:27:00 +00:00
|
|
|
int msg_store_count;
|
2017-08-11 23:25:59 +00:00
|
|
|
unsigned long msg_store_bytes;
|
2018-05-02 22:56:11 +00:00
|
|
|
char *config_file;
|
2015-05-16 18:03:12 +00:00
|
|
|
struct mosquitto__config *config;
|
2015-06-29 21:22:28 +00:00
|
|
|
int auth_plugin_count;
|
2018-05-02 22:56:11 +00:00
|
|
|
bool verbose;
|
2014-09-16 22:48:26 +00:00
|
|
|
#ifdef WITH_SYS_TREE
|
2014-05-07 22:27:00 +00:00
|
|
|
int subscription_count;
|
|
|
|
int retained_count;
|
2014-06-02 21:08:40 +00:00
|
|
|
#endif
|
2017-08-11 23:25:59 +00:00
|
|
|
int persistence_changes;
|
2014-09-22 22:35:09 +00:00
|
|
|
struct mosquitto *ll_for_free;
|
2017-07-27 17:43:09 +00:00
|
|
|
#ifdef WITH_EPOLL
|
|
|
|
int epollfd;
|
|
|
|
#endif
|
2018-09-18 10:54:58 +00:00
|
|
|
mosq_sock_t spare_sock;
|
2014-05-07 22:27:00 +00:00
|
|
|
};
|
|
|
|
|
2015-05-16 18:03:12 +00:00
|
|
|
enum mosquitto__bridge_direction{
|
2014-05-07 22:27:00 +00:00
|
|
|
bd_out = 0,
|
|
|
|
bd_in = 1,
|
|
|
|
bd_both = 2
|
|
|
|
};
|
|
|
|
|
|
|
|
enum mosquitto_bridge_start_type{
|
|
|
|
bst_automatic = 0,
|
|
|
|
bst_lazy = 1,
|
|
|
|
bst_manual = 2,
|
|
|
|
bst_once = 3
|
|
|
|
};
|
|
|
|
|
2015-05-16 18:03:12 +00:00
|
|
|
struct mosquitto__bridge_topic{
|
2014-05-07 22:27:00 +00:00
|
|
|
char *topic;
|
|
|
|
int qos;
|
2015-05-16 18:03:12 +00:00
|
|
|
enum mosquitto__bridge_direction direction;
|
2014-05-07 22:27:00 +00:00
|
|
|
char *local_prefix;
|
|
|
|
char *remote_prefix;
|
|
|
|
char *local_topic; /* topic prefixed with local_prefix */
|
|
|
|
char *remote_topic; /* topic prefixed with remote_prefix */
|
|
|
|
};
|
|
|
|
|
|
|
|
struct bridge_address{
|
|
|
|
char *address;
|
|
|
|
int port;
|
|
|
|
};
|
|
|
|
|
2015-05-16 18:03:12 +00:00
|
|
|
struct mosquitto__bridge{
|
2014-05-07 22:27:00 +00:00
|
|
|
char *name;
|
|
|
|
struct bridge_address *addresses;
|
|
|
|
int cur_address;
|
|
|
|
int address_count;
|
|
|
|
time_t primary_retry;
|
|
|
|
bool round_robin;
|
2014-11-18 07:42:49 +00:00
|
|
|
bool try_private;
|
|
|
|
bool try_private_accepted;
|
2014-05-07 22:27:00 +00:00
|
|
|
bool clean_session;
|
2014-11-18 07:42:49 +00:00
|
|
|
int keepalive;
|
2015-05-16 18:03:12 +00:00
|
|
|
struct mosquitto__bridge_topic *topics;
|
2014-05-07 22:27:00 +00:00
|
|
|
int topic_count;
|
|
|
|
bool topic_remapping;
|
2015-04-19 21:10:59 +00:00
|
|
|
enum mosquitto__protocol protocol_version;
|
2014-05-07 22:27:00 +00:00
|
|
|
time_t restart_t;
|
2014-08-16 20:31:12 +00:00
|
|
|
char *remote_clientid;
|
|
|
|
char *remote_username;
|
|
|
|
char *remote_password;
|
2014-06-10 22:30:15 +00:00
|
|
|
char *local_clientid;
|
2014-05-08 17:45:34 +00:00
|
|
|
char *local_username;
|
|
|
|
char *local_password;
|
2017-08-11 23:25:59 +00:00
|
|
|
char *notification_topic;
|
2014-05-07 22:27:00 +00:00
|
|
|
bool notifications;
|
2016-12-04 21:47:38 +00:00
|
|
|
bool notifications_local_only;
|
2014-05-07 22:27:00 +00:00
|
|
|
enum mosquitto_bridge_start_type start_type;
|
|
|
|
int idle_timeout;
|
|
|
|
int restart_timeout;
|
|
|
|
int threshold;
|
|
|
|
bool lazy_reconnect;
|
2015-01-07 21:50:10 +00:00
|
|
|
bool attempt_unsubscribe;
|
2015-05-16 11:02:18 +00:00
|
|
|
bool initial_notification_done;
|
2014-05-07 22:27:00 +00:00
|
|
|
#ifdef WITH_TLS
|
2017-08-11 23:25:59 +00:00
|
|
|
bool tls_insecure;
|
2014-05-07 22:27:00 +00:00
|
|
|
char *tls_cafile;
|
|
|
|
char *tls_capath;
|
|
|
|
char *tls_certfile;
|
|
|
|
char *tls_keyfile;
|
|
|
|
char *tls_version;
|
2018-04-11 16:10:27 +00:00
|
|
|
# ifdef WITH_TLS_PSK
|
2014-05-07 22:27:00 +00:00
|
|
|
char *tls_psk_identity;
|
|
|
|
char *tls_psk;
|
|
|
|
# endif
|
|
|
|
#endif
|
|
|
|
};
|
|
|
|
|
2014-06-30 22:30:43 +00:00
|
|
|
#ifdef WITH_WEBSOCKETS
|
|
|
|
struct libws_mqtt_hack {
|
2014-09-08 17:21:53 +00:00
|
|
|
char *http_dir;
|
2014-06-30 22:30:43 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct libws_mqtt_data {
|
|
|
|
struct mosquitto *mosq;
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
2014-05-07 22:27:00 +00:00
|
|
|
#include <net_mosq.h>
|
|
|
|
|
|
|
|
/* ============================================================
|
|
|
|
* Main functions
|
|
|
|
* ============================================================ */
|
2015-03-29 09:43:08 +00:00
|
|
|
int mosquitto_main_loop(struct mosquitto_db *db, mosq_sock_t *listensock, int listensock_count, int listener_max);
|
2015-04-19 21:10:59 +00:00
|
|
|
struct mosquitto_db *mosquitto__get_db(void);
|
2014-05-07 22:27:00 +00:00
|
|
|
|
|
|
|
/* ============================================================
|
|
|
|
* Config functions
|
|
|
|
* ============================================================ */
|
|
|
|
/* Initialise config struct to default values. */
|
2018-05-02 22:56:11 +00:00
|
|
|
void config__init(struct mosquitto_db *db, struct mosquitto__config *config);
|
2014-05-07 22:27:00 +00:00
|
|
|
/* Parse command line options into config. */
|
2018-05-02 22:56:11 +00:00
|
|
|
int config__parse_args(struct mosquitto_db *db, struct mosquitto__config *config, int argc, char *argv[]);
|
2014-05-07 22:27:00 +00:00
|
|
|
/* Read configuration data from config->config_file into config.
|
|
|
|
* If reload is true, don't process config options that shouldn't be reloaded (listeners etc)
|
|
|
|
* Returns 0 on success, 1 if there is a configuration error or if a file cannot be opened.
|
|
|
|
*/
|
2018-05-02 22:56:11 +00:00
|
|
|
int config__read(struct mosquitto_db *db, struct mosquitto__config *config, bool reload);
|
2014-05-07 22:27:00 +00:00
|
|
|
/* Free all config data. */
|
2015-05-16 18:03:12 +00:00
|
|
|
void config__cleanup(struct mosquitto__config *config);
|
2017-02-19 20:29:04 +00:00
|
|
|
int config__get_dir_files(const char *include_dir, char ***files, int *file_count);
|
2014-05-07 22:27:00 +00:00
|
|
|
|
2015-05-16 18:03:12 +00:00
|
|
|
int drop_privileges(struct mosquitto__config *config, bool temporary);
|
2015-02-08 22:06:11 +00:00
|
|
|
int restore_privileges(void);
|
|
|
|
|
2014-05-07 22:27:00 +00:00
|
|
|
/* ============================================================
|
|
|
|
* Server send functions
|
|
|
|
* ============================================================ */
|
2015-05-16 14:24:24 +00:00
|
|
|
int send__connack(struct mosquitto *context, int ack, int result);
|
|
|
|
int send__suback(struct mosquitto *context, uint16_t mid, uint32_t payloadlen, const void *payload);
|
2014-05-07 22:27:00 +00:00
|
|
|
|
|
|
|
/* ============================================================
|
|
|
|
* Network functions
|
|
|
|
* ============================================================ */
|
2015-09-03 16:46:55 +00:00
|
|
|
int net__socket_accept(struct mosquitto_db *db, mosq_sock_t listensock);
|
2015-05-16 18:03:12 +00:00
|
|
|
int net__socket_listen(struct mosquitto__listener *listener);
|
2015-09-03 16:46:55 +00:00
|
|
|
int net__socket_get_address(mosq_sock_t sock, char *buf, int len);
|
2014-05-07 22:27:00 +00:00
|
|
|
|
|
|
|
/* ============================================================
|
|
|
|
* Read handling functions
|
|
|
|
* ============================================================ */
|
2015-05-18 08:29:22 +00:00
|
|
|
int handle__packet(struct mosquitto_db *db, struct mosquitto *context);
|
2015-05-16 17:43:06 +00:00
|
|
|
int handle__connack(struct mosquitto_db *db, struct mosquitto *context);
|
|
|
|
int handle__connect(struct mosquitto_db *db, struct mosquitto *context);
|
|
|
|
int handle__disconnect(struct mosquitto_db *db, struct mosquitto *context);
|
|
|
|
int handle__publish(struct mosquitto_db *db, struct mosquitto *context);
|
|
|
|
int handle__subscribe(struct mosquitto_db *db, struct mosquitto *context);
|
|
|
|
int handle__unsubscribe(struct mosquitto_db *db, struct mosquitto *context);
|
2014-05-07 22:27:00 +00:00
|
|
|
|
|
|
|
/* ============================================================
|
|
|
|
* Database handling
|
|
|
|
* ============================================================ */
|
2015-05-16 18:03:12 +00:00
|
|
|
int db__open(struct mosquitto__config *config, struct mosquitto_db *db);
|
2015-05-16 14:24:24 +00:00
|
|
|
int db__close(struct mosquitto_db *db);
|
2014-05-07 22:27:00 +00:00
|
|
|
#ifdef WITH_PERSISTENCE
|
2015-05-16 14:24:24 +00:00
|
|
|
int persist__backup(struct mosquitto_db *db, bool shutdown);
|
|
|
|
int persist__restore(struct mosquitto_db *db);
|
2014-05-07 22:27:00 +00:00
|
|
|
#endif
|
2016-06-21 14:47:41 +00:00
|
|
|
void db__limits_set(int inflight, unsigned long inflight_bytes, int queued, unsigned long queued_bytes);
|
2014-05-07 22:27:00 +00:00
|
|
|
/* Return the number of in-flight messages in count. */
|
2015-05-16 14:24:24 +00:00
|
|
|
int db__message_count(int *count);
|
|
|
|
int db__message_delete(struct mosquitto_db *db, struct mosquitto *context, uint16_t mid, enum mosquitto_msg_direction dir);
|
|
|
|
int db__message_insert(struct mosquitto_db *db, struct mosquitto *context, uint16_t mid, enum mosquitto_msg_direction dir, int qos, bool retain, struct mosquitto_msg_store *stored);
|
|
|
|
int db__message_release(struct mosquitto_db *db, struct mosquitto *context, uint16_t mid, enum mosquitto_msg_direction dir);
|
|
|
|
int db__message_update(struct mosquitto *context, uint16_t mid, enum mosquitto_msg_direction dir, enum mosquitto_msg_state state);
|
|
|
|
int db__message_write(struct mosquitto_db *db, struct mosquitto *context);
|
2016-04-18 13:41:47 +00:00
|
|
|
void db__message_dequeue_first(struct mosquitto *context);
|
2015-05-16 14:24:24 +00:00
|
|
|
int db__messages_delete(struct mosquitto_db *db, struct mosquitto *context);
|
|
|
|
int db__messages_easy_queue(struct mosquitto_db *db, struct mosquitto *context, const char *topic, int qos, uint32_t payloadlen, const void *payload, int retain);
|
2015-06-28 21:15:35 +00:00
|
|
|
int db__message_store(struct mosquitto_db *db, const char *source, uint16_t source_mid, char *topic, int qos, uint32_t payloadlen, mosquitto__payload_uhpa *payload, int retain, struct mosquitto_msg_store **stored, dbid_t store_id);
|
2015-05-16 14:24:24 +00:00
|
|
|
int db__message_store_find(struct mosquitto *context, uint16_t mid, struct mosquitto_msg_store **stored);
|
|
|
|
void db__msg_store_add(struct mosquitto_db *db, struct mosquitto_msg_store *store);
|
|
|
|
void db__msg_store_remove(struct mosquitto_db *db, struct mosquitto_msg_store *store);
|
|
|
|
void db__msg_store_deref(struct mosquitto_db *db, struct mosquitto_msg_store **store);
|
|
|
|
void db__msg_store_clean(struct mosquitto_db *db);
|
|
|
|
int db__message_reconnect_reset(struct mosquitto_db *db, struct mosquitto *context);
|
|
|
|
void db__vacuum(void);
|
2016-07-08 08:14:11 +00:00
|
|
|
void sys_tree__init(struct mosquitto_db *db);
|
|
|
|
void sys_tree__update(struct mosquitto_db *db, int interval, time_t start_time);
|
2014-05-07 22:27:00 +00:00
|
|
|
|
|
|
|
/* ============================================================
|
|
|
|
* Subscription functions
|
|
|
|
* ============================================================ */
|
2016-07-19 14:05:53 +00:00
|
|
|
int sub__add(struct mosquitto_db *db, struct mosquitto *context, const char *sub, int qos, struct mosquitto__subhier **root);
|
2018-08-09 13:17:49 +00:00
|
|
|
struct mosquitto__subhier *sub__add_hier_entry(struct mosquitto__subhier *parent, struct mosquitto__subhier **sibling, const char *topic, size_t len);
|
2015-05-18 08:29:22 +00:00
|
|
|
int sub__remove(struct mosquitto_db *db, struct mosquitto *context, const char *sub, struct mosquitto__subhier *root);
|
|
|
|
void sub__tree_print(struct mosquitto__subhier *root, int level);
|
|
|
|
int sub__clean_session(struct mosquitto_db *db, struct mosquitto *context);
|
|
|
|
int sub__retain_queue(struct mosquitto_db *db, struct mosquitto *context, const char *sub, int sub_qos);
|
|
|
|
int sub__messages_queue(struct mosquitto_db *db, const char *source_id, const char *topic, int qos, int retain, struct mosquitto_msg_store **stored);
|
2014-05-07 22:27:00 +00:00
|
|
|
|
|
|
|
/* ============================================================
|
|
|
|
* Context functions
|
|
|
|
* ============================================================ */
|
2015-09-03 16:46:55 +00:00
|
|
|
struct mosquitto *context__init(struct mosquitto_db *db, mosq_sock_t sock);
|
2015-05-16 14:24:24 +00:00
|
|
|
void context__cleanup(struct mosquitto_db *db, struct mosquitto *context, bool do_free);
|
|
|
|
void context__disconnect(struct mosquitto_db *db, struct mosquitto *context);
|
|
|
|
void context__add_to_disused(struct mosquitto_db *db, struct mosquitto *context);
|
|
|
|
void context__free_disused(struct mosquitto_db *db);
|
2017-07-16 21:52:01 +00:00
|
|
|
void context__send_will(struct mosquitto_db *db, struct mosquitto *context);
|
2014-05-07 22:27:00 +00:00
|
|
|
|
|
|
|
/* ============================================================
|
|
|
|
* Logging functions
|
|
|
|
* ============================================================ */
|
2015-05-16 18:03:12 +00:00
|
|
|
int log__init(struct mosquitto__config *config);
|
|
|
|
int log__close(struct mosquitto__config *config);
|
2015-05-18 07:53:21 +00:00
|
|
|
int log__printf(struct mosquitto *mosq, int level, const char *fmt, ...) __attribute__((format(printf, 3, 4)));
|
2014-05-07 22:27:00 +00:00
|
|
|
|
|
|
|
/* ============================================================
|
|
|
|
* Bridge functions
|
|
|
|
* ============================================================ */
|
|
|
|
#ifdef WITH_BRIDGE
|
2015-05-16 18:03:12 +00:00
|
|
|
int bridge__new(struct mosquitto_db *db, struct mosquitto__bridge *bridge);
|
2015-05-16 14:24:24 +00:00
|
|
|
int bridge__connect(struct mosquitto_db *db, struct mosquitto *context);
|
2017-03-06 21:19:53 +00:00
|
|
|
int bridge__connect_step1(struct mosquitto_db *db, struct mosquitto *context);
|
|
|
|
int bridge__connect_step2(struct mosquitto_db *db, struct mosquitto *context);
|
2015-05-16 14:24:24 +00:00
|
|
|
void bridge__packet_cleanup(struct mosquitto *context);
|
2014-05-07 22:27:00 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
/* ============================================================
|
|
|
|
* Security related functions
|
|
|
|
* ============================================================ */
|
|
|
|
int mosquitto_security_module_init(struct mosquitto_db *db);
|
|
|
|
int mosquitto_security_module_cleanup(struct mosquitto_db *db);
|
|
|
|
|
|
|
|
int mosquitto_security_init(struct mosquitto_db *db, bool reload);
|
|
|
|
int mosquitto_security_apply(struct mosquitto_db *db);
|
|
|
|
int mosquitto_security_cleanup(struct mosquitto_db *db, bool reload);
|
2018-05-22 14:51:26 +00:00
|
|
|
int mosquitto_acl_check(struct mosquitto_db *db, struct mosquitto *context, const char *topic, long payloadlen, void* payload, int qos, bool retain, int access);
|
2016-07-08 12:27:14 +00:00
|
|
|
int mosquitto_unpwd_check(struct mosquitto_db *db, struct mosquitto *context, const char *username, const char *password);
|
2016-07-08 12:52:02 +00:00
|
|
|
int mosquitto_psk_key_get(struct mosquitto_db *db, struct mosquitto *context, const char *hint, const char *identity, char *key, int max_key_len);
|
2014-05-07 22:27:00 +00:00
|
|
|
|
|
|
|
int mosquitto_security_init_default(struct mosquitto_db *db, bool reload);
|
|
|
|
int mosquitto_security_apply_default(struct mosquitto_db *db);
|
|
|
|
int mosquitto_security_cleanup_default(struct mosquitto_db *db, bool reload);
|
|
|
|
int mosquitto_acl_check_default(struct mosquitto_db *db, struct mosquitto *context, const char *topic, int access);
|
2018-03-13 17:44:33 +00:00
|
|
|
int mosquitto_unpwd_check_default(struct mosquitto_db *db, struct mosquitto *context, const char *username, const char *password);
|
2018-03-15 21:39:42 +00:00
|
|
|
int mosquitto_psk_key_get_default(struct mosquitto_db *db, struct mosquitto *context, const char *hint, const char *identity, char *key, int max_key_len);
|
2014-05-07 22:27:00 +00:00
|
|
|
|
|
|
|
/* ============================================================
|
2018-01-06 22:42:13 +00:00
|
|
|
* Window service and signal related functions
|
2014-05-07 22:27:00 +00:00
|
|
|
* ============================================================ */
|
|
|
|
#if defined(WIN32) || defined(__CYGWIN__)
|
|
|
|
void service_install(void);
|
|
|
|
void service_uninstall(void);
|
|
|
|
void service_run(void);
|
2018-01-06 22:42:13 +00:00
|
|
|
|
|
|
|
DWORD WINAPI SigThreadProc(void* data);
|
2014-05-07 22:27:00 +00:00
|
|
|
#endif
|
|
|
|
|
2014-05-06 09:47:00 +00:00
|
|
|
/* ============================================================
|
|
|
|
* Websockets related functions
|
|
|
|
* ============================================================ */
|
|
|
|
#ifdef WITH_WEBSOCKETS
|
2015-12-19 01:21:17 +00:00
|
|
|
# if defined(LWS_LIBRARY_VERSION_NUMBER)
|
2016-01-26 15:55:17 +00:00
|
|
|
struct lws_context *mosq_websockets_init(struct mosquitto__listener *listener, int log_level);
|
2015-12-19 01:21:17 +00:00
|
|
|
# else
|
2016-01-26 15:55:17 +00:00
|
|
|
struct libwebsocket_context *mosq_websockets_init(struct mosquitto__listener *listener, int log_level);
|
2015-12-19 01:21:17 +00:00
|
|
|
# endif
|
2014-05-06 09:47:00 +00:00
|
|
|
#endif
|
2014-07-03 00:00:57 +00:00
|
|
|
void do_disconnect(struct mosquitto_db *db, struct mosquitto *context);
|
2014-05-06 09:47:00 +00:00
|
|
|
|
2014-05-07 22:27:00 +00:00
|
|
|
#endif
|
2017-07-27 17:43:09 +00:00
|
|
|
|