Move headers from server/include to include/maxscale
- Headers now to be included as <maxscale/xyz.h> - First step, no cleanup of headers has been made. Only moving from one place to another + necessary modifications.
This commit is contained in:
66
include/maxscale/adminusers.h.in
Normal file
66
include/maxscale/adminusers.h.in
Normal file
@ -0,0 +1,66 @@
|
||||
#ifndef _ADMINUSERS_H
|
||||
#define _ADMINUSERS_H
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file adminusers.h - Administration users support routines
|
||||
*
|
||||
* @verbatim
|
||||
* Revision History
|
||||
*
|
||||
* Date Who Description
|
||||
* 18/07/13 Mark Riddoch Initial implementation
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
#include <maxscale/dcb.h>
|
||||
|
||||
#define ADMIN_SALT "$1$MXS"
|
||||
|
||||
/* Max length of fields in for admin users */
|
||||
#define ADMIN_USER_MAXLEN 128
|
||||
#define ADMIN_PASSWORD_MAXLEN 128
|
||||
|
||||
/** Default user for the administrative interface */
|
||||
#define DEFAULT_ADMIN_USER "@DEFAULT_ADMIN_USER@"
|
||||
|
||||
/*
|
||||
* MySQL session specific data
|
||||
*
|
||||
*/
|
||||
typedef struct admin_session
|
||||
{
|
||||
#if defined(SS_DEBUG)
|
||||
skygw_chk_t adminses_chk_top;
|
||||
#endif
|
||||
char user[ADMIN_USER_MAXLEN + 1]; /*< username */
|
||||
bool validated; /* Was user validated? */
|
||||
#if defined(SS_DEBUG)
|
||||
skygw_chk_t adminses_chk_tail;
|
||||
#endif
|
||||
} ADMIN_session;
|
||||
|
||||
extern const char *admin_enable_linux_account(const char *uname);
|
||||
extern const char *admin_disable_linux_account(const char *uname);
|
||||
extern bool admin_linux_account_enabled(const char *uname);
|
||||
|
||||
extern const char *admin_add_inet_user(const char *uname, const char *password);
|
||||
extern const char *admin_remove_inet_user(const char *uname, const char *password);
|
||||
extern bool admin_inet_user_exists(const char *uname);
|
||||
|
||||
extern bool admin_verify_inet_user(const char *uname, const char *password);
|
||||
|
||||
extern void dcb_PrintAdminUsers(DCB *dcb);
|
||||
|
||||
#endif
|
82
include/maxscale/alloc.h
Normal file
82
include/maxscale/alloc.h
Normal file
@ -0,0 +1,82 @@
|
||||
#ifndef _MAXSCALE_ALLOC_H
|
||||
#define _MAXSCALE_ALLOC_H
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <maxscale/skygw_debug.h>
|
||||
|
||||
EXTERN_C_BLOCK_BEGIN
|
||||
|
||||
/*
|
||||
* NOTE: Do not use these functions directly, use the macros below.
|
||||
*/
|
||||
|
||||
// "caller" arg temporarily disabled so that existing code
|
||||
// using the previous version of mxs_alloc etc. will continue
|
||||
// to compile.
|
||||
void *mxs_malloc(size_t size/*, const char *caller*/);
|
||||
void *mxs_calloc(size_t nmemb, size_t size/*, const char *caller*/);
|
||||
void *mxs_realloc(void *ptr, size_t size/*, const char *caller*/);
|
||||
void mxs_free(void *ptr/*, const char *caller*/);
|
||||
|
||||
char *mxs_strdup(const char *s/*, const char *caller*/);
|
||||
char *mxs_strndup(const char *s, size_t n/*, const char *caller*/);
|
||||
|
||||
char *mxs_strdup_a(const char *s/*, const char *caller*/);
|
||||
char *mxs_strndup_a(const char *s, size_t n/*, const char *caller*/);
|
||||
|
||||
|
||||
/*
|
||||
* NOTE: USE these macros instead of the functions above.
|
||||
*/
|
||||
#define MXS_MALLOC(size) mxs_malloc(size/*, __func__*/)
|
||||
#define MXS_CALLOC(nmemb, size) mxs_calloc(nmemb, size/*, __func__*/)
|
||||
#define MXS_REALLOC(ptr, size) mxs_realloc(ptr, size/*, __func__*/)
|
||||
#define MXS_FREE(ptr) mxs_free(ptr/*, __func__*/)
|
||||
|
||||
#define MXS_STRDUP(s) mxs_strdup(s/*, __func__*/)
|
||||
#define MXS_STRNDUP(s, n) mxs_strndup(s, n/*, __func__*/)
|
||||
|
||||
#define MXS_STRDUP_A(s) mxs_strdup_a(s/*, __func__*/)
|
||||
#define MXS_STRNDUP_A(s, n) mxs_strndup_a(s, n/*, __func__*/)
|
||||
|
||||
|
||||
/**
|
||||
* @brief Abort the process if the pointer is NULL.
|
||||
*
|
||||
* To be used in circumstances where a memory allocation failure
|
||||
* cannot - currently - be dealt with properly.
|
||||
*/
|
||||
#define MXS_ABORT_IF_NULL(p) do { if (!p) { abort(); } } while (false)
|
||||
|
||||
/**
|
||||
* @brief Abort the process if the provided value is non-zero.
|
||||
*
|
||||
* To be used in circumstances where a memory allocation or other
|
||||
* fatal error cannot - currently - be dealt with properly.
|
||||
*/
|
||||
#define MXS_ABORT_IF_TRUE(b) do { if (b) { abort(); } } while (false)
|
||||
|
||||
/**
|
||||
* @brief Abort the process if the provided value is zero.
|
||||
*
|
||||
* To be used in circumstances where a memory allocation or other
|
||||
* fatal error cannot - currently - be dealt with properly.
|
||||
*/
|
||||
#define MXS_ABORT_IF_FALSE(b) do { if (!b) { abort(); } } while (false)
|
||||
|
||||
EXTERN_C_BLOCK_END
|
||||
|
||||
#endif
|
34
include/maxscale/atomic.h
Normal file
34
include/maxscale/atomic.h
Normal file
@ -0,0 +1,34 @@
|
||||
#ifndef _ATOMIC_H
|
||||
#define _ATOMIC_H
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file atomic.h The atomic operations used within the gateway
|
||||
*
|
||||
* @verbatim
|
||||
* Revision History
|
||||
*
|
||||
* Date Who Description
|
||||
* 10/06/13 Mark Riddoch Initial implementation
|
||||
* 23/06/15 Martin Brampton Alternative for C++
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" int atomic_add(int *variable, int value);
|
||||
#else
|
||||
extern int atomic_add(int *variable, int value);
|
||||
#endif
|
||||
#endif
|
220
include/maxscale/buffer.h
Normal file
220
include/maxscale/buffer.h
Normal file
@ -0,0 +1,220 @@
|
||||
#ifndef _BUFFER_H
|
||||
#define _BUFFER_H
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file buffer.h Definitions relating the gateway buffer manipulation facilities.
|
||||
*
|
||||
* These are used to store all data coming in form or going out to the client and the
|
||||
* backend structures.
|
||||
*
|
||||
* The buffers are designed to be used in linked lists and such that they may be passed
|
||||
* from one side of the gateway to another without the need to copy data. It may be the case
|
||||
* that not all of the data in the buffer is valid, to this end a start and end pointer are
|
||||
* included that point to the first valid byte in the buffer and the first byte after the
|
||||
* last valid byte. This allows data to be consumed from either end of the buffer whilst
|
||||
* still allowing for the copy free semantics of the buffering system.
|
||||
*
|
||||
* @verbatim
|
||||
* Revision History
|
||||
*
|
||||
* Date Who Description
|
||||
* 10/06/2013 Mark Riddoch Initial implementation
|
||||
* 11/07/2013 Mark Riddoch Addition of reference count in the gwbuf
|
||||
* 16/07/2013 Massimiliano Pinto Added command type for the queue
|
||||
* 10/07/2014 Mark Riddoch Addition of hints
|
||||
* 15/07/2014 Mark Riddoch Added buffer properties
|
||||
* 03/10/2014 Martin Brampton Pointer arithmetic standard conformity
|
||||
* Add more buffer handling macros
|
||||
* Add gwbuf_rtrim (handle chains)
|
||||
* 09/11/2014 Martin Brampton Add dprintAllBuffers (conditional compilation)
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <maxscale/skygw_debug.h>
|
||||
#include <maxscale/hint.h>
|
||||
#include <maxscale/spinlock.h>
|
||||
#include <stdint.h>
|
||||
|
||||
EXTERN_C_BLOCK_BEGIN
|
||||
|
||||
/**
|
||||
* Buffer properties - used to store properties related to the buffer
|
||||
* contents. This may be added at any point during the processing of the
|
||||
* data, especially in the protocol stage of the processing.
|
||||
*/
|
||||
typedef struct buf_property
|
||||
{
|
||||
char *name;
|
||||
char *value;
|
||||
struct buf_property *next;
|
||||
} BUF_PROPERTY;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GWBUF_TYPE_UNDEFINED = 0x00,
|
||||
GWBUF_TYPE_PLAINSQL = 0x01,
|
||||
GWBUF_TYPE_MYSQL = 0x02,
|
||||
GWBUF_TYPE_SINGLE_STMT = 0x04,
|
||||
GWBUF_TYPE_SESCMD_RESPONSE = 0x08,
|
||||
GWBUF_TYPE_RESPONSE_END = 0x10,
|
||||
GWBUF_TYPE_SESCMD = 0x20,
|
||||
GWBUF_TYPE_HTTP = 0x40
|
||||
} gwbuf_type_t;
|
||||
|
||||
#define GWBUF_IS_TYPE_UNDEFINED(b) (b->gwbuf_type == 0)
|
||||
#define GWBUF_IS_TYPE_PLAINSQL(b) (b->gwbuf_type & GWBUF_TYPE_PLAINSQL)
|
||||
#define GWBUF_IS_TYPE_MYSQL(b) (b->gwbuf_type & GWBUF_TYPE_MYSQL)
|
||||
#define GWBUF_IS_TYPE_SINGLE_STMT(b) (b->gwbuf_type & GWBUF_TYPE_SINGLE_STMT)
|
||||
#define GWBUF_IS_TYPE_SESCMD_RESPONSE(b) (b->gwbuf_type & GWBUF_TYPE_SESCMD_RESPONSE)
|
||||
#define GWBUF_IS_TYPE_RESPONSE_END(b) (b->gwbuf_type & GWBUF_TYPE_RESPONSE_END)
|
||||
#define GWBUF_IS_TYPE_SESCMD(b) (b->gwbuf_type & GWBUF_TYPE_SESCMD)
|
||||
|
||||
/**
|
||||
* A structure to encapsulate the data in a form that the data itself can be
|
||||
* shared between multiple GWBUF's without the need to make multiple copies
|
||||
* but still maintain separate data pointers.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
unsigned char *data; /*< Physical memory that was allocated */
|
||||
int refcount; /*< Reference count on the buffer */
|
||||
} SHARED_BUF;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GWBUF_INFO_NONE = 0x0,
|
||||
GWBUF_INFO_PARSED = 0x1
|
||||
} gwbuf_info_t;
|
||||
|
||||
#define GWBUF_IS_PARSED(b) (b->gwbuf_info & GWBUF_INFO_PARSED)
|
||||
|
||||
/**
|
||||
* A structure for cleaning up memory allocations of structures which are
|
||||
* referred to by GWBUF and deallocated in gwbuf_free but GWBUF doesn't
|
||||
* know what they are.
|
||||
* All functions on the list are executed before freeing memory of GWBUF struct.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
GWBUF_PARSING_INFO
|
||||
} bufobj_id_t;
|
||||
|
||||
typedef struct buffer_object_st buffer_object_t;
|
||||
|
||||
struct buffer_object_st
|
||||
{
|
||||
bufobj_id_t bo_id;
|
||||
void* bo_data;
|
||||
void (*bo_donefun_fp)(void *);
|
||||
buffer_object_t* bo_next;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The buffer structure used by the descriptor control blocks.
|
||||
*
|
||||
* Linked lists of buffers are created as data is read from a descriptor
|
||||
* or written to a descriptor. The use of linked lists of buffers with
|
||||
* flexible data pointers is designed to minimise the need for data to
|
||||
* be copied within the gateway.
|
||||
*/
|
||||
typedef struct gwbuf
|
||||
{
|
||||
SPINLOCK gwbuf_lock;
|
||||
struct gwbuf *next; /*< Next buffer in a linked chain of buffers */
|
||||
struct gwbuf *tail; /*< Last buffer in a linked chain of buffers */
|
||||
void *start; /*< Start of the valid data */
|
||||
void *end; /*< First byte after the valid data */
|
||||
SHARED_BUF *sbuf; /*< The shared buffer with the real data */
|
||||
buffer_object_t *gwbuf_bufobj; /*< List of objects referred to by GWBUF */
|
||||
gwbuf_info_t gwbuf_info; /*< Info bits */
|
||||
gwbuf_type_t gwbuf_type; /*< buffer's data type information */
|
||||
HINT *hint; /*< Hint data for this buffer */
|
||||
BUF_PROPERTY *properties; /*< Buffer properties */
|
||||
} GWBUF;
|
||||
|
||||
/*<
|
||||
* Macros to access the data in the buffers
|
||||
*/
|
||||
/*< First valid, unconsumed byte in the buffer */
|
||||
#define GWBUF_DATA(b) ((b)->start)
|
||||
|
||||
/*< Number of bytes in the individual buffer */
|
||||
#define GWBUF_LENGTH(b) ((char *)(b)->end - (char *)(b)->start)
|
||||
|
||||
/*< Return the byte at offset byte from the start of the unconsumed portion of the buffer */
|
||||
#define GWBUF_DATA_CHAR(b, byte) (GWBUF_LENGTH(b) < ((byte)+1) ? -1 : *(((char *)(b)->start)+4))
|
||||
|
||||
/*< Check that the data in a buffer has the SQL marker*/
|
||||
#define GWBUF_IS_SQL(b) (0x03 == GWBUF_DATA_CHAR(b,4))
|
||||
|
||||
/*< Check whether the buffer is contiguous*/
|
||||
#define GWBUF_IS_CONTIGUOUS(b) (((b) == NULL) || ((b)->next == NULL))
|
||||
|
||||
/*< True if all bytes in the buffer have been consumed */
|
||||
#define GWBUF_EMPTY(b) ((char *)(b)->start >= (char *)(b)->end)
|
||||
|
||||
/*< Consume a number of bytes in the buffer */
|
||||
#define GWBUF_CONSUME(b, bytes) ((b)->start = bytes > ((char *)(b)->end - (char *)(b)->start) ? (b)->end : (void *)((char *)(b)->start + (bytes)));
|
||||
|
||||
/*< Check if a given pointer is within the buffer */
|
||||
#define GWBUF_POINTER_IN_BUFFER (ptr, b)\
|
||||
((char *)(ptr) >= (char *)(b)->start && (char *)(ptr) < (char *)(b)->end)
|
||||
|
||||
/*< Consume a complete buffer */
|
||||
#define GWBUF_CONSUME_ALL(b) gwbuf_consume((b), GWBUF_LENGTH((b)))
|
||||
|
||||
#define GWBUF_RTRIM(b, bytes)\
|
||||
((b)->end = bytes > ((char *)(b)->end - (char *)(b)->start) ? (b)->start : \
|
||||
(void *)((char *)(b)->end - (bytes)));
|
||||
|
||||
#define GWBUF_TYPE(b) (b)->gwbuf_type
|
||||
/*<
|
||||
* Function prototypes for the API to maniplate the buffers
|
||||
*/
|
||||
extern GWBUF *gwbuf_alloc(unsigned int size);
|
||||
extern GWBUF *gwbuf_alloc_and_load(unsigned int size, const void *data);
|
||||
extern void gwbuf_free(GWBUF *buf);
|
||||
extern GWBUF *gwbuf_clone(GWBUF *buf);
|
||||
extern GWBUF *gwbuf_append(GWBUF *head, GWBUF *tail);
|
||||
extern GWBUF *gwbuf_consume(GWBUF *head, unsigned int length);
|
||||
extern GWBUF *gwbuf_trim(GWBUF *head, unsigned int length);
|
||||
extern GWBUF *gwbuf_rtrim(GWBUF *head, unsigned int length);
|
||||
extern unsigned int gwbuf_length(GWBUF *head);
|
||||
extern int gwbuf_count(GWBUF *head);
|
||||
extern size_t gwbuf_copy_data(GWBUF *buffer, size_t offset, size_t bytes,
|
||||
uint8_t* dest);
|
||||
extern GWBUF *gwbuf_split(GWBUF **buf, size_t length);
|
||||
extern GWBUF *gwbuf_clone_transform(GWBUF *head, gwbuf_type_t type);
|
||||
extern GWBUF *gwbuf_clone_all(GWBUF* head);
|
||||
extern void gwbuf_set_type(GWBUF *head, gwbuf_type_t type);
|
||||
extern int gwbuf_add_property(GWBUF *buf, char *name, char *value);
|
||||
extern char *gwbuf_get_property(GWBUF *buf, char *name);
|
||||
extern GWBUF *gwbuf_make_contiguous(GWBUF *);
|
||||
extern int gwbuf_add_hint(GWBUF *, HINT *);
|
||||
|
||||
void gwbuf_add_buffer_object(GWBUF* buf,
|
||||
bufobj_id_t id,
|
||||
void* data,
|
||||
void (*donefun_fp)(void *));
|
||||
void* gwbuf_get_buffer_object_data(GWBUF* buf, bufobj_id_t id);
|
||||
#if defined(BUFFER_TRACE)
|
||||
extern void dprintAllBuffers(void *pdcb);
|
||||
#endif
|
||||
EXTERN_C_BLOCK_END
|
||||
|
||||
|
||||
#endif
|
80
include/maxscale/dbusers.h
Normal file
80
include/maxscale/dbusers.h
Normal file
@ -0,0 +1,80 @@
|
||||
#ifndef _DBUSERS_H
|
||||
#define _DBUSERS_H
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
|
||||
#include <maxscale/service.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
|
||||
/**
|
||||
* @file dbusers.h Extarct user information form the backend database
|
||||
*
|
||||
* @verbatim
|
||||
* Revision History
|
||||
*
|
||||
* Date Who Description
|
||||
* 25/06/13 Mark Riddoch Initial implementation
|
||||
* 25/02/13 Massimiliano Pinto Added users table refresh rate default values
|
||||
* 28/02/14 Massimiliano Pinto Added MySQL user and host data structure
|
||||
* 03/10/14 Massimiliano Pinto Added netmask to MySQL user and host data structure
|
||||
* 13/10/14 Massimiliano Pinto Added resource to MySQL user and host data structure
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
|
||||
/* Refresh rate limits for load users from database */
|
||||
#define USERS_REFRESH_TIME 30 /* Allowed time interval (in seconds) after last update*/
|
||||
#define USERS_REFRESH_MAX_PER_TIME 4 /* Max number of load calls within the time interval */
|
||||
|
||||
/** Default timeout values used by the connections which fetch user authentication data */
|
||||
#define DEFAULT_AUTH_CONNECT_TIMEOUT 3
|
||||
#define DEFAULT_AUTH_READ_TIMEOUT 1
|
||||
#define DEFAULT_AUTH_WRITE_TIMEOUT 2
|
||||
|
||||
/* Max length of fields in the mysql.user table */
|
||||
#define MYSQL_USER_MAXLEN 128
|
||||
#define MYSQL_PASSWORD_LEN 41
|
||||
#define MYSQL_HOST_MAXLEN 60
|
||||
#define MYSQL_DATABASE_MAXLEN 128
|
||||
#define MYSQL_TABLE_MAXLEN 64
|
||||
|
||||
/** Cache directory and file names */
|
||||
static const char DBUSERS_DIR[] = "cache";
|
||||
static const char DBUSERS_FILE[] = "dbusers";
|
||||
|
||||
/**
|
||||
* MySQL user and host data structure
|
||||
*/
|
||||
typedef struct mysql_user_host_key
|
||||
{
|
||||
char *user;
|
||||
struct sockaddr_in ipv4;
|
||||
int netmask;
|
||||
char *resource;
|
||||
char hostname[MYSQL_HOST_MAXLEN + 1];
|
||||
} MYSQL_USER_HOST;
|
||||
|
||||
extern int add_mysql_users_with_host_ipv4(USERS *users, const char *user, const char *host,
|
||||
char *passwd, const char *anydb, const char *db);
|
||||
extern bool check_service_permissions(SERVICE* service);
|
||||
extern int dbusers_load(USERS *, const char *filename);
|
||||
extern int dbusers_save(USERS *, const char *filename);
|
||||
extern int load_mysql_users(SERV_LISTENER *listener);
|
||||
extern int mysql_users_add(USERS *users, MYSQL_USER_HOST *key, char *auth);
|
||||
extern USERS *mysql_users_alloc();
|
||||
extern char *mysql_users_fetch(USERS *users, MYSQL_USER_HOST *key);
|
||||
extern int reload_mysql_users(SERV_LISTENER *listener);
|
||||
extern int replace_mysql_users(SERV_LISTENER *listener);
|
||||
|
||||
#endif
|
372
include/maxscale/dcb.h
Normal file
372
include/maxscale/dcb.h
Normal file
@ -0,0 +1,372 @@
|
||||
#ifndef _DCB_H
|
||||
#define _DCB_H
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#include <maxscale/spinlock.h>
|
||||
#include <maxscale/buffer.h>
|
||||
#include <maxscale/listmanager.h>
|
||||
#include <maxscale/gw_protocol.h>
|
||||
#include <maxscale/gw_authenticator.h>
|
||||
#include <maxscale/gw_ssl.h>
|
||||
#include <maxscale/modinfo.h>
|
||||
#include <maxscale/gwbitmask.h>
|
||||
#include <maxscale/skygw_utils.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#define ERRHANDLE
|
||||
|
||||
struct session;
|
||||
struct server;
|
||||
struct service;
|
||||
struct servlistener;
|
||||
|
||||
/**
|
||||
* @file dcb.h The Descriptor Control Block
|
||||
*
|
||||
* The function pointer table used by descriptors to call relevant functions
|
||||
* within the protocol specific code.
|
||||
*
|
||||
* @verbatim
|
||||
* Revision History
|
||||
*
|
||||
* Date Who Description
|
||||
* 01/06/2013 Mark Riddoch Initial implementation
|
||||
* 11/06/2013 Mark Riddoch Updated GWPROTOCOL structure with new
|
||||
* entry points
|
||||
* 18/06/2013 Mark Riddoch Addition of the listener entry point
|
||||
* 02/07/2013 Massimiliano Pinto Addition of delayqlock, delayq and authlock
|
||||
* for handling backend asynchronous protocol connection
|
||||
* and a generic lock for backend authentication
|
||||
* 12/07/2013 Massimiliano Pinto Added auth entry point
|
||||
* 15/07/2013 Massimiliano Pinto Added session entry point
|
||||
* 16/07/2013 Massimiliano Pinto Added command type for dcb
|
||||
* 07/02/2014 Massimiliano Pinto Added ipv4 data struct into for dcb
|
||||
* 07/05/2014 Mark Riddoch Addition of callback mechanism
|
||||
* 08/05/2014 Mark Riddoch Addition of writeq high and low watermarks
|
||||
* 27/08/2014 Mark Riddoch Addition of write event queuing
|
||||
* 23/09/2014 Mark Riddoch New poll processing queue
|
||||
* 19/06/2015 Martin Brampton Provision of persistent connections
|
||||
* 20/01/2016 Martin Brampton Moved GWPROTOCOL to gw_protocol.h
|
||||
* 01/02/2016 Martin Brampton Added fields for SSL and authentication
|
||||
* 27/06/2016 Martin Brampton Changed DCB to conform to list manager
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
|
||||
struct dcb;
|
||||
|
||||
/**
|
||||
* The event queue structure used in the polling loop to maintain a queue
|
||||
* of events that need to be processed for the DCB.
|
||||
*
|
||||
* next The next DCB in the event queue
|
||||
* prev The previous DCB in the event queue
|
||||
* pending_events The events that are pending processing
|
||||
* processing_events The evets currently being processed
|
||||
* processing Flag to indicate the processing status of the DCB
|
||||
* eventqlock Spinlock to protect this structure
|
||||
* inserted Insertion time for logging purposes
|
||||
* started Time that the processign started
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
struct dcb *next;
|
||||
struct dcb *prev;
|
||||
uint32_t pending_events;
|
||||
uint32_t processing_events;
|
||||
int processing;
|
||||
SPINLOCK eventqlock;
|
||||
unsigned long inserted;
|
||||
unsigned long started;
|
||||
} DCBEVENTQ;
|
||||
|
||||
#define DCBEVENTQ_INIT {NULL, NULL, 0, 0, 0, SPINLOCK_INIT, 0, 0}
|
||||
|
||||
#define DCBFD_CLOSED -1
|
||||
|
||||
/**
|
||||
* The statistics gathered on a descriptor control block
|
||||
*/
|
||||
typedef struct dcbstats
|
||||
{
|
||||
int n_reads; /*< Number of reads on this descriptor */
|
||||
int n_writes; /*< Number of writes on this descriptor */
|
||||
int n_accepts; /*< Number of accepts on this descriptor */
|
||||
int n_buffered; /*< Number of buffered writes */
|
||||
int n_high_water; /*< Number of crosses of high water mark */
|
||||
int n_low_water; /*< Number of crosses of low water mark */
|
||||
} DCBSTATS;
|
||||
|
||||
#define DCBSTATS_INIT {0}
|
||||
|
||||
/**
|
||||
* The data structure that is embedded witin a DCB and manages the complex memory
|
||||
* management issues of a DCB.
|
||||
*
|
||||
* The DCB structures are used as the user data within the polling loop. This means that
|
||||
* polling threads may aschronously wake up and access these structures. It is not possible
|
||||
* to simple remove the DCB from the epoll system and then free the data, as every thread
|
||||
* that is currently running an epoll call must wake up and re-issue the epoll_wait system
|
||||
* call, the is the only way we can be sure that no polling thread is pending a wakeup or
|
||||
* processing an event that will access the DCB.
|
||||
*
|
||||
* We solve this issue by making the dcb_free routine merely mark a DCB as a zombie and
|
||||
* place it on a special zombie list. Before placing the DCB on the zombie list we create
|
||||
* a bitmask with a bit set in it for each active polling thread. Each thread will call
|
||||
* a routine to process the zombie list at the end of the polling loop. This routine
|
||||
* will clear the bit value that corresponds to the calling thread. Once the bitmask
|
||||
* is completely cleared the DCB can finally be freed and removed from the zombie list.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
GWBITMASK bitmask; /*< The bitmask of threads */
|
||||
struct dcb *next; /*< Next pointer for the zombie list */
|
||||
} DCBMM;
|
||||
|
||||
#define DCBMM_INIT {GWBITMASK_INIT}
|
||||
|
||||
/* DCB states */
|
||||
typedef enum
|
||||
{
|
||||
DCB_STATE_UNDEFINED, /*< State variable with no state */
|
||||
DCB_STATE_ALLOC, /*< Memory allocated but not populated */
|
||||
DCB_STATE_POLLING, /*< Waiting in the poll loop */
|
||||
DCB_STATE_WAITING, /*< Client wanting a connection */
|
||||
DCB_STATE_LISTENING, /*< The DCB is for a listening socket */
|
||||
DCB_STATE_DISCONNECTED, /*< The socket is now closed */
|
||||
DCB_STATE_NOPOLLING, /*< Removed from poll mask */
|
||||
DCB_STATE_ZOMBIE, /*< DCB is no longer active, waiting to free it */
|
||||
} dcb_state_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DCB_ROLE_SERVICE_LISTENER, /*< Receives initial connect requests from clients */
|
||||
DCB_ROLE_CLIENT_HANDLER, /*< Serves dedicated client */
|
||||
DCB_ROLE_BACKEND_HANDLER, /*< Serves back end connection */
|
||||
DCB_ROLE_INTERNAL /*< Internal DCB not connected to the outside */
|
||||
} dcb_role_t;
|
||||
|
||||
#define DCB_STRTYPE(dcb) (dcb->dcb_role == DCB_ROLE_CLIENT_HANDLER ? "Client DCB" : \
|
||||
dcb->dcb_role == DCB_ROLE_BACKEND_HANDLER ? "Backend DCB" : \
|
||||
dcb->dcb_role == DCB_ROLE_SERVICE_LISTENER ? "Listener DCB" : \
|
||||
dcb->dcb_role == DCB_ROLE_INTERNAL ? "Internal DCB" : "Unknown DCB")
|
||||
|
||||
/**
|
||||
* Callback reasons for the DCB callback mechanism.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
DCB_REASON_CLOSE, /*< The DCB is closing */
|
||||
DCB_REASON_DRAINED, /*< The write delay queue has drained */
|
||||
DCB_REASON_HIGH_WATER, /*< Cross high water mark */
|
||||
DCB_REASON_LOW_WATER, /*< Cross low water mark */
|
||||
DCB_REASON_ERROR, /*< An error was flagged on the connection */
|
||||
DCB_REASON_HUP, /*< A hangup was detected */
|
||||
DCB_REASON_NOT_RESPONDING /*< Server connection was lost */
|
||||
} DCB_REASON;
|
||||
|
||||
/**
|
||||
* Callback structure - used to track callbacks registered on a DCB
|
||||
*/
|
||||
typedef struct dcb_callback
|
||||
{
|
||||
DCB_REASON reason; /*< The reason for the callback */
|
||||
int (*cb)(struct dcb *dcb, DCB_REASON reason, void *userdata);
|
||||
void *userdata; /*< User data to be sent in the callback */
|
||||
struct dcb_callback *next; /*< Next callback for this DCB */
|
||||
} DCB_CALLBACK;
|
||||
|
||||
/**
|
||||
* State of SSL connection
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
SSL_HANDSHAKE_UNKNOWN, /*< The DCB has unknown SSL status */
|
||||
SSL_HANDSHAKE_REQUIRED, /*< SSL handshake is needed */
|
||||
SSL_HANDSHAKE_DONE, /*< The SSL handshake completed OK */
|
||||
SSL_ESTABLISHED, /*< The SSL connection is in use */
|
||||
SSL_HANDSHAKE_FAILED /*< The SSL handshake failed */
|
||||
} SSL_STATE;
|
||||
|
||||
/**
|
||||
* Descriptor Control Block
|
||||
*
|
||||
* A wrapper for a network descriptor within the gateway, it contains all the
|
||||
* state information necessary to allow for the implementation of the asynchronous
|
||||
* operation of the protocol and gateway functions. It also provides links to the service
|
||||
* and session data that is required to route the information within the gateway.
|
||||
*
|
||||
* It is important to hold the state information here such that any thread within the
|
||||
* gateway may be selected to execute the required actions when a network event occurs.
|
||||
*
|
||||
* Note that the first few fields (up to and including "entry_is_ready") must
|
||||
* precisely match the LIST_ENTRY structure defined in the list manager.
|
||||
*/
|
||||
typedef struct dcb
|
||||
{
|
||||
LIST_ENTRY_FIELDS
|
||||
skygw_chk_t dcb_chk_top;
|
||||
bool dcb_errhandle_called; /*< this can be called only once */
|
||||
bool dcb_is_zombie; /**< Whether the DCB is in the zombie list */
|
||||
bool draining_flag; /**< Set while write queue is drained */
|
||||
bool drain_called_while_busy; /**< Set as described */
|
||||
dcb_role_t dcb_role;
|
||||
SPINLOCK dcb_initlock;
|
||||
DCBEVENTQ evq; /**< The event queue for this DCB */
|
||||
int fd; /**< The descriptor */
|
||||
dcb_state_t state; /**< Current descriptor state */
|
||||
SSL_STATE ssl_state; /**< Current state of SSL if in use */
|
||||
int flags; /**< DCB flags */
|
||||
char *remote; /**< Address of remote end */
|
||||
char *user; /**< User name for connection */
|
||||
struct sockaddr_in ipv4; /**< remote end IPv4 address */
|
||||
char *protoname; /**< Name of the protocol */
|
||||
void *protocol; /**< The protocol specific state */
|
||||
size_t protocol_packet_length; /**< How long the protocol specific packet is */
|
||||
size_t protocol_bytes_processed; /**< How many bytes of a packet have been read */
|
||||
struct session *session; /**< The owning session */
|
||||
struct servlistener *listener; /**< For a client DCB, the listener data */
|
||||
GWPROTOCOL func; /**< The protocol functions for this descriptor */
|
||||
GWAUTHENTICATOR authfunc; /**< The authenticator functions for this descriptor */
|
||||
|
||||
int writeqlen; /**< Current number of byes in the write queue */
|
||||
SPINLOCK writeqlock; /**< Write Queue spinlock */
|
||||
GWBUF *writeq; /**< Write Data Queue */
|
||||
SPINLOCK delayqlock; /**< Delay Backend Write Queue spinlock */
|
||||
GWBUF *delayq; /**< Delay Backend Write Data Queue */
|
||||
GWBUF *dcb_readqueue; /**< read queue for storing incomplete reads */
|
||||
SPINLOCK authlock; /**< Generic Authorization spinlock */
|
||||
|
||||
DCBSTATS stats; /**< DCB related statistics */
|
||||
unsigned int dcb_server_status; /*< the server role indicator from SERVER */
|
||||
struct dcb *nextpersistent; /**< Next DCB in the persistent pool for SERVER */
|
||||
time_t persistentstart; /**< Time when DCB placed in persistent pool */
|
||||
struct service *service; /**< The related service */
|
||||
void *data; /**< Specific client data, shared between DCBs of this session */
|
||||
void *authenticator_data; /**< The authenticator data for this DCB */
|
||||
DCBMM memdata; /**< The data related to DCB memory management */
|
||||
SPINLOCK cb_lock; /**< The lock for the callbacks linked list */
|
||||
DCB_CALLBACK *callbacks; /**< The list of callbacks for the DCB */
|
||||
SPINLOCK pollinlock;
|
||||
int pollinbusy;
|
||||
int readcheck;
|
||||
|
||||
SPINLOCK polloutlock;
|
||||
int polloutbusy;
|
||||
int writecheck;
|
||||
long last_read; /*< Last time the DCB received data */
|
||||
int high_water; /**< High water mark */
|
||||
int low_water; /**< Low water mark */
|
||||
struct server *server; /**< The associated backend server */
|
||||
SSL* ssl; /*< SSL struct for connection */
|
||||
bool ssl_read_want_read; /*< Flag */
|
||||
bool ssl_read_want_write; /*< Flag */
|
||||
bool ssl_write_want_read; /*< Flag */
|
||||
bool ssl_write_want_write; /*< Flag */
|
||||
int dcb_port; /**< port of target server */
|
||||
skygw_chk_t dcb_chk_tail;
|
||||
} DCB;
|
||||
|
||||
#define DCB_INIT {.dcb_chk_top = CHK_NUM_DCB, .dcb_initlock = SPINLOCK_INIT, \
|
||||
.evq = DCBEVENTQ_INIT, .ipv4 = {0}, .func = {0}, .authfunc = {0}, \
|
||||
.writeqlock = SPINLOCK_INIT, .delayqlock = SPINLOCK_INIT, \
|
||||
.authlock = SPINLOCK_INIT, .stats = {0}, .memdata = DCBMM_INIT, \
|
||||
.cb_lock = SPINLOCK_INIT, .pollinlock = SPINLOCK_INIT, \
|
||||
.fd = DCBFD_CLOSED, .stats = DCBSTATS_INIT, .ssl_state = SSL_HANDSHAKE_UNKNOWN, \
|
||||
.state = DCB_STATE_ALLOC, .polloutlock = SPINLOCK_INIT, .dcb_chk_tail = CHK_NUM_DCB, \
|
||||
.authenticator_data = NULL}
|
||||
|
||||
/**
|
||||
* The DCB usage filer used for returning DCB's in use for a certain reason
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
DCB_USAGE_CLIENT,
|
||||
DCB_USAGE_LISTENER,
|
||||
DCB_USAGE_BACKEND,
|
||||
DCB_USAGE_INTERNAL,
|
||||
DCB_USAGE_ZOMBIE,
|
||||
DCB_USAGE_ALL
|
||||
} DCB_USAGE;
|
||||
|
||||
#if defined(FAKE_CODE)
|
||||
extern unsigned char dcb_fake_write_errno[10240];
|
||||
extern __int32_t dcb_fake_write_ev[10240];
|
||||
extern bool fail_next_backend_fd;
|
||||
extern bool fail_next_client_fd;
|
||||
extern int fail_next_accept;
|
||||
extern int fail_accept_errno;
|
||||
#endif /* FAKE_CODE */
|
||||
|
||||
/* A few useful macros */
|
||||
#define DCB_SESSION(x) (x)->session
|
||||
#define DCB_PROTOCOL(x, type) (type *)((x)->protocol)
|
||||
#define DCB_ISZOMBIE(x) ((x)->state == DCB_STATE_ZOMBIE)
|
||||
#define DCB_WRITEQLEN(x) (x)->writeqlen
|
||||
#define DCB_SET_LOW_WATER(x, lo) (x)->low_water = (lo);
|
||||
#define DCB_SET_HIGH_WATER(x, hi) (x)->low_water = (hi);
|
||||
#define DCB_BELOW_LOW_WATER(x) ((x)->low_water && (x)->writeqlen < (x)->low_water)
|
||||
#define DCB_ABOVE_HIGH_WATER(x) ((x)->high_water && (x)->writeqlen > (x)->high_water)
|
||||
|
||||
#define DCB_POLL_BUSY(x) ((x)->evq.next != NULL)
|
||||
|
||||
DCB *dcb_get_zombies(void);
|
||||
int dcb_write(DCB *, GWBUF *);
|
||||
DCB *dcb_accept(DCB *listener, GWPROTOCOL *protocol_funcs);
|
||||
bool dcb_pre_alloc(int number);
|
||||
DCB *dcb_alloc(dcb_role_t, struct servlistener *);
|
||||
void dcb_free(DCB *);
|
||||
void dcb_free_all_memory(DCB *dcb);
|
||||
DCB *dcb_connect(struct server *, struct session *, const char *);
|
||||
DCB *dcb_clone(DCB *);
|
||||
int dcb_read(DCB *, GWBUF **, int);
|
||||
int dcb_drain_writeq(DCB *);
|
||||
void dcb_close(DCB *);
|
||||
DCB *dcb_process_zombies(int); /* Process Zombies except the one behind the pointer */
|
||||
void printAllDCBs(); /* Debug to print all DCB in the system */
|
||||
void printDCB(DCB *); /* Debug print routine */
|
||||
void dprintDCBList(DCB *); /* Debug print DCB list statistics */
|
||||
void dprintAllDCBs(DCB *); /* Debug to print all DCB in the system */
|
||||
void dprintOneDCB(DCB *, DCB *); /* Debug to print one DCB */
|
||||
void dprintDCB(DCB *, DCB *); /* Debug to print a DCB in the system */
|
||||
void dListDCBs(DCB *); /* List all DCBs in the system */
|
||||
void dListClients(DCB *); /* List al the client DCBs */
|
||||
const char *gw_dcb_state2string(dcb_state_t); /* DCB state to string */
|
||||
void dcb_printf(DCB *, const char *, ...) __attribute__((format(printf, 2, 3))); /* DCB version of printf */
|
||||
void dcb_hashtable_stats(DCB *, void *); /**< Print statisitics */
|
||||
int dcb_add_callback(DCB *, DCB_REASON, int (*)(struct dcb *, DCB_REASON, void *), void *);
|
||||
int dcb_remove_callback(DCB *, DCB_REASON, int (*)(struct dcb *, DCB_REASON, void *), void *);
|
||||
int dcb_isvalid(DCB *); /* Check the DCB is in the linked list */
|
||||
int dcb_count_by_usage(DCB_USAGE); /* Return counts of DCBs */
|
||||
int dcb_persistent_clean_count(DCB *, bool); /* Clean persistent and return count */
|
||||
|
||||
void dcb_call_foreach (struct server* server, DCB_REASON reason);
|
||||
void dcb_hangup_foreach (struct server* server);
|
||||
size_t dcb_get_session_id(DCB* dcb);
|
||||
bool dcb_get_ses_log_info(DCB* dcb, size_t* sesid, int* enabled_logs);
|
||||
char *dcb_role_name(DCB *); /* Return the name of a role */
|
||||
int dcb_accept_SSL(DCB* dcb);
|
||||
int dcb_connect_SSL(DCB* dcb);
|
||||
int dcb_listen(DCB *listener, const char *config, const char *protocol_name);
|
||||
void dcb_append_readqueue(DCB *dcb, GWBUF *buffer);
|
||||
|
||||
/**
|
||||
* DCB flags values
|
||||
*/
|
||||
#define DCBF_CLONE 0x0001 /*< DCB is a clone */
|
||||
#define DCBF_HUNG 0x0002 /*< Hangup has been dispatched */
|
||||
#define DCBF_REPLIED 0x0004 /*< DCB was written to */
|
||||
|
||||
#define DCB_IS_CLONE(d) ((d)->flags & DCBF_CLONE)
|
||||
#define DCB_REPLIED(d) ((d)->flags & DCBF_REPLIED)
|
||||
#endif /* _DCB_H */
|
46
include/maxscale/def_monitor_event.h
Normal file
46
include/maxscale/def_monitor_event.h
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file def_monitor_event.h
|
||||
*
|
||||
* @verbatim
|
||||
* Revision History
|
||||
*
|
||||
* Date Who Description
|
||||
* 01-06-2013 Martin Brampton Initial implementation
|
||||
*/
|
||||
|
||||
ADDITEM( UNDEFINED_MONITOR_EVENT, undefined ),
|
||||
ADDITEM( MASTER_DOWN_EVENT, master_down ),
|
||||
ADDITEM( MASTER_UP_EVENT, master_up ),
|
||||
ADDITEM( SLAVE_DOWN_EVENT, slave_down ),
|
||||
ADDITEM( SLAVE_UP_EVENT, slave_up ),
|
||||
ADDITEM( SERVER_DOWN_EVENT, server_down ),
|
||||
ADDITEM( SERVER_UP_EVENT, server_up ),
|
||||
ADDITEM( SYNCED_DOWN_EVENT, synced_down ),
|
||||
ADDITEM( SYNCED_UP_EVENT, synced_up ),
|
||||
ADDITEM( DONOR_DOWN_EVENT, donor_down ),
|
||||
ADDITEM( DONOR_UP_EVENT, donor_up ),
|
||||
ADDITEM( NDB_DOWN_EVENT, ndb_down ),
|
||||
ADDITEM( NDB_UP_EVENT, ndb_up ),
|
||||
ADDITEM( LOST_MASTER_EVENT, lost_master ),
|
||||
ADDITEM( LOST_SLAVE_EVENT, lost_slave ),
|
||||
ADDITEM( LOST_SYNCED_EVENT, lost_synced ),
|
||||
ADDITEM( LOST_DONOR_EVENT, lost_donor ),
|
||||
ADDITEM( LOST_NDB_EVENT, lost_ndb ),
|
||||
ADDITEM( NEW_MASTER_EVENT, new_master ),
|
||||
ADDITEM( NEW_SLAVE_EVENT, new_slave ),
|
||||
ADDITEM( NEW_SYNCED_EVENT, new_synced ),
|
||||
ADDITEM( NEW_DONOR_EVENT, new_donor ),
|
||||
ADDITEM( NEW_NDB_EVENT, new_ndb ),
|
41
include/maxscale/externcmd.h
Normal file
41
include/maxscale/externcmd.h
Normal file
@ -0,0 +1,41 @@
|
||||
#ifndef _EXTERN_CMD_HG
|
||||
#define _EXTERN_CMD_HG
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <maxscale/skygw_utils.h>
|
||||
#include <maxscale/log_manager.h>
|
||||
#include <maxscale/maxscale_pcre2.h>
|
||||
|
||||
#define MAXSCALE_EXTCMD_ARG_MAX 256
|
||||
|
||||
typedef struct extern_cmd_t
|
||||
{
|
||||
char** argv; /*< Argument vector for the command, first being the actual command
|
||||
* being executed. */
|
||||
int n_exec; /*< Number of times executed */
|
||||
pid_t child; /*< PID of the child process */
|
||||
} EXTERNCMD;
|
||||
|
||||
char* externcmd_extract_command(const char* argstr);
|
||||
EXTERNCMD* externcmd_allocate(char* argstr);
|
||||
void externcmd_free(EXTERNCMD* cmd);
|
||||
int externcmd_execute(EXTERNCMD* cmd);
|
||||
bool externcmd_substitute_arg(EXTERNCMD* cmd, const char* re, const char* replace);
|
||||
bool externcmd_can_execute(const char* argstr);
|
||||
bool externcmd_matches(const EXTERNCMD* cmd, const char* match);
|
||||
|
||||
#endif
|
119
include/maxscale/filter.h
Normal file
119
include/maxscale/filter.h
Normal file
@ -0,0 +1,119 @@
|
||||
#ifndef _FILTER_H
|
||||
#define _FILTER_H
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file filter.h - The filter interface mechanisms
|
||||
*
|
||||
* Revision History
|
||||
*
|
||||
* Date Who Description
|
||||
* 27/05/2014 Mark Riddoch Initial implementation
|
||||
*
|
||||
*/
|
||||
#include <maxscale/dcb.h>
|
||||
#include <maxscale/session.h>
|
||||
#include <maxscale/buffer.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* The FILTER handle points to module specific data, so the best we can do
|
||||
* is to make it a void * externally.
|
||||
*/
|
||||
typedef void *FILTER;
|
||||
|
||||
/**
|
||||
* The structure used to pass name, value pairs to the filter instances
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
char *name; /**< Name of the parameter */
|
||||
char *value; /**< Value of the parameter */
|
||||
} FILTER_PARAMETER;
|
||||
|
||||
/**
|
||||
* @verbatim
|
||||
* The "module object" structure for a query router module
|
||||
*
|
||||
* The entry points are:
|
||||
* createInstance Called by the service to create a new
|
||||
* instance of the filter
|
||||
* newSession Called to create a new user session
|
||||
* within the filter
|
||||
* closeSession Called when a session is closed
|
||||
* freeSession Called when a session is freed
|
||||
* setDownstream Sets the downstream component of the
|
||||
* filter pipline
|
||||
* routeQuery Called on each query that requires
|
||||
* routing
|
||||
* clientReply Called for each reply packet
|
||||
* diagnostics Called to force the filter to print
|
||||
* diagnostic output
|
||||
*
|
||||
* @endverbatim
|
||||
*
|
||||
* @see load_module
|
||||
*/
|
||||
typedef struct filter_object
|
||||
{
|
||||
FILTER *(*createInstance)(const char *name,
|
||||
char **options,
|
||||
FILTER_PARAMETER **params);
|
||||
void *(*newSession)(FILTER *instance, SESSION *session);
|
||||
void (*closeSession)(FILTER *instance, void *fsession);
|
||||
void (*freeSession)(FILTER *instance, void *fsession);
|
||||
void (*setDownstream)(FILTER *instance, void *fsession, DOWNSTREAM *downstream);
|
||||
void (*setUpstream)(FILTER *instance, void *fsession, UPSTREAM *downstream);
|
||||
int (*routeQuery)(FILTER *instance, void *fsession, GWBUF *queue);
|
||||
int (*clientReply)(FILTER *instance, void *fsession, GWBUF *queue);
|
||||
void (*diagnostics)(FILTER *instance, void *fsession, DCB *dcb);
|
||||
} FILTER_OBJECT;
|
||||
|
||||
/**
|
||||
* The filter API version. If the FILTER_OBJECT structure or the filter API
|
||||
* is changed these values must be updated in line with the rules in the
|
||||
* file modinfo.h.
|
||||
*/
|
||||
#define FILTER_VERSION {2, 1, 0}
|
||||
/**
|
||||
* The definition of a filter from the configuration file.
|
||||
* This is basically the link between a plugin to load and the
|
||||
* optons to pass to that plugin.
|
||||
*/
|
||||
typedef struct filter_def
|
||||
{
|
||||
char *name; /**< The Filter name */
|
||||
char *module; /**< The module to load */
|
||||
char **options; /**< The options set for this filter */
|
||||
FILTER_PARAMETER **parameters; /**< The filter parameters */
|
||||
FILTER filter; /**< The runtime filter */
|
||||
FILTER_OBJECT *obj; /**< The "MODULE_OBJECT" for the filter */
|
||||
SPINLOCK spin; /**< Spinlock to protect the filter definition */
|
||||
struct filter_def *next; /**< Next filter in the chain of all filters */
|
||||
} FILTER_DEF;
|
||||
|
||||
FILTER_DEF *filter_alloc(char *, char *);
|
||||
void filter_free(FILTER_DEF *);
|
||||
bool filter_load(FILTER_DEF* filter);
|
||||
FILTER_DEF *filter_find(char *);
|
||||
void filterAddOption(FILTER_DEF *, char *);
|
||||
void filterAddParameter(FILTER_DEF *, char *, char *);
|
||||
DOWNSTREAM *filterApply(FILTER_DEF *, SESSION *, DOWNSTREAM *);
|
||||
UPSTREAM *filterUpstream(FILTER_DEF *, void *, UPSTREAM *);
|
||||
int filter_standard_parameter(char *);
|
||||
void dprintAllFilters(DCB *);
|
||||
void dprintFilter(DCB *, FILTER_DEF *);
|
||||
void dListFilters(DCB *);
|
||||
|
||||
#endif
|
86
include/maxscale/gw.h
Normal file
86
include/maxscale/gw.h
Normal file
@ -0,0 +1,86 @@
|
||||
#ifndef _GW_HG
|
||||
#define _GW_HG
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <netdb.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <syslog.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <pwd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/epoll.h>
|
||||
#include <signal.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <stdbool.h>
|
||||
#include <maxscale/gwdirs.h>
|
||||
|
||||
#define EXIT_FAILURE 1
|
||||
|
||||
// network buffer is 32K
|
||||
#define MAX_BUFFER_SIZE 32768
|
||||
|
||||
/**
|
||||
* Configuration for send and receive socket buffer sizes for
|
||||
* backend and cleint connections.
|
||||
*/
|
||||
#define GW_BACKEND_SO_SNDBUF (128 * 1024)
|
||||
#define GW_BACKEND_SO_RCVBUF (128 * 1024)
|
||||
#define GW_CLIENT_SO_SNDBUF (128 * 1024)
|
||||
#define GW_CLIENT_SO_RCVBUF (128 * 1024)
|
||||
|
||||
#define GW_NOINTR_CALL(A) do { errno = 0; A; } while (errno == EINTR)
|
||||
#define GW_MYSQL_LOOP_TIMEOUT 300000000
|
||||
#define GW_MYSQL_READ 0
|
||||
#define GW_MYSQL_WRITE 1
|
||||
|
||||
#define GW_MYSQL_PROTOCOL_VERSION 10 // version is 10
|
||||
#define GW_MYSQL_HANDSHAKE_FILLER 0x00
|
||||
#define GW_MYSQL_SERVER_CAPABILITIES_BYTE1 0xff
|
||||
#define GW_MYSQL_SERVER_CAPABILITIES_BYTE2 0xf7
|
||||
#define GW_MYSQL_SERVER_LANGUAGE 0x08
|
||||
#define GW_MYSQL_MAX_PACKET_LEN 0xffffffL;
|
||||
#define GW_MYSQL_SCRAMBLE_SIZE 20
|
||||
|
||||
// debug for mysql_* functions
|
||||
#define MYSQL_CONN_DEBUG
|
||||
#undef MYSQL_CONN_DEBUG
|
||||
|
||||
#include "dcb.h"
|
||||
|
||||
bool gw_daemonize(void);
|
||||
int do_read_dcb(DCB *dcb);
|
||||
void MySQLListener(int epfd, char *config_bind);
|
||||
int MySQLAccept(DCB *listener);
|
||||
int do_read_dcb(DCB *dcb);
|
||||
int do_read_10(DCB *dcb, uint8_t *buffer);
|
||||
int MySQLWrite(DCB *dcb, GWBUF *queue);
|
||||
int setnonblocking(int fd);
|
||||
int gw_getsockerrno(int fd);
|
||||
int parse_bindconfig(const char *, struct sockaddr_in *);
|
||||
int setipaddress(struct in_addr *, char *);
|
||||
char* get_libdir();
|
||||
long get_processor_count();
|
||||
void clean_up_pathname(char *path);
|
||||
bool mxs_mkdir_all(const char *path, int mask);
|
||||
#endif
|
138
include/maxscale/gw_authenticator.h
Normal file
138
include/maxscale/gw_authenticator.h
Normal file
@ -0,0 +1,138 @@
|
||||
#ifndef GW_AUTHENTICATOR_H
|
||||
#define GW_AUTHENTICATOR_H
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file protocol.h
|
||||
*
|
||||
* The authenticator module interface definitions for MaxScale
|
||||
*
|
||||
* @verbatim
|
||||
* Revision History
|
||||
*
|
||||
* Date Who Description
|
||||
* 17/02/16 Martin Brampton Initial implementation
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
|
||||
#include <maxscale/buffer.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/dh.h>
|
||||
|
||||
/** Maximum number of authenticator options */
|
||||
#define AUTHENTICATOR_MAX_OPTIONS 256
|
||||
|
||||
struct dcb;
|
||||
struct server;
|
||||
struct session;
|
||||
struct servlistener;
|
||||
|
||||
/**
|
||||
* @verbatim
|
||||
* The operations that can be performed on the descriptor
|
||||
*
|
||||
* initialize Initialize the authenticator instance. The return value
|
||||
* of this function will be given to the `create` entry point.
|
||||
* If a module does not implement this entry point, the value
|
||||
* given to the `create` is NULL.
|
||||
*
|
||||
* create Create a data structure unique to this DCB, stored in
|
||||
* `dcb->authenticator_data`. If a module does not implement
|
||||
* this entry point, `dcb->authenticator_data` will be set to NULL.
|
||||
*
|
||||
* extract Extract the data from a buffer and place in a structure
|
||||
* shared at the session level, stored in `dcb->data`
|
||||
*
|
||||
* connectSSL Determine whether the connection can support SSL
|
||||
*
|
||||
* authenticate Carry out the authentication
|
||||
*
|
||||
* free Free extracted data. This is only called for the client
|
||||
* side authenticators so backend authenticators should not
|
||||
* implement it.
|
||||
*
|
||||
* destroy Destroy the unique DCB data returned by the `create`
|
||||
* entry point.
|
||||
*
|
||||
* loadUsers Load or update authenticator user data
|
||||
* @endverbatim
|
||||
*
|
||||
* This forms the "module object" for authenticator modules within the gateway.
|
||||
*
|
||||
* @see load_module
|
||||
*/
|
||||
typedef struct gw_authenticator
|
||||
{
|
||||
void* (*initialize)(char **options);
|
||||
void* (*create)(void* instance);
|
||||
int (*extract)(struct dcb *, GWBUF *);
|
||||
bool (*connectssl)(struct dcb *);
|
||||
int (*authenticate)(struct dcb *);
|
||||
void (*free)(struct dcb *);
|
||||
void (*destroy)(void *);
|
||||
int (*loadusers)(struct servlistener *);
|
||||
} GWAUTHENTICATOR;
|
||||
|
||||
/** Return values for extract and authenticate entry points */
|
||||
#define MXS_AUTH_SUCCEEDED 0 /**< Authentication was successful */
|
||||
#define MXS_AUTH_FAILED 1 /**< Authentication failed */
|
||||
#define MXS_AUTH_FAILED_DB 2 /**< Authentication failed, database not found */
|
||||
#define MXS_AUTH_FAILED_SSL 3 /**< SSL authentication failed */
|
||||
#define MXS_AUTH_INCOMPLETE 4 /**< Authentication is not yet complete */
|
||||
#define MXS_AUTH_SSL_INCOMPLETE 5 /**< SSL connection is not yet complete */
|
||||
#define MXS_AUTH_NO_SESSION 6
|
||||
|
||||
/** Return values for the loadusers entry point */
|
||||
#define MXS_AUTH_LOADUSERS_OK 0 /**< Users loaded successfully */
|
||||
#define MXS_AUTH_LOADUSERS_ERROR 1 /**< Failed to load users */
|
||||
|
||||
/**
|
||||
* Authentication states
|
||||
*
|
||||
* The state usually goes from INIT to CONNECTED and alternates between
|
||||
* MESSAGE_READ and RESPONSE_SENT until ending up in either FAILED or COMPLETE.
|
||||
*
|
||||
* If the server immediately rejects the connection, the state ends up in
|
||||
* HANDSHAKE_FAILED. If the connection creation would block, instead of going to
|
||||
* the CONNECTED state, the connection will be in PENDING_CONNECT state until
|
||||
* the connection can be created.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
MXS_AUTH_STATE_INIT, /**< Initial authentication state */
|
||||
MXS_AUTH_STATE_PENDING_CONNECT,/**< Connection creation is underway */
|
||||
MXS_AUTH_STATE_CONNECTED, /**< Network connection to server created */
|
||||
MXS_AUTH_STATE_MESSAGE_READ, /**< Read a authentication message from the server */
|
||||
MXS_AUTH_STATE_RESPONSE_SENT, /**< Responded to the read authentication message */
|
||||
MXS_AUTH_STATE_FAILED, /**< Authentication failed */
|
||||
MXS_AUTH_STATE_HANDSHAKE_FAILED, /**< Authentication failed immediately */
|
||||
MXS_AUTH_STATE_COMPLETE /**< Authentication is complete */
|
||||
} mxs_auth_state_t;
|
||||
|
||||
/**
|
||||
* The GWAUTHENTICATOR version data. The following should be updated whenever
|
||||
* the GWAUTHENTICATOR structure is changed. See the rules defined in modinfo.h
|
||||
* that define how these numbers should change.
|
||||
*/
|
||||
#define GWAUTHENTICATOR_VERSION {1, 1, 0}
|
||||
|
||||
|
||||
bool authenticator_init(void **instance, const char *authenticator, const char *options);
|
||||
char* get_default_authenticator(const char *protocol);
|
||||
|
||||
#endif /* GW_AUTHENTICATOR_H */
|
||||
|
86
include/maxscale/gw_protocol.h
Normal file
86
include/maxscale/gw_protocol.h
Normal file
@ -0,0 +1,86 @@
|
||||
#ifndef GW_PROTOCOL_H
|
||||
#define GW_PROTOCOL_H
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file protocol.h
|
||||
*
|
||||
* The listener definitions for MaxScale
|
||||
*
|
||||
* @verbatim
|
||||
* Revision History
|
||||
*
|
||||
* Date Who Description
|
||||
* 22/01/16 Martin Brampton Initial implementation
|
||||
* 31/05/16 Martin Brampton Add API entry for connection limit
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
|
||||
#include <maxscale/buffer.h>
|
||||
|
||||
struct dcb;
|
||||
struct server;
|
||||
struct session;
|
||||
|
||||
/**
|
||||
* @verbatim
|
||||
* The operations that can be performed on the descriptor
|
||||
*
|
||||
* read EPOLLIN handler for the socket
|
||||
* write MaxScale data write entry point
|
||||
* write_ready EPOLLOUT handler for the socket, indicates
|
||||
* that the socket is ready to send more data
|
||||
* error EPOLLERR handler for the socket
|
||||
* hangup EPOLLHUP handler for the socket
|
||||
* accept Accept handler for listener socket only
|
||||
* connect Create a connection to the specified server
|
||||
* for the session pased in
|
||||
* close MaxScale close entry point for the socket
|
||||
* listen Create a listener for the protocol
|
||||
* auth Authentication entry point
|
||||
* session Session handling entry point
|
||||
* @endverbatim
|
||||
*
|
||||
* This forms the "module object" for protocol modules within the gateway.
|
||||
*
|
||||
* @see load_module
|
||||
*/
|
||||
typedef struct gw_protocol
|
||||
{
|
||||
int (*read)(struct dcb *);
|
||||
int (*write)(struct dcb *, GWBUF *);
|
||||
int (*write_ready)(struct dcb *);
|
||||
int (*error)(struct dcb *);
|
||||
int (*hangup)(struct dcb *);
|
||||
int (*accept)(struct dcb *);
|
||||
int (*connect)(struct dcb *, struct server *, struct session *);
|
||||
int (*close)(struct dcb *);
|
||||
int (*listen)(struct dcb *, char *);
|
||||
int (*auth)(struct dcb *, struct server *, struct session *, GWBUF *);
|
||||
int (*session)(struct dcb *, void *);
|
||||
char *(*auth_default)();
|
||||
int (*connlimit)(struct dcb *, int limit);
|
||||
} GWPROTOCOL;
|
||||
|
||||
/**
|
||||
* The GWPROTOCOL version data. The following should be updated whenever
|
||||
* the GWPROTOCOL structure is changed. See the rules defined in modinfo.h
|
||||
* that define how these numbers should change.
|
||||
*/
|
||||
#define GWPROTOCOL_VERSION {1, 1, 0}
|
||||
|
||||
|
||||
#endif /* GW_PROTOCOL_H */
|
||||
|
81
include/maxscale/gw_ssl.h
Normal file
81
include/maxscale/gw_ssl.h
Normal file
@ -0,0 +1,81 @@
|
||||
#ifndef _GW_SSL_H
|
||||
#define _GW_SSL_H
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file gw_ssl.h
|
||||
*
|
||||
* The SSL definitions for MaxScale
|
||||
*
|
||||
* @verbatim
|
||||
* Revision History
|
||||
*
|
||||
* Date Who Description
|
||||
* 27/01/16 Martin Brampton Initial implementation
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
|
||||
#include <maxscale/gw_protocol.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/dh.h>
|
||||
|
||||
struct dcb;
|
||||
|
||||
typedef enum ssl_method_type
|
||||
{
|
||||
SERVICE_TLS10,
|
||||
#ifdef OPENSSL_1_0
|
||||
SERVICE_TLS11,
|
||||
SERVICE_TLS12,
|
||||
#endif
|
||||
SERVICE_SSL_MAX,
|
||||
SERVICE_TLS_MAX,
|
||||
SERVICE_SSL_TLS_MAX
|
||||
} ssl_method_type_t;
|
||||
|
||||
/**
|
||||
* Return codes for SSL authentication checks
|
||||
*/
|
||||
#define SSL_AUTH_CHECKS_OK 0
|
||||
#define SSL_ERROR_CLIENT_NOT_SSL 1
|
||||
#define SSL_ERROR_ACCEPT_FAILED 2
|
||||
|
||||
/**
|
||||
* The ssl_listener structure is used to aggregate the SSL configuration items
|
||||
* and data for a particular listener
|
||||
*/
|
||||
typedef struct ssl_listener
|
||||
{
|
||||
SSL_CTX *ctx;
|
||||
SSL_METHOD *method; /*< SSLv3 or TLS1.0/1.1/1.2 methods
|
||||
* see: https://www.openssl.org/docs/ssl/SSL_CTX_new.html */
|
||||
int ssl_cert_verify_depth; /*< SSL certificate verification depth */
|
||||
int ssl_method_type; /*< Which of the SSLv3 or TLS1.0/1.1/1.2 methods to use */
|
||||
char *ssl_cert; /*< SSL certificate */
|
||||
char *ssl_key; /*< SSL private key */
|
||||
char *ssl_ca_cert; /*< SSL CA certificate */
|
||||
bool ssl_init_done; /*< If SSL has already been initialized for this service */
|
||||
} SSL_LISTENER;
|
||||
|
||||
int ssl_authenticate_client(struct dcb *dcb, bool is_capable);
|
||||
bool ssl_is_connection_healthy(struct dcb *dcb);
|
||||
bool ssl_check_data_to_process(struct dcb *dcb);
|
||||
bool ssl_required_by_dcb(struct dcb *dcb);
|
||||
bool ssl_required_but_not_negotiated(struct dcb *dcb);
|
||||
const char* ssl_method_type_to_string(ssl_method_type_t method_type);
|
||||
|
||||
#endif /* _GW_SSL_H */
|
58
include/maxscale/gwbitmask.h
Normal file
58
include/maxscale/gwbitmask.h
Normal file
@ -0,0 +1,58 @@
|
||||
#ifndef _GWBITMASK_H
|
||||
#define _GWBITMASK_H
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
|
||||
#include <maxscale/spinlock.h>
|
||||
#include <maxscale/limits.h>
|
||||
|
||||
/**
|
||||
* @file gwbitmask.h An implementation of an arbitrarily long bitmask
|
||||
*
|
||||
* @verbatim
|
||||
* Revision History
|
||||
*
|
||||
* Date Who Description
|
||||
* 28/06/13 Mark Riddoch Initial implementation
|
||||
* 17/10/15 Martin Brampton Add bitmask_render_readable
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
|
||||
/* This number MUST an be exact multiple of 8 */
|
||||
#define MXS_BITMASK_LENGTH (MXS_MAX_THREADS + 1) /**< Number of bits in the bitmask */
|
||||
|
||||
#define MXS_BITMASK_SIZE (MXS_BITMASK_LENGTH / 8) /**< Number of bytes in the bitmask */
|
||||
|
||||
/**
|
||||
* The bitmask structure used to store a fixed size bitmask
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
SPINLOCK lock; /**< Lock to protect the bitmask */
|
||||
unsigned char bits[MXS_BITMASK_SIZE]; /**< The bits themselves */
|
||||
} GWBITMASK;
|
||||
|
||||
#define GWBITMASK_INIT {SPINLOCK_INIT}
|
||||
|
||||
extern void bitmask_init(GWBITMASK *);
|
||||
extern void bitmask_free(GWBITMASK *);
|
||||
extern int bitmask_set(GWBITMASK *, int);
|
||||
extern int bitmask_clear(GWBITMASK *, int);
|
||||
extern int bitmask_clear_without_spinlock(GWBITMASK *, int);
|
||||
extern int bitmask_isset(GWBITMASK *, int);
|
||||
extern int bitmask_isallclear(GWBITMASK *);
|
||||
extern void bitmask_copy(GWBITMASK *, GWBITMASK *);
|
||||
extern char *bitmask_render_readable(GWBITMASK *);
|
||||
|
||||
#endif
|
81
include/maxscale/gwdirs.h.in
Normal file
81
include/maxscale/gwdirs.h.in
Normal file
@ -0,0 +1,81 @@
|
||||
#ifndef _GW_DIRS_HG
|
||||
#define _GW_DIRS_HG
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE 1
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <maxscale/skygw_utils.h>
|
||||
|
||||
EXTERN_C_BLOCK_BEGIN
|
||||
|
||||
/**
|
||||
* All of the following DEFAULT_* variables are defined in cmake/install_layout.cmake
|
||||
*/
|
||||
#define MXS_DEFAULT_PID_SUBPATH "@DEFAULT_PID_SUBPATH@"
|
||||
#define MXS_DEFAULT_LOG_SUBPATH "@DEFAULT_LOG_SUBPATH@"
|
||||
#define MXS_DEFAULT_DATA_SUBPATH "@DEFAULT_DATA_SUBPATH@"
|
||||
#define MXS_DEFAULT_LIB_SUBPATH "@DEFAULT_LIB_SUBPATH@"
|
||||
#define MXS_DEFAULT_CACHE_SUBPATH "@DEFAULT_CACHE_SUBPATH@"
|
||||
#define MXS_DEFAULT_LANG_SUBPATH "@DEFAULT_LANG_SUBPATH@"
|
||||
#define MXS_DEFAULT_EXEC_SUBPATH "@DEFAULT_EXEC_SUBPATH@"
|
||||
#define MXS_DEFAULT_CONFIG_SUBPATH "@DEFAULT_CONFIG_SUBPATH@"
|
||||
|
||||
/** Default file locations, configured by CMake */
|
||||
static const char* default_cnf_fname = "maxscale.cnf";
|
||||
static const char* default_configdir = "@DEFAULT_CONFIGDIR@";
|
||||
/*< This should be changed to just /run eventually,
|
||||
* the /var/run folder is an old standard and the newer FSH 3.0
|
||||
* uses /run for PID files.*/
|
||||
static const char* default_piddir = "@DEFAULT_PIDDIR@";
|
||||
static const char* default_logdir = "@DEFAULT_LOGDIR@";
|
||||
static const char* default_datadir = "@DEFAULT_DATADIR@";
|
||||
static const char* default_libdir = "@DEFAULT_LIBDIR@";
|
||||
static const char* default_cachedir = "@DEFAULT_CACHEDIR@";
|
||||
static const char* default_langdir = "@DEFAULT_LANGDIR@";
|
||||
static const char* default_execdir = "@DEFAULT_EXECDIR@";
|
||||
|
||||
static char* configdir = NULL;
|
||||
static char* logdir = NULL;
|
||||
static char* libdir = NULL;
|
||||
static char* cachedir = NULL;
|
||||
static char* maxscaledatadir = NULL; /*< The data directory */
|
||||
static char* processdatadir = NULL; /*< Process specific data directory */
|
||||
static char* langdir = NULL;
|
||||
static char* piddir = NULL;
|
||||
static char* execdir = NULL;
|
||||
|
||||
void set_libdir(char* param);
|
||||
void set_datadir(char* param);
|
||||
void set_process_datadir(char* param);
|
||||
void set_cachedir(char* param);
|
||||
void set_configdir(char* param);
|
||||
void set_logdir(char* param);
|
||||
void set_langdir(char* param);
|
||||
void set_piddir(char* param);
|
||||
void set_execdir(char* param);
|
||||
char* get_libdir();
|
||||
char* get_datadir();
|
||||
char* get_process_datadir();
|
||||
char* get_cachedir();
|
||||
char* get_configdir();
|
||||
char* get_piddir();
|
||||
char* get_logdir();
|
||||
char* get_langdir();
|
||||
char* get_execdir();
|
||||
|
||||
EXTERN_C_BLOCK_END
|
||||
|
||||
#endif
|
155
include/maxscale/hashtable.h
Normal file
155
include/maxscale/hashtable.h
Normal file
@ -0,0 +1,155 @@
|
||||
#ifndef _HASTABLE_H
|
||||
#define _HASTABLE_H
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file hashtable.h A general purpose hashtable mechanism for use within the
|
||||
* gateway
|
||||
*
|
||||
* @verbatim
|
||||
* Revision History
|
||||
*
|
||||
* Date Who Description
|
||||
* 23/06/2013 Mark Riddoch Initial implementation
|
||||
* 23/07/2013 Mark Riddoch Addition of iterator mechanism
|
||||
* 08/01/2014 Massimiliano Pinto Added function pointers for key/value copy and free
|
||||
* the routine hashtable_memory_fns() changed accordingly
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
#include <maxscale/skygw_debug.h>
|
||||
#include <maxscale/spinlock.h>
|
||||
|
||||
EXTERN_C_BLOCK_BEGIN
|
||||
|
||||
/**
|
||||
* The entries within a hashtable.
|
||||
*
|
||||
* A NULL value for key indicates an empty entry.
|
||||
* The next pointer is the overflow chain for this hashentry.
|
||||
*/
|
||||
typedef struct hashentry
|
||||
{
|
||||
void *key; /**< The value of the key or NULL if empty entry */
|
||||
void *value; /**< The value associated with key */
|
||||
struct hashentry *next; /**< The overflow chain */
|
||||
} HASHENTRIES;
|
||||
|
||||
/**
|
||||
* HASHTABLE iterator - used to walk the hashtable in a thread safe
|
||||
* way
|
||||
*/
|
||||
typedef struct hashiterator
|
||||
{
|
||||
struct hashtable *table; /**< The hashtable the iterator refers to */
|
||||
int chain; /**< The current chain we are walking */
|
||||
int depth; /**< The current depth down the chain */
|
||||
} HASHITERATOR;
|
||||
|
||||
/**
|
||||
* The type definition for the hash function
|
||||
*/
|
||||
typedef int (*HASHHASHFN)(const void *);
|
||||
|
||||
/**
|
||||
* The type definition for the comparison function
|
||||
*/
|
||||
typedef int (*HASHCMPFN)(const void *, const void *);
|
||||
|
||||
/**
|
||||
* The type definition for the key/value copying functions
|
||||
*/
|
||||
typedef void *(*HASHCOPYFN)(const void *);
|
||||
|
||||
/**
|
||||
* The type definition for the key/value freeing functions
|
||||
*/
|
||||
typedef void (*HASHFREEFN)(void *);
|
||||
|
||||
/**
|
||||
* The general purpose hashtable struct.
|
||||
*/
|
||||
typedef struct hashtable
|
||||
{
|
||||
#if defined(SS_DEBUG)
|
||||
skygw_chk_t ht_chk_top;
|
||||
#endif
|
||||
int hashsize; /**< The number of HASHENTRIES */
|
||||
HASHENTRIES **entries; /**< The entries themselves */
|
||||
HASHHASHFN hashfn; /**< The hash function */
|
||||
HASHCMPFN cmpfn; /**< The key comparison function */
|
||||
HASHCOPYFN kcopyfn; /**< Optional key copy function */
|
||||
HASHCOPYFN vcopyfn; /**< Optional value copy function */
|
||||
HASHFREEFN kfreefn; /**< Optional key free function */
|
||||
HASHFREEFN vfreefn; /**< Optional value free function */
|
||||
SPINLOCK spin; /**< Internal spinlock for the hashtable */
|
||||
int n_readers; /**< Number of clients reading the table */
|
||||
int writelock; /**< The table is locked by a writer */
|
||||
bool ht_isflat; /**< Indicates whether hashtable is in stack or heap */
|
||||
int n_elements; /**< Number of added elements */
|
||||
#if defined(SS_DEBUG)
|
||||
skygw_chk_t ht_chk_tail;
|
||||
#endif
|
||||
} HASHTABLE;
|
||||
|
||||
extern HASHTABLE *hashtable_alloc(int, HASHHASHFN hashfn, HASHCMPFN cmpfn);
|
||||
HASHTABLE *hashtable_alloc_flat(HASHTABLE* target,
|
||||
int size,
|
||||
HASHHASHFN hashfn,
|
||||
HASHCMPFN cmpfn);
|
||||
/**< Allocate a hashtable */
|
||||
extern void hashtable_memory_fns(HASHTABLE *table,
|
||||
HASHCOPYFN kcopyfn,
|
||||
HASHCOPYFN vcopyfn,
|
||||
HASHFREEFN kfreefn,
|
||||
HASHFREEFN vfreefn);
|
||||
/**< Provide an interface to control key/value memory
|
||||
* manipulation
|
||||
*/
|
||||
extern void hashtable_free(HASHTABLE *); /**< Free a hashtable */
|
||||
extern int hashtable_add(HASHTABLE *, void *, void *); /**< Add an entry */
|
||||
extern int hashtable_delete(HASHTABLE *, void *);
|
||||
/**< Delete an entry table */
|
||||
extern void *hashtable_fetch(HASHTABLE *, void *);
|
||||
/**< Fetch the data for a given key */
|
||||
extern void hashtable_stats(HASHTABLE *); /**< Print statisitics */
|
||||
void hashtable_get_stats(void* hashtable,
|
||||
int* hashsize,
|
||||
int* nelems,
|
||||
int* longest);
|
||||
extern int hashtable_save(HASHTABLE *,
|
||||
const char *filename,
|
||||
int (*keywrite)(int, void*),
|
||||
int (*valuewrite)(int, void*));
|
||||
extern int hashtable_load(HASHTABLE *,
|
||||
const char *filename,
|
||||
void *(*keyread)(int),
|
||||
void *(*valueread)(int));
|
||||
|
||||
extern HASHITERATOR *hashtable_iterator(HASHTABLE *);
|
||||
/**< Allocate an iterator on the hashtable */
|
||||
extern void *hashtable_next(HASHITERATOR *);
|
||||
/**< Return the key of the hash table iterator */
|
||||
extern void hashtable_iterator_free(HASHITERATOR *);
|
||||
extern int hashtable_size(HASHTABLE *table);
|
||||
|
||||
extern void hashtable_item_free(void *data);
|
||||
extern int hashtable_item_strcasecmp(const void* str1, const void* str2);
|
||||
extern int hashtable_item_strcmp(const void* str1, const void* str2);
|
||||
extern void* hashtable_item_strdup(const void *str);
|
||||
extern int hashtable_item_strhash(const void *str);
|
||||
|
||||
EXTERN_C_BLOCK_END
|
||||
|
||||
#endif
|
66
include/maxscale/hint.h
Normal file
66
include/maxscale/hint.h
Normal file
@ -0,0 +1,66 @@
|
||||
#ifndef _HINT_H
|
||||
#define _HINT_H
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file hint.h The generic hint data that may be attached to buffers
|
||||
*
|
||||
* @verbatim
|
||||
* Revision History
|
||||
*
|
||||
* Date Who Description
|
||||
* 10/07/14 Mark Riddoch Initial implementation
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
|
||||
#include <maxscale/skygw_debug.h>
|
||||
|
||||
|
||||
/**
|
||||
* The types of hint that are supported by the generic hinting mechanism.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
HINT_ROUTE_TO_MASTER = 1,
|
||||
HINT_ROUTE_TO_SLAVE,
|
||||
HINT_ROUTE_TO_NAMED_SERVER,
|
||||
HINT_ROUTE_TO_UPTODATE_SERVER,
|
||||
HINT_ROUTE_TO_ALL, /*< not implemented yet */
|
||||
HINT_PARAMETER
|
||||
} HINT_TYPE;
|
||||
|
||||
/**
|
||||
* A generic hint.
|
||||
*
|
||||
* A hint has a type associated with it and may optionally have hint
|
||||
* specific data.
|
||||
* Multiple hints may be attached to a single buffer.
|
||||
*/
|
||||
typedef struct hint
|
||||
{
|
||||
HINT_TYPE type; /*< The Type of hint */
|
||||
void *data; /*< Type specific data */
|
||||
void *value; /*< Parameter value for hint */
|
||||
unsigned int dsize; /*< Size of the hint data */
|
||||
struct hint *next; /*< Another hint for this buffer */
|
||||
} HINT;
|
||||
|
||||
extern HINT *hint_alloc(HINT_TYPE, void *, unsigned int);
|
||||
extern HINT *hint_create_parameter(HINT *, char *, char *);
|
||||
extern HINT *hint_create_route(HINT *, HINT_TYPE, char *);
|
||||
extern void hint_free(HINT *);
|
||||
extern HINT *hint_dup(HINT *);
|
||||
bool hint_exists(HINT **, HINT_TYPE);
|
||||
#endif
|
24
include/maxscale/hk_heartbeat.h
Normal file
24
include/maxscale/hk_heartbeat.h
Normal file
@ -0,0 +1,24 @@
|
||||
#ifndef _HK_HEARTBEAT_H
|
||||
#define _HK_HEARTBEAT_H
|
||||
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The global housekeeper heartbeat value. This value is incremented
|
||||
* every 100 milliseconds and may be used for crude timing etc.
|
||||
*/
|
||||
|
||||
extern long hkheartbeat;
|
||||
|
||||
#endif
|
57
include/maxscale/housekeeper.h
Normal file
57
include/maxscale/housekeeper.h
Normal file
@ -0,0 +1,57 @@
|
||||
#ifndef _HOUSEKEEPER_H
|
||||
#define _HOUSEKEEPER_H
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#include <time.h>
|
||||
#include <maxscale/dcb.h>
|
||||
#include <maxscale/hk_heartbeat.h>
|
||||
/**
|
||||
* @file housekeeper.h A mechanism to have task run periodically
|
||||
*
|
||||
* @verbatim
|
||||
* Revision History
|
||||
*
|
||||
* Date Who Description
|
||||
* 29/08/14 Mark Riddoch Initial implementation
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
HK_REPEATED = 1,
|
||||
HK_ONESHOT
|
||||
} HKTASK_TYPE;
|
||||
|
||||
/**
|
||||
* The housekeeper task list
|
||||
*/
|
||||
typedef struct hktask
|
||||
{
|
||||
char *name; /*< A simple task name */
|
||||
void (*task)(void *data); /*< The task to call */
|
||||
void *data; /*< Data to pass the task */
|
||||
int frequency; /*< How often to call the tasks (seconds) */
|
||||
time_t nextdue; /*< When the task should be next run */
|
||||
HKTASK_TYPE type; /*< The task type */
|
||||
struct hktask *next; /*< Next task in the list */
|
||||
} HKTASK;
|
||||
|
||||
extern void hkinit();
|
||||
extern int hktask_add(const char *name, void (*task)(void *), void *data, int frequency);
|
||||
extern int hktask_oneshot(const char *name, void (*task)(void *), void *data, int when);
|
||||
extern int hktask_remove(const char *name);
|
||||
extern void hkshutdown();
|
||||
extern void hkshow_tasks(DCB *pdcb);
|
||||
|
||||
#endif
|
24
include/maxscale/limits.h
Normal file
24
include/maxscale/limits.h
Normal file
@ -0,0 +1,24 @@
|
||||
#ifndef _MAXSCALE_LIMITS_H
|
||||
#define _MAXSCALE_LIMITS_H
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
|
||||
// This file defines hard limits of MaxScale.
|
||||
|
||||
// Thread information is stored in a bitmask whose size must be a
|
||||
// multiple of 8. The bitmask is indexed using the thread id that start
|
||||
// from 1. Hence, the hard maximum number of threads must be a
|
||||
// multiple of 8 minus 1.
|
||||
#define MXS_MAX_THREADS 255
|
||||
|
||||
#endif
|
68
include/maxscale/listener.h
Normal file
68
include/maxscale/listener.h
Normal file
@ -0,0 +1,68 @@
|
||||
#ifndef _LISTENER_H
|
||||
#define _LISTENER_H
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file listener.h
|
||||
*
|
||||
* The listener definitions for MaxScale
|
||||
*
|
||||
* @verbatim
|
||||
* Revision History
|
||||
*
|
||||
* Date Who Description
|
||||
* 19/01/16 Martin Brampton Initial implementation
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
|
||||
#include <maxscale/gw_protocol.h>
|
||||
#include <maxscale/gw_ssl.h>
|
||||
#include <maxscale/hashtable.h>
|
||||
|
||||
struct dcb;
|
||||
struct service;
|
||||
|
||||
/**
|
||||
* The servlistener structure is used to link a service to the protocols that
|
||||
* are used to support that service. It defines the name of the protocol module
|
||||
* that should be loaded to support the client connection and the port that the
|
||||
* protocol should use to listen for incoming client connections.
|
||||
*/
|
||||
typedef struct servlistener
|
||||
{
|
||||
char *name; /**< Name of the listener */
|
||||
char *protocol; /**< Protocol module to load */
|
||||
unsigned short port; /**< Port to listen on */
|
||||
char *address; /**< Address to listen with */
|
||||
char *authenticator; /**< Name of authenticator */
|
||||
void *auth_instance; /**< Authenticator instance created in GWAUTHENTICATOR::initialize() */
|
||||
SSL_LISTENER *ssl; /**< Structure of SSL data or NULL */
|
||||
struct dcb *listener; /**< The DCB for the listener */
|
||||
struct users *users; /**< The user data for this listener */
|
||||
HASHTABLE *resources; /**< hastable for listener resources, i.e. database names */
|
||||
struct service* service; /**< The service which used by this listener */
|
||||
SPINLOCK lock;
|
||||
struct servlistener *next; /**< Next service protocol */
|
||||
} SERV_LISTENER;
|
||||
|
||||
SERV_LISTENER *listener_alloc(struct service* service, char *name, char *protocol,
|
||||
char *address, unsigned short port, char *authenticator,
|
||||
char* options, SSL_LISTENER *ssl);
|
||||
void listener_free(SERV_LISTENER* listener);
|
||||
int listener_set_ssl_version(SSL_LISTENER *ssl_listener, char* version);
|
||||
void listener_set_certificates(SSL_LISTENER *ssl_listener, char* cert, char* key, char* ca_cert);
|
||||
int listener_init_SSL(SSL_LISTENER *ssl_listener);
|
||||
|
||||
#endif
|
119
include/maxscale/listmanager.h
Normal file
119
include/maxscale/listmanager.h
Normal file
@ -0,0 +1,119 @@
|
||||
#ifndef _LISTMANAGER_H
|
||||
#define _LISTMANAGER_H
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file listmanager.h The List Manager header file
|
||||
*
|
||||
*
|
||||
* @verbatim
|
||||
* Revision History
|
||||
*
|
||||
* Date Who Description
|
||||
* 20/04/2016 Martin Brampton Initial implementation
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
|
||||
#include <maxscale/spinlock.h>
|
||||
#include <maxscale/skygw_debug.h>
|
||||
|
||||
struct dcb;
|
||||
|
||||
/*
|
||||
* The possible types of list that could be supported. At present, only
|
||||
* LIST_TYPE_RECYCLABLE is fully tested.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
LIST_TYPE_SIMPLE, /* A simple linked list with pointer to last entry */
|
||||
LIST_TYPE_RECYCLABLE, /* A simple linked list, entries are recycled */
|
||||
LIST_TYPE_DOUBLE, /* A doubly linked list, next and previous */
|
||||
} list_type_t;
|
||||
|
||||
/*
|
||||
* The list entry structure
|
||||
*
|
||||
* Each list entry must have this format, but will typically be extended
|
||||
* well beyond these items. The "previous" field is only required for
|
||||
* a doubly linked list, LIST_TYPE_DOUBLE.
|
||||
*
|
||||
* The first data to be used with the list manager is the DCB. Note that
|
||||
* the first few fields in the DCB structure correspond exactly to the
|
||||
* fields in the list entry structure. The pointers used need to be cast
|
||||
* as appropriate in order to be able to use the same data as either a DCB
|
||||
* or a list entry.
|
||||
*
|
||||
*/
|
||||
#define LIST_ENTRY_FIELDS \
|
||||
skygw_chk_t list_entry_chk_top; \
|
||||
struct list_entry *next; \
|
||||
struct list_entry *previous; \
|
||||
bool entry_is_in_use; \
|
||||
bool entry_is_ready; \
|
||||
skygw_chk_t list_entry_chk_tail;
|
||||
|
||||
typedef struct list_entry
|
||||
{
|
||||
LIST_ENTRY_FIELDS
|
||||
} list_entry_t;
|
||||
|
||||
/*
|
||||
* The list configuration structure
|
||||
*
|
||||
* This provides the basis for a list. It can be declared and initialised
|
||||
* statically, for example in server/core/dcb.c. It includes an anchor
|
||||
* pointer for the list, a pointer to the last entry in the list and the
|
||||
* last entry that was found to be free and reused.
|
||||
*
|
||||
* The count tells us the current number of entries in live use, and maximum
|
||||
* is the highest number ever observed in live use. The freecount is the
|
||||
* number of entries currently free and ready for reuse. The entry_size is
|
||||
* the actual size of the real entries, e.g. the DCB structure (NOT the size
|
||||
* of the list entry structure).
|
||||
*
|
||||
* A spinlock is declared for use during list manipulation operations.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
list_type_t list_type;
|
||||
size_t entry_size;
|
||||
SPINLOCK list_lock;
|
||||
list_entry_t *all_entries;
|
||||
list_entry_t *last_entry;
|
||||
list_entry_t *last_free;
|
||||
int count;
|
||||
int maximum;
|
||||
int freecount;
|
||||
int num_malloc;
|
||||
} LIST_CONFIG;
|
||||
|
||||
void list_initialise(LIST_CONFIG *list_config, list_type_t type_of_list, size_t entry_size);
|
||||
bool list_pre_alloc(LIST_CONFIG *list_config, int num_entries, void (*init_struct)(void *));
|
||||
list_entry_t *list_find_free(LIST_CONFIG *list_config, void (*init_struct)(void *));
|
||||
void dprintListStats(struct dcb *pdcb, LIST_CONFIG *list_config, const char *listname);
|
||||
void list_free_entry (LIST_CONFIG *list_config, list_entry_t *to_be_freed);
|
||||
list_entry_t *list_start_iteration(LIST_CONFIG *list_config);
|
||||
list_entry_t *list_iterate(LIST_CONFIG *list_config, list_entry_t *current_entry);
|
||||
void list_terminate_iteration_early(LIST_CONFIG *list_config, list_entry_t *current_entry);
|
||||
bool list_is_entry_in_use(LIST_CONFIG *list_config, list_entry_t *to_be_found);
|
||||
void list_add_to_end(LIST_CONFIG *list_config, list_entry_t *new_entry);
|
||||
void list_map(LIST_CONFIG *list_config, bool (*callback)(void *, ...));
|
||||
|
||||
/* The following UNTESTED! */
|
||||
list_entry_t *list_remove_first(LIST_CONFIG *list_config);
|
||||
list_entry_t *list_remove_last(LIST_CONFIG *list_config);
|
||||
|
||||
|
||||
#endif /* LISTMANAGER_H */
|
202
include/maxscale/log_manager.h
Normal file
202
include/maxscale/log_manager.h
Normal file
@ -0,0 +1,202 @@
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#if !defined(LOG_MANAGER_H)
|
||||
#define LOG_MANAGER_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <syslog.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We need a common.h file that is included by every component.
|
||||
*/
|
||||
#if !defined(STRERROR_BUFLEN)
|
||||
#define STRERROR_BUFLEN 512
|
||||
#endif
|
||||
|
||||
/**
|
||||
* If MXS_MODULE_NAME is defined before log_manager.h is included, then all
|
||||
* logged messages will be prefixed with that string enclosed in square brackets.
|
||||
* For instance, the following
|
||||
*
|
||||
* #define MXS_MODULE_NAME "xyz"
|
||||
* #include <log_manager.h>
|
||||
*
|
||||
* will lead to every logged message looking like:
|
||||
*
|
||||
* 2016-08-12 13:49:11 error : [xyz] The gadget was not ready
|
||||
*
|
||||
* In general, the value of MXS_MODULE_NAME should be the name of the shared
|
||||
* library to which the source file, where MXS_MODULE_NAME is defined, belongs.
|
||||
*
|
||||
* Note that a file that is compiled into multiple modules should
|
||||
* have MXS_MODULE_NAME defined as something else than the name of a real
|
||||
* module, or not at all.
|
||||
*
|
||||
* Any file that is compiled into maxscale-common should *not* have
|
||||
* MXS_MODULE_NAME defined.
|
||||
*/
|
||||
#if !defined(MXS_MODULE_NAME)
|
||||
#define MXS_MODULE_NAME NULL
|
||||
#endif
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MXS_LOG_TARGET_DEFAULT = 0,
|
||||
MXS_LOG_TARGET_FS = 1, // File system
|
||||
MXS_LOG_TARGET_SHMEM = 2, // Shared memory
|
||||
MXS_LOG_TARGET_STDOUT = 3, // Standard output
|
||||
} mxs_log_target_t;
|
||||
|
||||
/**
|
||||
* Thread-specific logging information.
|
||||
*/
|
||||
typedef struct mxs_log_info
|
||||
{
|
||||
size_t li_sesid;
|
||||
int li_enabled_priorities;
|
||||
} mxs_log_info_t;
|
||||
|
||||
extern int mxs_log_enabled_priorities;
|
||||
extern ssize_t mxs_log_session_count[];
|
||||
extern __thread mxs_log_info_t mxs_log_tls;
|
||||
|
||||
/**
|
||||
* Check if specified log type is enabled in general or if it is enabled
|
||||
* for the current session.
|
||||
*
|
||||
* @param priority One of the syslog LOG_ERR, LOG_WARNING, etc. constants.
|
||||
*/
|
||||
#define MXS_LOG_PRIORITY_IS_ENABLED(priority) \
|
||||
(((mxs_log_enabled_priorities & (1 << priority)) || \
|
||||
(mxs_log_session_count[priority] > 0 && \
|
||||
mxs_log_tls.li_enabled_priorities & (1 << priority))) ? true : false)
|
||||
|
||||
/**
|
||||
* LOG_AUGMENT_WITH_FUNCTION Each logged line is suffixed with [function-name].
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
MXS_LOG_AUGMENT_WITH_FUNCTION = 1,
|
||||
MXS_LOG_AUGMENTATION_MASK = (MXS_LOG_AUGMENT_WITH_FUNCTION)
|
||||
} mxs_log_augmentation_t;
|
||||
|
||||
typedef struct mxs_log_throttling
|
||||
{
|
||||
size_t count; // Maximum number of a specific message...
|
||||
size_t window_ms; // ...during this many milliseconds.
|
||||
size_t suppress_ms; // If exceeded, suppress such messages for this many ms.
|
||||
} MXS_LOG_THROTTLING;
|
||||
|
||||
bool mxs_log_init(const char* ident, const char* logdir, mxs_log_target_t target);
|
||||
void mxs_log_finish(void);
|
||||
|
||||
int mxs_log_flush();
|
||||
int mxs_log_flush_sync();
|
||||
int mxs_log_rotate();
|
||||
|
||||
int mxs_log_set_priority_enabled(int priority, bool enabled);
|
||||
void mxs_log_set_syslog_enabled(bool enabled);
|
||||
void mxs_log_set_maxlog_enabled(bool enabled);
|
||||
void mxs_log_set_highprecision_enabled(bool enabled);
|
||||
void mxs_log_set_augmentation(int bits);
|
||||
void mxs_log_set_throttling(const MXS_LOG_THROTTLING* throttling);
|
||||
|
||||
void mxs_log_get_throttling(MXS_LOG_THROTTLING* throttling);
|
||||
|
||||
int mxs_log_message(int priority,
|
||||
const char* modname,
|
||||
const char* file, int line, const char* function,
|
||||
const char* format, ...) __attribute__((format(printf, 6, 7)));
|
||||
/**
|
||||
* Log an error, warning, notice, info, or debug message.
|
||||
*
|
||||
* @param priority One of the syslog constants (LOG_ERR, LOG_WARNING, ...)
|
||||
* @param format The printf format of the message.
|
||||
* @param ... Arguments, depending on the format.
|
||||
*
|
||||
* NOTE: Should typically not be called directly. Use some of the
|
||||
* MXS_ERROR, MXS_WARNING, etc. macros instead.
|
||||
*/
|
||||
#define MXS_LOG_MESSAGE(priority, format, ...)\
|
||||
mxs_log_message(priority, MXS_MODULE_NAME, __FILE__, __LINE__, __func__, format, ##__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* Log an alert, error, warning, notice, info, or debug message.
|
||||
*
|
||||
* MXS_ALERT Not throttled To be used when the system is about to go down in flames.
|
||||
* MXS_ERROR Throttled For errors.
|
||||
* MXS_WARNING Throttled For warnings.
|
||||
* MXS_NOTICE Not Throttled For messages deemed important, typically used during startup.
|
||||
* MXS_INFO Not Throttled For information thought to be of value for investigating some problem.
|
||||
* MXS_DEBUG Not Throttled For debugging messages during development. Should be removed when a
|
||||
* feature is ready.
|
||||
*
|
||||
* @param format The printf format of the message.
|
||||
* @param ... Arguments, depending on the format.
|
||||
*/
|
||||
#define MXS_ALERT(format, ...) MXS_LOG_MESSAGE(LOG_ALERT, format, ##__VA_ARGS__)
|
||||
#define MXS_ERROR(format, ...) MXS_LOG_MESSAGE(LOG_ERR, format, ##__VA_ARGS__)
|
||||
#define MXS_WARNING(format, ...) MXS_LOG_MESSAGE(LOG_WARNING, format, ##__VA_ARGS__)
|
||||
#define MXS_NOTICE(format, ...) MXS_LOG_MESSAGE(LOG_NOTICE, format, ##__VA_ARGS__)
|
||||
#define MXS_INFO(format, ...) MXS_LOG_MESSAGE(LOG_INFO, format, ##__VA_ARGS__)
|
||||
#define MXS_DEBUG(format, ...) MXS_LOG_MESSAGE(LOG_DEBUG, format, ##__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* Log an out of memory error using custom message.
|
||||
*
|
||||
* @param message Text to be logged.
|
||||
*/
|
||||
// TODO: In an OOM situation, the default logging will (most likely) *not* work,
|
||||
// TODO: as memory is allocated as part of the process. A custom route, that does
|
||||
// TODO: not allocate memory, must be created for OOM messages.
|
||||
// TODO: So, currently these are primarily placeholders.
|
||||
#define MXS_OOM_MESSAGE(message) MXS_ERROR("OOM: %s", message);
|
||||
|
||||
/**
|
||||
* Log an out of memory error using custom message, if the
|
||||
* provided pointer is NULL.
|
||||
*
|
||||
* @param p If NULL, an OOM message will be logged.
|
||||
* @param message Text to be logged.
|
||||
*/
|
||||
#define MXS_OOM_MESSAGE_IFNULL(p, m) do { if (!p) { MXS_OOM_MESSAGE(m); } } while (false)
|
||||
|
||||
/**
|
||||
* Log an out of memory error using a default message.
|
||||
*/
|
||||
#define MXS_OOM() MXS_OOM_MESSAGE(__func__)
|
||||
|
||||
/**
|
||||
* Log an out of memory error using a default message, if the
|
||||
* provided pointer is NULL.
|
||||
*
|
||||
* @param p If NULL, an OOM message will be logged.
|
||||
*/
|
||||
#define MXS_OOM_IFNULL(p) do { if (!p) { MXS_OOM(); } } while (false)
|
||||
|
||||
enum
|
||||
{
|
||||
MXS_OOM_MESSAGE_MAXLEN = 80 /** Maximum length of an OOM message, including the
|
||||
trailing NULL. If longer, it will be cut. */
|
||||
};
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /** LOG_MANAGER_H */
|
163
include/maxscale/maxconfig.h
Normal file
163
include/maxscale/maxconfig.h
Normal file
@ -0,0 +1,163 @@
|
||||
#ifndef _MAXSCALE_CONFIG_H
|
||||
#define _MAXSCALE_CONFIG_H
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#include <maxscale/skygw_utils.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <stdint.h>
|
||||
#include <openssl/sha.h>
|
||||
#include <maxscale/spinlock.h>
|
||||
/**
|
||||
* @file config.h The configuration handling elements
|
||||
*
|
||||
* @verbatim
|
||||
* Revision History
|
||||
*
|
||||
* Date Who Description
|
||||
* 21/06/13 Mark Riddoch Initial implementation
|
||||
* 07/05/14 Massimiliano Pinto Added version_string to global configuration
|
||||
* 23/05/14 Massimiliano Pinto Added id to global configuration
|
||||
* 17/10/14 Mark Riddoch Added poll tuning configuration parameters
|
||||
* 05/03/15 Massimiliano Pinto Added sysname, release, sha1_mac to gateway struct
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
|
||||
#define DEFAULT_NBPOLLS 3 /**< Default number of non block polls before we block */
|
||||
#define DEFAULT_POLLSLEEP 1000 /**< Default poll wait time (milliseconds) */
|
||||
#define _RELEASE_STR_LENGTH 256 /**< release len */
|
||||
#define DEFAULT_NTHREADS 1 /**< Default number of polling threads */
|
||||
/**
|
||||
* Maximum length for configuration parameter value.
|
||||
*/
|
||||
enum
|
||||
{
|
||||
MAX_PARAM_LEN = 256
|
||||
};
|
||||
|
||||
typedef enum
|
||||
{
|
||||
UNDEFINED_TYPE = 0x00,
|
||||
STRING_TYPE = 0x01,
|
||||
COUNT_TYPE = 0x02,
|
||||
PERCENT_TYPE = 0x04,
|
||||
BOOL_TYPE = 0x08,
|
||||
SQLVAR_TARGET_TYPE = 0x10
|
||||
} config_param_type_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TYPE_UNDEFINED = 0,
|
||||
TYPE_MASTER,
|
||||
TYPE_ALL
|
||||
} target_t;
|
||||
|
||||
enum
|
||||
{
|
||||
MAX_RLAG_NOT_AVAILABLE = -1,
|
||||
MAX_RLAG_UNDEFINED = -2
|
||||
};
|
||||
|
||||
#define PARAM_IS_TYPE(p,t) ((p) & (t))
|
||||
|
||||
/**
|
||||
* The config parameter
|
||||
*/
|
||||
typedef struct config_parameter
|
||||
{
|
||||
char *name; /**< The name of the parameter */
|
||||
char *value; /**< The value of the parameter */
|
||||
union
|
||||
{
|
||||
/*< qualified parameter value by type */
|
||||
char* valstr; /*< terminated char* array */
|
||||
int valcount; /*< int */
|
||||
int valpercent; /*< int */
|
||||
bool valbool; /*< bool */
|
||||
target_t valtarget; /*< sql variable route target */
|
||||
} qfd;
|
||||
config_param_type_t qfd_param_type;
|
||||
struct config_parameter *next; /**< Next pointer in the linked list */
|
||||
} CONFIG_PARAMETER;
|
||||
|
||||
/**
|
||||
* The config context structure, used to build the configuration
|
||||
* data during the parse process
|
||||
*/
|
||||
typedef struct config_context
|
||||
{
|
||||
char *object; /**< The name of the object being configured */
|
||||
CONFIG_PARAMETER *parameters; /**< The list of parameter values */
|
||||
void *element; /**< The element created from the data */
|
||||
struct config_context *next; /**< Next pointer in the linked list */
|
||||
} CONFIG_CONTEXT;
|
||||
|
||||
/**
|
||||
* The gateway global configuration data
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int n_threads; /**< Number of polling threads */
|
||||
char *version_string; /**< The version string of embedded db library */
|
||||
char release_string[_RELEASE_STR_LENGTH]; /**< The release name string of the system */
|
||||
char sysname[_UTSNAME_SYSNAME_LENGTH]; /**< The OS name of the system */
|
||||
uint8_t mac_sha1[SHA_DIGEST_LENGTH]; /**< The SHA1 digest of an interface MAC address */
|
||||
unsigned long id; /**< MaxScale ID */
|
||||
unsigned int n_nbpoll; /**< Tune number of non-blocking polls */
|
||||
unsigned int pollsleep; /**< Wait time in blocking polls */
|
||||
int syslog; /**< Log to syslog */
|
||||
int maxlog; /**< Log to MaxScale's own logs */
|
||||
int log_to_shm; /**< Write log-file to shared memory */
|
||||
unsigned int auth_conn_timeout; /**< Connection timeout for the user authentication */
|
||||
unsigned int auth_read_timeout; /**< Read timeout for the user authentication */
|
||||
unsigned int auth_write_timeout; /**< Write timeout for the user authentication */
|
||||
bool skip_permission_checks; /**< Skip service and monitor permission checks */
|
||||
char qc_name[PATH_MAX]; /**< The name of the query classifier to load */
|
||||
char* qc_args; /**< Arguments for the query classifier */
|
||||
} GATEWAY_CONF;
|
||||
|
||||
|
||||
char* config_clean_string_list(char* str);
|
||||
CONFIG_PARAMETER* config_clone_param(CONFIG_PARAMETER* param);
|
||||
void config_enable_feedback_task(void);
|
||||
void config_disable_feedback_task(void);
|
||||
unsigned long config_get_gateway_id(void);
|
||||
GATEWAY_CONF* config_get_global_options();
|
||||
CONFIG_PARAMETER* config_get_param(CONFIG_PARAMETER* params, const char* name);
|
||||
config_param_type_t config_get_paramtype(CONFIG_PARAMETER* param);
|
||||
bool config_get_valint(int* val,
|
||||
CONFIG_PARAMETER* param,
|
||||
const char* name, /*< if NULL examine current param only */
|
||||
config_param_type_t ptype);
|
||||
bool config_get_valbool(bool* val,
|
||||
CONFIG_PARAMETER* param,
|
||||
const char* name, /*< if NULL examine current param only */
|
||||
config_param_type_t ptype);
|
||||
bool config_get_valtarget(target_t* val,
|
||||
CONFIG_PARAMETER* param,
|
||||
const char* name, /*< if NULL examine current param only */
|
||||
config_param_type_t ptype);
|
||||
bool config_load(char *);
|
||||
unsigned int config_nbpolls();
|
||||
double config_percentage_value(char *str);
|
||||
unsigned int config_pollsleep();
|
||||
int config_reload();
|
||||
bool config_set_qualified_param(CONFIG_PARAMETER* param,
|
||||
void* val,
|
||||
config_param_type_t type);
|
||||
int config_threadcount();
|
||||
int config_truth_value(char *);
|
||||
void free_config_parameter(CONFIG_PARAMETER* p1);
|
||||
bool is_internal_service(const char *router);
|
||||
|
||||
#endif
|
46
include/maxscale/maxscale.h
Normal file
46
include/maxscale/maxscale.h
Normal file
@ -0,0 +1,46 @@
|
||||
#ifndef _MAXSCALE_H
|
||||
#define _MAXSCALE_H
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file maxscale.h
|
||||
*
|
||||
* Some general definitions for MaxScale
|
||||
*
|
||||
* @verbatim
|
||||
* Revision History
|
||||
*
|
||||
* Date Who Description
|
||||
* 05/02/14 Mark Riddoch Initial implementation
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
|
||||
#include <time.h>
|
||||
|
||||
|
||||
/* Exit status for MaxScale */
|
||||
#define MAXSCALE_SHUTDOWN 0 /* Good shutdown */
|
||||
#define MAXSCALE_BADCONFIG 1 /* Configuration fiel error */
|
||||
#define MAXSCALE_NOLIBRARY 2 /* No embedded library found */
|
||||
#define MAXSCALE_NOSERVICES 3 /* No servics are running */
|
||||
#define MAXSCALE_ALREADYRUNNING 4 /* MaxScale is already runing */
|
||||
#define MAXSCALE_BADARG 5 /* Bad command line argument */
|
||||
#define MAXSCALE_INTERNALERROR 6 /* Internal error, see error log */
|
||||
|
||||
void maxscale_reset_starttime(void);
|
||||
time_t maxscale_started(void);
|
||||
int maxscale_uptime(void);
|
||||
|
||||
#endif
|
47
include/maxscale/maxscale_pcre2.h
Normal file
47
include/maxscale/maxscale_pcre2.h
Normal file
@ -0,0 +1,47 @@
|
||||
#ifndef _MAXSCALE_PCRE2_H
|
||||
#define _MAXSCALE_PCRE2_H
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PCRE2_CODE_UNIT_WIDTH
|
||||
#define PCRE2_CODE_UNIT_WIDTH 8
|
||||
#endif
|
||||
|
||||
#include <pcre2.h>
|
||||
|
||||
/**
|
||||
* @file maxscale_pcre2.h - Utility functions for regular expression matching
|
||||
* with the bundled PCRE2 library.
|
||||
*
|
||||
* @verbatim
|
||||
* Revision History
|
||||
*
|
||||
* Date Who Description
|
||||
* 30-10-2015 Markus Makela Initial implementation
|
||||
* @endverbatim
|
||||
*/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MXS_PCRE2_MATCH,
|
||||
MXS_PCRE2_NOMATCH,
|
||||
MXS_PCRE2_ERROR
|
||||
} mxs_pcre2_result_t;
|
||||
|
||||
mxs_pcre2_result_t mxs_pcre2_substitute(pcre2_code *re, const char *subject,
|
||||
const char *replace, char** dest, size_t* size);
|
||||
mxs_pcre2_result_t mxs_pcre2_simple_match(const char* pattern, const char* subject,
|
||||
int options, int* error);
|
||||
|
||||
#endif
|
62
include/maxscale/memlog.h
Normal file
62
include/maxscale/memlog.h
Normal file
@ -0,0 +1,62 @@
|
||||
#ifndef _MEMLOG_H
|
||||
#define _MEMLOG_H
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file memlog.h The memory logging mechanism
|
||||
*
|
||||
* @verbatim
|
||||
* Revision History
|
||||
*
|
||||
* Date Who Description
|
||||
* 26/09/14 Mark Riddoch Initial implementation
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
#include <maxscale/spinlock.h>
|
||||
|
||||
typedef enum { ML_INT, ML_LONG, ML_LONGLONG, ML_STRING } MEMLOGTYPE;
|
||||
|
||||
typedef struct memlog
|
||||
{
|
||||
char *name;
|
||||
SPINLOCK lock;
|
||||
void *values;
|
||||
int offset;
|
||||
int size;
|
||||
MEMLOGTYPE type;
|
||||
unsigned int flags;
|
||||
unsigned int iflags;
|
||||
struct memlog *next;
|
||||
} MEMLOG;
|
||||
|
||||
/*
|
||||
* MEMLOG flag bits
|
||||
*/
|
||||
#define MLNOAUTOFLUSH 0x0001
|
||||
|
||||
/*
|
||||
* MEMLOG internal flags
|
||||
*/
|
||||
#define MLWRAPPED 0x0001
|
||||
|
||||
|
||||
extern MEMLOG *memlog_create(char *, MEMLOGTYPE, int);
|
||||
extern void memlog_destroy(MEMLOG *);
|
||||
extern void memlog_set(MEMLOG *, unsigned int);
|
||||
extern void memlog_log(MEMLOG *, void *);
|
||||
extern void memlog_flush_all();
|
||||
extern void memlog_flush(MEMLOG *);
|
||||
|
||||
#endif
|
79
include/maxscale/mlist.h
Normal file
79
include/maxscale/mlist.h
Normal file
@ -0,0 +1,79 @@
|
||||
#ifndef _MLIST_H
|
||||
#define _MLIST_H
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
|
||||
#include <maxscale/skygw_utils.h>
|
||||
|
||||
EXTERN_C_BLOCK_BEGIN
|
||||
|
||||
typedef struct mlist_node_st mlist_node_t;
|
||||
|
||||
typedef struct mlist_st
|
||||
{
|
||||
skygw_chk_t mlist_chk_top;
|
||||
char* mlist_name;
|
||||
void (*mlist_datadel)(void *); /**< clean-up function for data */
|
||||
simple_mutex_t mlist_mutex; /**< protect node updates and clean-up */
|
||||
bool mlist_uselock;
|
||||
bool mlist_islocked;
|
||||
bool mlist_deleted;
|
||||
size_t mlist_nodecount;
|
||||
size_t mlist_nodecount_max; /**< size limit. 0 == no limit */
|
||||
size_t mlist_versno;
|
||||
bool mlist_flat;
|
||||
mlist_node_t* mlist_first;
|
||||
mlist_node_t* mlist_last;
|
||||
skygw_chk_t mlist_chk_tail;
|
||||
} mlist_t;
|
||||
|
||||
typedef struct mlist_cursor_st
|
||||
{
|
||||
skygw_chk_t mlcursor_chk_top;
|
||||
mlist_t* mlcursor_list;
|
||||
mlist_node_t* mlcursor_pos;
|
||||
pthread_t* mlcursor_owner_thr;
|
||||
skygw_chk_t mlcursor_chk_tail;
|
||||
} mlist_cursor_t;
|
||||
|
||||
struct mlist_node_st
|
||||
{
|
||||
skygw_chk_t mlnode_chk_top;
|
||||
mlist_t* mlnode_list;
|
||||
mlist_node_t* mlnode_next;
|
||||
void* mlnode_data;
|
||||
bool mlnode_deleted;
|
||||
skygw_chk_t mlnode_chk_tail;
|
||||
};
|
||||
|
||||
|
||||
mlist_t* mlist_init(mlist_t* mlist,
|
||||
mlist_cursor_t** cursor,
|
||||
char* name,
|
||||
void (*datadel)(void*),
|
||||
int maxnodes);
|
||||
void mlist_done(mlist_t* list);
|
||||
bool mlist_add_data_nomutex(mlist_t* list, void* data);
|
||||
bool mlist_add_node_nomutex(mlist_t* list, mlist_node_t* newnode);
|
||||
mlist_node_t* mlist_detach_first(mlist_t* ml);
|
||||
mlist_node_t* mlist_detach_nodes(mlist_t* ml);
|
||||
void* mlist_node_get_data(mlist_node_t* node);
|
||||
void mlist_node_done(mlist_node_t* n);
|
||||
|
||||
mlist_cursor_t* mlist_cursor_init(mlist_t* ml);
|
||||
void* mlist_cursor_get_data_nomutex(mlist_cursor_t* c);
|
||||
bool mlist_cursor_move_to_first(mlist_cursor_t* c);
|
||||
|
||||
EXTERN_C_BLOCK_END
|
||||
|
||||
#endif
|
86
include/maxscale/modinfo.h
Normal file
86
include/maxscale/modinfo.h
Normal file
@ -0,0 +1,86 @@
|
||||
#ifndef _MODINFO_H
|
||||
#define _MODINFO_H
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file modinfo.h The module information interface
|
||||
*
|
||||
* @verbatim
|
||||
* Revision History
|
||||
*
|
||||
* Date Who Description
|
||||
* 02/06/14 Mark Riddoch Initial implementation
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
|
||||
/**
|
||||
* The status of the module. This gives some idea of the module
|
||||
* maturity.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
MODULE_IN_DEVELOPMENT = 0,
|
||||
MODULE_ALPHA_RELEASE,
|
||||
MODULE_BETA_RELEASE,
|
||||
MODULE_GA,
|
||||
MODULE_EXPERIMENTAL
|
||||
} MODULE_STATUS;
|
||||
|
||||
/**
|
||||
* The API implemented by the module
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
MODULE_API_PROTOCOL = 0,
|
||||
MODULE_API_ROUTER,
|
||||
MODULE_API_MONITOR,
|
||||
MODULE_API_FILTER,
|
||||
MODULE_API_AUTHENTICATOR,
|
||||
MODULE_API_QUERY_CLASSIFIER,
|
||||
} MODULE_API;
|
||||
|
||||
/**
|
||||
* The module version structure.
|
||||
*
|
||||
* The rules for changing these values are:
|
||||
*
|
||||
* Any change that affects an inexisting call in the API in question,
|
||||
* making the new API no longer compatible with the old,
|
||||
* must increment the major version.
|
||||
*
|
||||
* Any change that adds to the API, but does not alter the existing API
|
||||
* calls, must increment the minor version.
|
||||
*
|
||||
* Any change that is purely cosmetic and does not affect the calling
|
||||
* conventions of the API must increment only the patch version number.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int major;
|
||||
int minor;
|
||||
int patch;
|
||||
} MODULE_VERSION;
|
||||
|
||||
/**
|
||||
* The module information structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
MODULE_API modapi;
|
||||
MODULE_STATUS status;
|
||||
MODULE_VERSION api_version;
|
||||
char *description;
|
||||
} MODULE_INFO;
|
||||
#endif
|
76
include/maxscale/modules.h
Normal file
76
include/maxscale/modules.h
Normal file
@ -0,0 +1,76 @@
|
||||
#ifndef _MODULES_H
|
||||
#define _MODULES_H
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#include <maxscale/dcb.h>
|
||||
#include <maxscale/modinfo.h>
|
||||
#include <maxscale/resultset.h>
|
||||
#include <maxscale/skygw_debug.h>
|
||||
|
||||
EXTERN_C_BLOCK_BEGIN
|
||||
|
||||
/**
|
||||
* @file modules.h Utilities for loading modules
|
||||
*
|
||||
* The module interface used within the gateway
|
||||
*
|
||||
* @verbatim
|
||||
* Revision History
|
||||
*
|
||||
* Date Who Description
|
||||
* 13/06/13 Mark Riddoch Initial implementation
|
||||
* 08/07/13 Mark Riddoch Addition of monitor modules
|
||||
* 29/05/14 Mark Riddoch Addition of filter modules
|
||||
* 01/10/14 Mark Riddoch Addition of call to unload all modules on shutdown
|
||||
* 19/02/15 Mark Riddoch Addition of moduleGetList
|
||||
* 26/02/15 Massimiliano Pinto Addition of module_feedback_send
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
|
||||
typedef struct modules
|
||||
{
|
||||
char *module; /**< The name of the module */
|
||||
char *type; /**< The module type */
|
||||
char *version; /**< Module version */
|
||||
void *handle; /**< The handle returned by dlopen */
|
||||
void *modobj; /**< The module "object" this is the set of entry points */
|
||||
MODULE_INFO
|
||||
*info; /**< The module information */
|
||||
struct modules
|
||||
*next; /**< Next module in the linked list */
|
||||
} MODULES;
|
||||
|
||||
/**
|
||||
* Module types
|
||||
*/
|
||||
#define MODULE_PROTOCOL "Protocol" /**< A protocol module type */
|
||||
#define MODULE_AUTHENTICATOR "Authenticator" /**< An authenticator module type */
|
||||
#define MODULE_ROUTER "Router" /**< A router module type */
|
||||
#define MODULE_MONITOR "Monitor" /**< A database monitor module type */
|
||||
#define MODULE_FILTER "Filter" /**< A filter module type */
|
||||
#define MODULE_QUERY_CLASSIFIER "QueryClassifier" /**< A query classifier module type */
|
||||
|
||||
|
||||
extern void *load_module(const char *module, const char *type);
|
||||
extern void unload_module(const char *module);
|
||||
extern void unload_all_modules();
|
||||
extern void printModules();
|
||||
extern void dprintAllModules(DCB *);
|
||||
extern RESULTSET *moduleGetList();
|
||||
extern void module_feedback_send(void*);
|
||||
extern void moduleShowFeedbackReport(DCB *dcb);
|
||||
|
||||
EXTERN_C_BLOCK_END
|
||||
|
||||
#endif
|
73
include/maxscale/modutil.h
Normal file
73
include/maxscale/modutil.h
Normal file
@ -0,0 +1,73 @@
|
||||
#ifndef _MODUTIL_H
|
||||
#define _MODUTIL_H
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file modutil.h A set of useful routines for module writers
|
||||
*
|
||||
* @verbatim
|
||||
* Revision History
|
||||
*
|
||||
* Date Who Description
|
||||
* 04/06/14 Mark Riddoch Initial implementation
|
||||
* 24/06/14 Mark Riddoch Add modutil_MySQL_Query to enable multipacket queries
|
||||
* 24/10/14 Massimiliano Pinto Add modutil_send_mysql_err_packet to send a mysql ERR_Packet
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
#include <maxscale/buffer.h>
|
||||
#include <maxscale/dcb.h>
|
||||
#include <string.h>
|
||||
#include <maxscale/maxscale_pcre2.h>
|
||||
|
||||
#define PTR_IS_RESULTSET(b) (b[0] == 0x01 && b[1] == 0x0 && b[2] == 0x0 && b[3] == 0x01)
|
||||
#define PTR_IS_EOF(b) (b[0] == 0x05 && b[1] == 0x0 && b[2] == 0x0 && b[4] == 0xfe)
|
||||
#define PTR_IS_OK(b) (b[4] == 0x00)
|
||||
#define PTR_IS_ERR(b) (b[4] == 0xff)
|
||||
#define PTR_IS_LOCAL_INFILE(b) (b[4] == 0xfb)
|
||||
#define IS_FULL_RESPONSE(buf) (modutil_count_signal_packets(buf,0,0) == 2)
|
||||
#define PTR_EOF_MORE_RESULTS(b) ((PTR_IS_EOF(b) && ptr[7] & 0x08))
|
||||
|
||||
|
||||
extern int modutil_is_SQL(GWBUF *);
|
||||
extern int modutil_is_SQL_prepare(GWBUF *);
|
||||
extern int modutil_extract_SQL(GWBUF *, char **, int *);
|
||||
extern int modutil_MySQL_Query(GWBUF *, char **, int *, int *);
|
||||
extern char* modutil_get_SQL(GWBUF *);
|
||||
extern GWBUF* modutil_replace_SQL(GWBUF *, char *);
|
||||
extern char* modutil_get_query(GWBUF* buf);
|
||||
extern int modutil_send_mysql_err_packet(DCB *, int, int, int, const char *, const char *);
|
||||
GWBUF* modutil_get_next_MySQL_packet(GWBUF** p_readbuf);
|
||||
GWBUF* modutil_get_complete_packets(GWBUF** p_readbuf);
|
||||
int modutil_MySQL_query_len(GWBUF* buf, int* nbytes_missing);
|
||||
void modutil_reply_parse_error(DCB* backend_dcb, char* errstr, uint32_t flags);
|
||||
void modutil_reply_auth_error(DCB* backend_dcb, char* errstr, uint32_t flags);
|
||||
int modutil_count_statements(GWBUF* buffer);
|
||||
GWBUF* modutil_create_query(char* query);
|
||||
GWBUF* modutil_create_mysql_err_msg(int packet_number,
|
||||
int affected_rows,
|
||||
int merrno,
|
||||
const char *statemsg,
|
||||
const char *msg);
|
||||
int modutil_count_signal_packets(GWBUF*, int, int, int*);
|
||||
mxs_pcre2_result_t modutil_mysql_wildcard_match(const char* pattern, const char* string);
|
||||
|
||||
/** Character and token searching functions */
|
||||
char* strnchr_esc(char* ptr, char c, int len);
|
||||
char* strnchr_esc_mysql(char* ptr, char c, int len);
|
||||
bool is_mysql_statement_end(const char* start, int len);
|
||||
bool is_mysql_sp_end(const char* start, int len);
|
||||
char* modutil_get_canonical(GWBUF* querybuf);
|
||||
|
||||
#endif
|
229
include/maxscale/monitor.h
Normal file
229
include/maxscale/monitor.h
Normal file
@ -0,0 +1,229 @@
|
||||
#ifndef _MONITOR_H
|
||||
#define _MONITOR_H
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#include <mysql.h>
|
||||
#include <maxscale/server.h>
|
||||
#include <maxscale/dcb.h>
|
||||
#include <maxscale/log_manager.h>
|
||||
#include <maxscale/resultset.h>
|
||||
#include <maxscale/maxconfig.h>
|
||||
#include <maxscale/externcmd.h>
|
||||
#include <maxscale/secrets.h>
|
||||
|
||||
/**
|
||||
* @file monitor.h The interface to the monitor module
|
||||
*
|
||||
* @verbatim
|
||||
* Revision History
|
||||
*
|
||||
* Date Who Description
|
||||
* 07/07/13 Mark Riddoch Initial implementation
|
||||
* 25/07/13 Mark Riddoch Addition of diagnotics
|
||||
* 23/05/14 Mark Riddoch Addition of routine to find monitors by name
|
||||
* 23/05/14 Massimiliano Pinto Addition of defaultId and setInterval
|
||||
* 23/06/14 Massimiliano Pinto Addition of replicationHeartbeat
|
||||
* 28/08/14 Massimiliano Pinto Addition of detectStaleMaster
|
||||
* 30/10/14 Massimiliano Pinto Addition of disableMasterFailback
|
||||
* 07/11/14 Massimiliano Pinto Addition of setNetworkTimeout
|
||||
* 19/02/15 Mark Riddoch Addition of monitorGetList
|
||||
* 19/11/15 Martin Brampton Automation of event and name declaration, absorption
|
||||
* of what was formerly monitor_common.h
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
|
||||
/**
|
||||
* The "Module Object" for a monitor module.
|
||||
*
|
||||
* The monitor modules are designed to monitor the backend databases that the gateway
|
||||
* connects to and provide information regarding the status of the databases that
|
||||
* is used in the routing decisions.
|
||||
*
|
||||
* startMonitor is called to start the monitoring process, it is called on the main
|
||||
* thread of the gateway and is responsible for creating a thread for the monitor
|
||||
* itself to run on. This should use the entry points defined in the thread.h
|
||||
* header file rather than make direct calls to the operating system thrading libraries.
|
||||
* The return from startMonitor is a void * handle that will be passed to all other monitor
|
||||
* API calls.
|
||||
*
|
||||
* stopMonitor is responsible for shuting down and destroying a monitor, it is called
|
||||
* with the void * handle that was returned by startMonitor.
|
||||
*
|
||||
* registerServer is called to register a server that must be monitored with a running
|
||||
* monitor. this will be called with the handle returned from the startMonitor call and
|
||||
* the SERVER structure that the monitor must update and monitor. The SERVER structure
|
||||
* contains the information required to connect to the monitored server.
|
||||
*
|
||||
* unregisterServer is called to remove a server from the set of servers that need to be
|
||||
* monitored.
|
||||
*/
|
||||
|
||||
struct monitor;
|
||||
typedef struct monitor MONITOR;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void *(*startMonitor)(MONITOR *monitor, const CONFIG_PARAMETER *params);
|
||||
void (*stopMonitor)(MONITOR *monitor);
|
||||
void (*diagnostics)(DCB *, const MONITOR *);
|
||||
} MONITOR_OBJECT;
|
||||
|
||||
/**
|
||||
* The monitor API version number. Any change to the monitor module API
|
||||
* must change these versions usign the rules defined in modinfo.h
|
||||
*/
|
||||
#define MONITOR_VERSION {3, 0, 0}
|
||||
|
||||
/** Monitor's poll frequency */
|
||||
#define MON_BASE_INTERVAL_MS 100
|
||||
|
||||
/**
|
||||
* Monitor state bit mask values
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
MONITOR_STATE_ALLOC = 0x00,
|
||||
MONITOR_STATE_RUNNING = 0x01,
|
||||
MONITOR_STATE_STOPPING = 0x02,
|
||||
MONITOR_STATE_STOPPED = 0x04,
|
||||
MONITOR_STATE_FREED = 0x08
|
||||
} monitor_state_t;
|
||||
|
||||
/**
|
||||
* Monitor network timeout types
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
MONITOR_CONNECT_TIMEOUT = 0,
|
||||
MONITOR_READ_TIMEOUT = 1,
|
||||
MONITOR_WRITE_TIMEOUT = 2
|
||||
} monitor_timeouts_t;
|
||||
|
||||
/*
|
||||
* Results of attempt at database connection for monitoring
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
MONITOR_CONN_OK,
|
||||
MONITOR_CONN_REFUSED,
|
||||
MONITOR_CONN_TIMEOUT
|
||||
} connect_result_t;
|
||||
|
||||
#define MON_ARG_MAX 8192
|
||||
|
||||
#define DEFAULT_CONNECT_TIMEOUT 3
|
||||
#define DEFAULT_READ_TIMEOUT 1
|
||||
#define DEFAULT_WRITE_TIMEOUT 2
|
||||
|
||||
|
||||
#define MONITOR_RUNNING 1
|
||||
#define MONITOR_STOPPING 2
|
||||
#define MONITOR_STOPPED 3
|
||||
|
||||
#define MONITOR_INTERVAL 10000 // in milliseconds
|
||||
#define MONITOR_DEFAULT_ID 1UL // unsigned long value
|
||||
|
||||
/*
|
||||
* Create declarations of the enum for monitor events and also the array of
|
||||
* structs containing the matching names. The data is taken from def_monitor_event.h
|
||||
*/
|
||||
#undef ADDITEM
|
||||
#define ADDITEM( _event_type, _event_name ) _event_type
|
||||
typedef enum
|
||||
{
|
||||
#include "def_monitor_event.h"
|
||||
MAX_MONITOR_EVENT
|
||||
} monitor_event_t;
|
||||
#undef ADDITEM
|
||||
|
||||
typedef struct monitor_def_s
|
||||
{
|
||||
char name[30];
|
||||
} monitor_def_t;
|
||||
|
||||
extern const monitor_def_t monitor_event_definitions[];
|
||||
|
||||
/**
|
||||
* The linked list of servers that are being monitored by the monitor module.
|
||||
*/
|
||||
typedef struct monitor_servers
|
||||
{
|
||||
SERVER *server; /**< The server being monitored */
|
||||
MYSQL *con; /**< The MySQL connection */
|
||||
bool log_version_err;
|
||||
int mon_err_count;
|
||||
unsigned int mon_prev_status;
|
||||
unsigned int pending_status; /**< Pending Status flag bitmap */
|
||||
struct monitor_servers *next; /**< The next server in the list */
|
||||
} MONITOR_SERVERS;
|
||||
|
||||
/**
|
||||
* Representation of the running monitor.
|
||||
*/
|
||||
struct monitor
|
||||
{
|
||||
char *name; /**< The name of the monitor module */
|
||||
char *user; /*< Monitor username */
|
||||
char *password; /*< Monitor password */
|
||||
SPINLOCK lock;
|
||||
CONFIG_PARAMETER* parameters; /*< configuration parameters */
|
||||
MONITOR_SERVERS* databases; /*< List of databases the monitor monitors */
|
||||
monitor_state_t state; /**< The state of the monitor */
|
||||
int connect_timeout; /**< Connect timeout in seconds for mysql_real_connect */
|
||||
int read_timeout; /**< Timeout in seconds to read from the server.
|
||||
* There are retries and the total effective timeout
|
||||
* value is three times the option value.
|
||||
*/
|
||||
int write_timeout; /**< Timeout in seconds for each attempt to write to the server.
|
||||
* There are retries and the total effective timeout value is
|
||||
* two times the option value.
|
||||
*/
|
||||
MONITOR_OBJECT *module; /**< The "monitor object" */
|
||||
void *handle; /**< Handle returned from startMonitor */
|
||||
size_t interval; /**< The monitor interval */
|
||||
struct monitor *next; /**< Next monitor in the linked list */
|
||||
};
|
||||
|
||||
extern MONITOR *monitor_alloc(char *, char *);
|
||||
extern void monitor_free(MONITOR *);
|
||||
extern MONITOR *monitor_find(char *);
|
||||
extern void monitorAddServer(MONITOR *, SERVER *);
|
||||
extern void monitorAddUser(MONITOR *, char *, char *);
|
||||
extern void monitorAddParameters(MONITOR *monitor, CONFIG_PARAMETER *params);
|
||||
extern void monitorStop(MONITOR *);
|
||||
extern void monitorStart(MONITOR *, void*);
|
||||
extern void monitorStopAll();
|
||||
extern void monitorStartAll();
|
||||
extern void monitorShowAll(DCB *);
|
||||
extern void monitorShow(DCB *, MONITOR *);
|
||||
extern void monitorList(DCB *);
|
||||
extern void monitorSetInterval (MONITOR *, unsigned long);
|
||||
extern bool monitorSetNetworkTimeout(MONITOR *, int, int);
|
||||
extern RESULTSET *monitorGetList();
|
||||
extern bool check_monitor_permissions(MONITOR* monitor, const char* query);
|
||||
|
||||
monitor_event_t mon_name_to_event(const char* tok);
|
||||
monitor_event_t mon_get_event_type(MONITOR_SERVERS* node);
|
||||
const char* mon_get_event_name(MONITOR_SERVERS* node);
|
||||
void monitor_clear_pending_status(MONITOR_SERVERS *ptr, int bit);
|
||||
void monitor_set_pending_status(MONITOR_SERVERS *ptr, int bit);
|
||||
bool mon_status_changed(MONITOR_SERVERS* mon_srv);
|
||||
bool mon_print_fail_status(MONITOR_SERVERS* mon_srv);
|
||||
void monitor_launch_script(MONITOR* mon, MONITOR_SERVERS* ptr, char* script);
|
||||
int mon_parse_event_string(bool* events, size_t count, char* string);
|
||||
connect_result_t mon_connect_to_db(MONITOR* mon, MONITOR_SERVERS *database);
|
||||
void mon_log_connect_error(MONITOR_SERVERS* database, connect_result_t rval);
|
||||
void mon_log_state_change(MONITOR_SERVERS *ptr);
|
||||
|
||||
#endif
|
94
include/maxscale/mysql_binlog.h
Normal file
94
include/maxscale/mysql_binlog.h
Normal file
@ -0,0 +1,94 @@
|
||||
#ifndef MYSQL_BINLOG_H
|
||||
#define MYSQL_BINLOG_H
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file mysql_binlog.h - Extracting information from binary logs
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <time.h>
|
||||
|
||||
/** Maximum GTID string length */
|
||||
#define GTID_MAX_LEN 64
|
||||
|
||||
/** Table map column types */
|
||||
#define TABLE_COL_TYPE_DECIMAL 0x00
|
||||
#define TABLE_COL_TYPE_TINY 0x01
|
||||
#define TABLE_COL_TYPE_SHORT 0x02
|
||||
#define TABLE_COL_TYPE_LONG 0x03
|
||||
#define TABLE_COL_TYPE_FLOAT 0x04
|
||||
#define TABLE_COL_TYPE_DOUBLE 0x05
|
||||
#define TABLE_COL_TYPE_NULL 0x06
|
||||
#define TABLE_COL_TYPE_TIMESTAMP 0x07
|
||||
#define TABLE_COL_TYPE_LONGLONG 0x08
|
||||
#define TABLE_COL_TYPE_INT24 0x09
|
||||
#define TABLE_COL_TYPE_DATE 0x0a
|
||||
#define TABLE_COL_TYPE_TIME 0x0b
|
||||
#define TABLE_COL_TYPE_DATETIME 0x0c
|
||||
#define TABLE_COL_TYPE_YEAR 0x0d
|
||||
#define TABLE_COL_TYPE_NEWDATE 0x0e
|
||||
#define TABLE_COL_TYPE_VARCHAR 0x0f
|
||||
#define TABLE_COL_TYPE_BIT 0x10
|
||||
#define TABLE_COL_TYPE_TIMESTAMP2 0x11
|
||||
#define TABLE_COL_TYPE_DATETIME2 0x12
|
||||
#define TABLE_COL_TYPE_TIME2 0x13
|
||||
#define TABLE_COL_TYPE_NEWDECIMAL 0xf6
|
||||
#define TABLE_COL_TYPE_ENUM 0xf7
|
||||
#define TABLE_COL_TYPE_SET 0xf8
|
||||
#define TABLE_COL_TYPE_TINY_BLOB 0xf9
|
||||
#define TABLE_COL_TYPE_MEDIUM_BLOB 0xfa
|
||||
#define TABLE_COL_TYPE_LONG_BLOB 0xfb
|
||||
#define TABLE_COL_TYPE_BLOB 0xfc
|
||||
#define TABLE_COL_TYPE_VAR_STRING 0xfd
|
||||
#define TABLE_COL_TYPE_STRING 0xfe
|
||||
#define TABLE_COL_TYPE_GEOMETRY 0xff
|
||||
|
||||
/**
|
||||
* RBR row event flags
|
||||
*/
|
||||
#define ROW_EVENT_END_STATEMENT 0x0001
|
||||
#define ROW_EVENT_NO_FKCHECK 0x0002
|
||||
#define ROW_EVENT_NO_UKCHECK 0x0004
|
||||
#define ROW_EVENT_HAS_COLUMNS 0x0008
|
||||
|
||||
/** The table ID used for end of statement row events */
|
||||
#define TABLE_DUMMY_ID 0x00ffffff
|
||||
|
||||
|
||||
const char* column_type_to_string(uint8_t type);
|
||||
|
||||
/** Column type checking functions */
|
||||
bool column_is_variable_string(uint8_t type);
|
||||
bool column_is_fixed_string(uint8_t type);
|
||||
bool column_is_blob(uint8_t type);
|
||||
bool column_is_temporal(uint8_t type);
|
||||
bool column_is_bit(uint8_t type);
|
||||
bool column_is_decimal(uint8_t type);
|
||||
|
||||
/** Various types are stored as fixed string types and the real type is stored
|
||||
* in the table metadata */
|
||||
bool fixed_string_is_enum(uint8_t type);
|
||||
|
||||
/** Value unpacking */
|
||||
uint64_t unpack_temporal_value(uint8_t type, uint8_t *ptr, uint8_t* metadata, struct tm *tm);
|
||||
uint64_t unpack_enum(uint8_t *ptr, uint8_t *metadata, uint8_t *dest);
|
||||
uint64_t unpack_numeric_field(uint8_t *ptr, uint8_t type, uint8_t* metadata, uint8_t* val);
|
||||
uint64_t unpack_bit(uint8_t *ptr, uint8_t *null_mask, uint32_t col_count,
|
||||
uint32_t curr_col_index, uint8_t *metadata, uint64_t *dest);
|
||||
|
||||
void format_temporal_value(char *str, size_t size, uint8_t type, struct tm *tm);
|
||||
|
||||
#endif /* MYSQL_BINLOG_H */
|
33
include/maxscale/mysql_utils.h
Normal file
33
include/maxscale/mysql_utils.h
Normal file
@ -0,0 +1,33 @@
|
||||
#ifndef _MYSQL_UTILS_H
|
||||
#define _MYSQL_UTILS_H
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <mysql.h>
|
||||
#include <maxscale/server.h>
|
||||
|
||||
/** Length-encoded integers */
|
||||
size_t leint_bytes(uint8_t* ptr);
|
||||
uint64_t leint_value(uint8_t* c);
|
||||
uint64_t leint_consume(uint8_t ** c);
|
||||
|
||||
/** Length-encoded strings */
|
||||
char* lestr_consume_dup(uint8_t** c);
|
||||
char* lestr_consume(uint8_t** c, size_t *size);
|
||||
|
||||
|
||||
MYSQL *mxs_mysql_real_connect(MYSQL *mysql, SERVER *server, const char *user, const char *passwd);
|
||||
|
||||
#endif
|
60
include/maxscale/notification.h
Normal file
60
include/maxscale/notification.h
Normal file
@ -0,0 +1,60 @@
|
||||
#ifndef _NOTIFICATION_SERVICE_H
|
||||
#define _NOTIFICATION_SERVICE_H
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file notification.h
|
||||
*
|
||||
* The configuration stuct for notification/feedback service
|
||||
*
|
||||
* @verbatim
|
||||
* Revision History
|
||||
*
|
||||
* Date Who Description
|
||||
* 02/03/15 Massimiliano Pinto Initial implementation
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
|
||||
#define _NOTIFICATION_CONNECT_TIMEOUT 30
|
||||
#define _NOTIFICATION_OPERATION_TIMEOUT 30
|
||||
#define _NOTIFICATION_SEND_PENDING 0
|
||||
#define _NOTIFICATION_SEND_OK 1
|
||||
#define _NOTIFICATION_SEND_ERROR 2
|
||||
#define _NOTIFICATION_REPORT_ROW_LEN 255
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* The configuration and usage information data for feeback service
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int feedback_enable; /**< Enable/Disable Notification feedback */
|
||||
char *feedback_url; /**< URL to which the data is sent */
|
||||
char *feedback_user_info; /**< User info included in the feedback data sent */
|
||||
int feedback_timeout; /**< An attempt to write/read the data times out and fails after this many seconds */
|
||||
int feedback_connect_timeout; /**< An attempt to send the data times out and fails after this many seconds */
|
||||
int feedback_last_action; /**< Holds the feedback last send action status */
|
||||
int feedback_frequency; /*< Frequency of the housekeeper task */
|
||||
char *release_info; /**< Operating system Release name */
|
||||
char *sysname; /**< Operating system name */
|
||||
uint8_t *mac_sha1; /**< First available MAC address*/
|
||||
} FEEDBACK_CONF;
|
||||
|
||||
extern char *gw_bin2hex(char *out, const uint8_t *in, unsigned int len);
|
||||
extern void gw_sha1_str(const uint8_t *in, int in_len, uint8_t *out);
|
||||
extern FEEDBACK_CONF * config_get_feedback_data();
|
||||
#endif
|
51
include/maxscale/platform.h
Normal file
51
include/maxscale/platform.h
Normal file
@ -0,0 +1,51 @@
|
||||
#ifndef _PLATFORM_H
|
||||
#define _PLATFORM_H
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
|
||||
#if !defined(__cplusplus)
|
||||
|
||||
#if __STDC_VERSION__ >= 201112
|
||||
|
||||
#if defined(__STDC_NO_THREADS__)
|
||||
#define thread_local _Thread_local
|
||||
#else
|
||||
#include <threads.h>
|
||||
#endif
|
||||
|
||||
#else // __STDC_VERSION >= 201112
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#define thread_local __thread
|
||||
#else
|
||||
#error Do not know how to define thread_local on this compiler/OS platform.
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#else // __cplusplus
|
||||
|
||||
// C++11 supports thread_local natively.
|
||||
#if __cplusplus < 201103
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#define thread_local __thread
|
||||
#else
|
||||
#error Do not know how to define thread_local on this compiler/OS platform.
|
||||
#endif
|
||||
|
||||
#endif // __cplusplus < 201103
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // _PLATFORM_H
|
70
include/maxscale/poll.h
Normal file
70
include/maxscale/poll.h
Normal file
@ -0,0 +1,70 @@
|
||||
#ifndef _POLL_H
|
||||
#define _POLL_H
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#include <maxscale/dcb.h>
|
||||
#include <maxscale/gwbitmask.h>
|
||||
#include <maxscale/resultset.h>
|
||||
#include <sys/epoll.h>
|
||||
|
||||
/**
|
||||
* @file poll.h The poll related functionality
|
||||
*
|
||||
* @verbatim
|
||||
* Revision History
|
||||
*
|
||||
* Date Who Description
|
||||
* 19/06/13 Mark Riddoch Initial implementation
|
||||
* 17/10/15 Martin Brampton Declare fake event functions
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
#define MAX_EVENTS 1000
|
||||
|
||||
/**
|
||||
* A statistic identifier that can be returned by poll_get_stat
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
POLL_STAT_READ,
|
||||
POLL_STAT_WRITE,
|
||||
POLL_STAT_ERROR,
|
||||
POLL_STAT_HANGUP,
|
||||
POLL_STAT_ACCEPT,
|
||||
POLL_STAT_EVQ_LEN,
|
||||
POLL_STAT_EVQ_PENDING,
|
||||
POLL_STAT_EVQ_MAX,
|
||||
POLL_STAT_MAX_QTIME,
|
||||
POLL_STAT_MAX_EXECTIME
|
||||
} POLL_STAT;
|
||||
|
||||
extern void poll_init();
|
||||
extern int poll_add_dcb(DCB *);
|
||||
extern int poll_remove_dcb(DCB *);
|
||||
extern void poll_waitevents(void *);
|
||||
extern void poll_shutdown();
|
||||
extern GWBITMASK *poll_bitmask();
|
||||
extern void poll_set_maxwait(unsigned int);
|
||||
extern void poll_set_nonblocking_polls(unsigned int);
|
||||
extern void dprintPollStats(DCB *);
|
||||
extern void dShowThreads(DCB *dcb);
|
||||
extern void poll_add_epollin_event_to_dcb(DCB* dcb, GWBUF* buf);
|
||||
extern void dShowEventQ(DCB *dcb);
|
||||
extern void dShowEventStats(DCB *dcb);
|
||||
extern int poll_get_stat(POLL_STAT stat);
|
||||
extern RESULTSET *eventTimesGetList();
|
||||
extern void poll_fake_event(DCB *dcb, enum EPOLL_EVENTS ev);
|
||||
extern void poll_fake_hangup_event(DCB *dcb);
|
||||
extern void poll_fake_write_event(DCB *dcb);
|
||||
extern void poll_fake_read_event(DCB *dcb);
|
||||
#endif
|
135
include/maxscale/query_classifier.h
Normal file
135
include/maxscale/query_classifier.h
Normal file
@ -0,0 +1,135 @@
|
||||
#ifndef QUERY_CLASSIFIER_HG
|
||||
#define QUERY_CLASSIFIER_HG
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
|
||||
#include <maxscale/skygw_utils.h>
|
||||
#include <maxscale/buffer.h>
|
||||
|
||||
EXTERN_C_BLOCK_BEGIN
|
||||
|
||||
typedef enum
|
||||
{
|
||||
QUERY_TYPE_UNKNOWN = 0x000000, /*< Initial value, can't be tested bitwisely */
|
||||
QUERY_TYPE_LOCAL_READ = 0x000001, /*< Read non-database data, execute in MaxScale:any */
|
||||
QUERY_TYPE_READ = 0x000002, /*< Read database data:any */
|
||||
QUERY_TYPE_WRITE = 0x000004, /*< Master data will be modified:master */
|
||||
QUERY_TYPE_MASTER_READ = 0x000008, /*< Read from the master:master */
|
||||
QUERY_TYPE_SESSION_WRITE = 0x000010, /*< Session data will be modified:master or all */
|
||||
/** Not implemented yet */
|
||||
//QUERY_TYPE_USERVAR_WRITE = 0x000020, /*< Write a user variable:master or all */
|
||||
QUERY_TYPE_USERVAR_READ = 0x000040, /*< Read a user variable:master or any */
|
||||
QUERY_TYPE_SYSVAR_READ = 0x000080, /*< Read a system variable:master or any */
|
||||
/** Not implemented yet */
|
||||
//QUERY_TYPE_SYSVAR_WRITE = 0x000100, /*< Write a system variable:master or all */
|
||||
QUERY_TYPE_GSYSVAR_READ = 0x000200, /*< Read global system variable:master or any */
|
||||
QUERY_TYPE_GSYSVAR_WRITE = 0x000400, /*< Write global system variable:master or all */
|
||||
QUERY_TYPE_BEGIN_TRX = 0x000800, /*< BEGIN or START TRANSACTION */
|
||||
QUERY_TYPE_ENABLE_AUTOCOMMIT = 0x001000, /*< SET autocommit=1 */
|
||||
QUERY_TYPE_DISABLE_AUTOCOMMIT = 0x002000, /*< SET autocommit=0 */
|
||||
QUERY_TYPE_ROLLBACK = 0x004000, /*< ROLLBACK */
|
||||
QUERY_TYPE_COMMIT = 0x008000, /*< COMMIT */
|
||||
QUERY_TYPE_PREPARE_NAMED_STMT = 0x010000, /*< Prepared stmt with name from user:all */
|
||||
QUERY_TYPE_PREPARE_STMT = 0x020000, /*< Prepared stmt with id provided by server:all */
|
||||
QUERY_TYPE_EXEC_STMT = 0x040000, /*< Execute prepared statement:master or any */
|
||||
QUERY_TYPE_CREATE_TMP_TABLE = 0x080000, /*< Create temporary table:master (could be all) */
|
||||
QUERY_TYPE_READ_TMP_TABLE = 0x100000, /*< Read temporary table:master (could be any) */
|
||||
QUERY_TYPE_SHOW_DATABASES = 0x200000, /*< Show list of databases */
|
||||
QUERY_TYPE_SHOW_TABLES = 0x400000 /*< Show list of tables */
|
||||
} qc_query_type_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
QUERY_OP_UNDEFINED = 0,
|
||||
QUERY_OP_SELECT = (1 << 0),
|
||||
QUERY_OP_UPDATE = (1 << 1),
|
||||
QUERY_OP_INSERT = (1 << 2),
|
||||
QUERY_OP_DELETE = (1 << 3),
|
||||
QUERY_OP_TRUNCATE = (1 << 4),
|
||||
QUERY_OP_ALTER = (1 << 5),
|
||||
QUERY_OP_CREATE = (1 << 6),
|
||||
QUERY_OP_DROP = (1 << 7),
|
||||
QUERY_OP_CHANGE_DB = (1 << 8),
|
||||
QUERY_OP_LOAD = (1 << 9),
|
||||
QUERY_OP_GRANT = (1 << 10),
|
||||
QUERY_OP_REVOKE = (1 << 11)
|
||||
} qc_query_op_t;
|
||||
|
||||
typedef enum qc_parse_result
|
||||
{
|
||||
QC_QUERY_INVALID = 0, /*< The query was not recognized or could not be parsed. */
|
||||
QC_QUERY_TOKENIZED = 1, /*< The query was classified based on tokens; incompletely classified. */
|
||||
QC_QUERY_PARTIALLY_PARSED = 2, /*< The query was only partially parsed; incompletely classified. */
|
||||
QC_QUERY_PARSED = 3 /*< The query was fully parsed; completely classified. */
|
||||
} qc_parse_result_t;
|
||||
|
||||
#define QUERY_IS_TYPE(mask,type) ((mask & type) == type)
|
||||
|
||||
bool qc_init(const char* plugin_name, const char* plugin_args);
|
||||
void qc_end(void);
|
||||
|
||||
typedef struct query_classifier QUERY_CLASSIFIER;
|
||||
|
||||
QUERY_CLASSIFIER* qc_load(const char* plugin_name);
|
||||
void qc_unload(QUERY_CLASSIFIER* classifier);
|
||||
|
||||
bool qc_thread_init(void);
|
||||
void qc_thread_end(void);
|
||||
|
||||
qc_parse_result_t qc_parse(GWBUF* querybuf);
|
||||
|
||||
uint32_t qc_get_type(GWBUF* querybuf);
|
||||
qc_query_op_t qc_get_operation(GWBUF* querybuf);
|
||||
|
||||
char* qc_get_created_table_name(GWBUF* querybuf);
|
||||
bool qc_is_drop_table_query(GWBUF* querybuf);
|
||||
bool qc_is_real_query(GWBUF* querybuf);
|
||||
char** qc_get_table_names(GWBUF* querybuf, int* tblsize, bool fullnames);
|
||||
char* qc_get_canonical(GWBUF* querybuf);
|
||||
bool qc_query_has_clause(GWBUF* buf);
|
||||
char* qc_get_qtype_str(qc_query_type_t qtype);
|
||||
char* qc_get_affected_fields(GWBUF* buf);
|
||||
char** qc_get_database_names(GWBUF* querybuf, int* size);
|
||||
|
||||
const char* qc_op_to_string(qc_query_op_t op);
|
||||
const char* qc_type_to_string(qc_query_type_t type);
|
||||
char* qc_types_to_string(uint32_t types);
|
||||
|
||||
struct query_classifier
|
||||
{
|
||||
bool (*qc_init)(const char* args);
|
||||
void (*qc_end)(void);
|
||||
|
||||
bool (*qc_thread_init)(void);
|
||||
void (*qc_thread_end)(void);
|
||||
|
||||
qc_parse_result_t (*qc_parse)(GWBUF* querybuf);
|
||||
|
||||
uint32_t (*qc_get_type)(GWBUF* querybuf);
|
||||
qc_query_op_t (*qc_get_operation)(GWBUF* querybuf);
|
||||
|
||||
char* (*qc_get_created_table_name)(GWBUF* querybuf);
|
||||
bool (*qc_is_drop_table_query)(GWBUF* querybuf);
|
||||
bool (*qc_is_real_query)(GWBUF* querybuf);
|
||||
char** (*qc_get_table_names)(GWBUF* querybuf, int* tblsize, bool fullnames);
|
||||
char* (*qc_get_canonical)(GWBUF* querybuf);
|
||||
bool (*qc_query_has_clause)(GWBUF* buf);
|
||||
char* (*qc_get_affected_fields)(GWBUF* buf);
|
||||
char** (*qc_get_database_names)(GWBUF* querybuf, int* size);
|
||||
};
|
||||
|
||||
#define QUERY_CLASSIFIER_VERSION {1, 0, 0}
|
||||
|
||||
EXTERN_C_BLOCK_END
|
||||
|
||||
#endif
|
70
include/maxscale/queuemanager.h
Normal file
70
include/maxscale/queuemanager.h
Normal file
@ -0,0 +1,70 @@
|
||||
#ifndef _QUEUEMANAGER_H
|
||||
#define _QUEUEMANAGER_H
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file queuemanager.h The Queue Manager header file
|
||||
*
|
||||
*
|
||||
* @verbatim
|
||||
* Revision History
|
||||
*
|
||||
* Date Who Description
|
||||
* 27/04/2016 Martin Brampton Initial implementation
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <maxscale/spinlock.h>
|
||||
|
||||
#define CONNECTION_QUEUE_LIMIT 1000
|
||||
|
||||
typedef struct queue_entry
|
||||
{
|
||||
void *queued_object;
|
||||
long heartbeat;
|
||||
#if defined(SS_DEBUG)
|
||||
long sequence_check;
|
||||
#endif /* SS_DEBUG */
|
||||
} QUEUE_ENTRY;
|
||||
|
||||
typedef struct queue_config
|
||||
{
|
||||
int queue_limit;
|
||||
int start;
|
||||
int end;
|
||||
int timeout;
|
||||
bool has_entries;
|
||||
SPINLOCK queue_lock;
|
||||
QUEUE_ENTRY *queue_array;
|
||||
#if defined(SS_DEBUG)
|
||||
long sequence_number;
|
||||
#endif /* SS_DEBUG */
|
||||
} QUEUE_CONFIG;
|
||||
|
||||
QUEUE_CONFIG *mxs_queue_alloc(int limit, int timeout);
|
||||
void mxs_queue_free(QUEUE_CONFIG *queue_config);
|
||||
bool mxs_enqueue(QUEUE_CONFIG *queue_config, void *new_entry);
|
||||
bool mxs_dequeue(QUEUE_CONFIG *queue_config, QUEUE_ENTRY *result);
|
||||
bool mxs_dequeue_if_expired(QUEUE_CONFIG *queue_config, QUEUE_ENTRY *result);
|
||||
|
||||
static inline int
|
||||
mxs_queue_count(QUEUE_CONFIG *queue_config)
|
||||
{
|
||||
int count = queue_config->end - queue_config->start;
|
||||
return count < 0 ? (count + queue_config->queue_limit + 1): count;
|
||||
}
|
||||
|
||||
#endif /* QUEUEMANAGER_H */
|
33
include/maxscale/random_jkiss.h
Normal file
33
include/maxscale/random_jkiss.h
Normal file
@ -0,0 +1,33 @@
|
||||
#ifndef RANDOM_JKISS_H
|
||||
#define RANDOM_JKISS_H
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* File: random_jkiss.h
|
||||
* Author: mbrampton
|
||||
*
|
||||
* Created on 26 August 2015, 15:34
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern unsigned int random_jkiss(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* RANDOM_H */
|
56
include/maxscale/rdtsc.h
Normal file
56
include/maxscale/rdtsc.h
Normal file
@ -0,0 +1,56 @@
|
||||
#ifndef _RDTSC_H
|
||||
#define _RDTSC_H
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file rdtsc.h Access the process time-stamp counter
|
||||
*
|
||||
* This is an Intel only facilty that is used to access an accurate time
|
||||
* value, the granularity of which is related to the processor clock speed
|
||||
* and the overhead for access is much lower than using any system call
|
||||
* mechanism.
|
||||
*
|
||||
*
|
||||
* @verbatim
|
||||
* Revision History
|
||||
*
|
||||
* Date Who Description
|
||||
* 19/09/2014 Mark Riddoch Initial implementation
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
|
||||
typedef unsigned long long CYCLES;
|
||||
|
||||
/**
|
||||
* Get the current time-stamp counter value from the processor. This is the
|
||||
* count of CPU cyceles as a 64 bit value.
|
||||
*
|
||||
* The value returned is related to the clock speed, to obtian a value in
|
||||
* seconds divide the returned value by the clock frequency for the processor.
|
||||
*
|
||||
* Note, on multi-processsor systems care much be taken to avoid the thread
|
||||
* moving to a different processor when taken succsive value of RDTSC to
|
||||
* obtian accurate timing. This may be done by setting pocessor affinity for
|
||||
* the thread. See sched_setaffinity/sched_getaffinity.
|
||||
*
|
||||
* @return CPU cycle count
|
||||
*/
|
||||
static __inline__ CYCLES rdtsc(void)
|
||||
{
|
||||
unsigned long long int x;
|
||||
__asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
|
||||
return x;
|
||||
}
|
||||
#endif
|
88
include/maxscale/resultset.h
Normal file
88
include/maxscale/resultset.h
Normal file
@ -0,0 +1,88 @@
|
||||
#ifndef _RESULTSET_H
|
||||
#define _RESULTSET_H
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file resultset.h The MaxScale generic result set mechanism
|
||||
*
|
||||
* @verbatim
|
||||
* Revision History
|
||||
*
|
||||
* Date Who Description
|
||||
* 17/02/15 Mark Riddoch Initial implementation
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
#include <maxscale/dcb.h>
|
||||
|
||||
|
||||
/**
|
||||
* Column types
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
COL_TYPE_VARCHAR = 0x0f,
|
||||
COL_TYPE_VARSTRING = 0xfd
|
||||
} RESULT_COL_TYPE;
|
||||
|
||||
/**
|
||||
* The result set column definition. Each result set has an order linked
|
||||
* list of column definitions.
|
||||
*/
|
||||
typedef struct resultcolumn
|
||||
{
|
||||
char *name; /*< Column name */
|
||||
int len; /*< Column length */
|
||||
RESULT_COL_TYPE type; /*< Column type */
|
||||
struct resultcolumn *next; /*< next column */
|
||||
} RESULT_COLUMN;
|
||||
|
||||
/**
|
||||
* A representation of a row within a result set.
|
||||
*/
|
||||
typedef struct resultrow
|
||||
{
|
||||
int n_cols; /*< No. of columns in row */
|
||||
char **cols; /*< The columns themselves */
|
||||
} RESULT_ROW;
|
||||
|
||||
struct resultset;
|
||||
|
||||
/**
|
||||
* Type of callback function used to supply each row
|
||||
*/
|
||||
typedef RESULT_ROW * (*RESULT_ROW_CB)(struct resultset *, void *);
|
||||
|
||||
/**
|
||||
* The representation of the result set itself.
|
||||
*/
|
||||
typedef struct resultset
|
||||
{
|
||||
int n_cols; /*< No. of columns */
|
||||
RESULT_COLUMN *column; /*< Linked list of column definitions */
|
||||
RESULT_ROW_CB fetchrow; /*< Fetch a row for the result set */
|
||||
void *userdata; /*< User data for the fetch row call */
|
||||
} RESULTSET;
|
||||
|
||||
extern RESULTSET *resultset_create(RESULT_ROW_CB, void *);
|
||||
extern void resultset_free(RESULTSET *);
|
||||
extern int resultset_add_column(RESULTSET *, const char *, int, RESULT_COL_TYPE);
|
||||
extern void resultset_column_free(RESULT_COLUMN *);
|
||||
extern RESULT_ROW *resultset_make_row(RESULTSET *);
|
||||
extern void resultset_free_row(RESULT_ROW *);
|
||||
extern int resultset_row_set(RESULT_ROW *, int, const char *);
|
||||
extern void resultset_stream_mysql(RESULTSET *, DCB *);
|
||||
extern void resultset_stream_json(RESULTSET *, DCB *);
|
||||
|
||||
#endif
|
105
include/maxscale/router.h
Normal file
105
include/maxscale/router.h
Normal file
@ -0,0 +1,105 @@
|
||||
#ifndef _ROUTER_H
|
||||
#define _ROUTER_H
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file router.h - The query router interface mechanisms
|
||||
*
|
||||
* Revision History
|
||||
*
|
||||
* Date Who Description
|
||||
* 14/06/2013 Mark Riddoch Initial implementation
|
||||
* 26/06/2013 Mark Riddoch Addition of router options and the diagnostic entry point
|
||||
* 15/07/2013 Massimiliano Pinto Added clientReply entry point
|
||||
* 16/07/2013 Massimiliano Pinto Added router commands values
|
||||
* 22/10/2013 Massimiliano Pinto Added router errorReply entry point
|
||||
* 27/10/2015 Martin Brampton Add RCAP_TYPE_NO_RSESSION
|
||||
*
|
||||
*/
|
||||
#include <maxscale/service.h>
|
||||
#include <maxscale/session.h>
|
||||
#include <maxscale/buffer.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* The ROUTER handle points to module specific data, so the best we can do
|
||||
* is to make it a void * externally.
|
||||
*/
|
||||
typedef void *ROUTER;
|
||||
|
||||
typedef enum error_action
|
||||
{
|
||||
ERRACT_NEW_CONNECTION = 0x001,
|
||||
ERRACT_REPLY_CLIENT = 0x002
|
||||
} error_action_t;
|
||||
|
||||
/**
|
||||
* @verbatim
|
||||
* The "module object" structure for a query router module
|
||||
*
|
||||
* The entry points are:
|
||||
* createInstance Called by the service to create a new instance of the query router
|
||||
* newSession Called to create a new user session within the query router
|
||||
* closeSession Called when a session is closed
|
||||
* routeQuery Called on each query that requires routing
|
||||
* diagnostics Called to force the router to print diagnostic output
|
||||
* clientReply Called to reply to client the data from one or all backends
|
||||
* errorReply Called to reply to client errors with optional closeSession or make a request for
|
||||
* a new backend connection
|
||||
*
|
||||
* @endverbatim
|
||||
*
|
||||
* @see load_module
|
||||
*/
|
||||
typedef struct router_object
|
||||
{
|
||||
ROUTER *(*createInstance)(SERVICE *service, char **options);
|
||||
void *(*newSession)(ROUTER *instance, SESSION *session);
|
||||
void (*closeSession)(ROUTER *instance, void *router_session);
|
||||
void (*freeSession)(ROUTER *instance, void *router_session);
|
||||
int (*routeQuery)(ROUTER *instance, void *router_session, GWBUF *queue);
|
||||
void (*diagnostics)(ROUTER *instance, DCB *dcb);
|
||||
void (*clientReply)(ROUTER* instance, void* router_session, GWBUF* queue, DCB *backend_dcb);
|
||||
void (*handleError)(ROUTER* instance,
|
||||
void* router_session,
|
||||
GWBUF* errmsgbuf,
|
||||
DCB* backend_dcb,
|
||||
error_action_t action,
|
||||
bool* succp);
|
||||
int (*getCapabilities)();
|
||||
} ROUTER_OBJECT;
|
||||
|
||||
/**
|
||||
* The router module API version. Any change that changes the router API
|
||||
* must update these versions numbers in accordance with the rules in
|
||||
* modinfo.h.
|
||||
*/
|
||||
#define ROUTER_VERSION { 1, 0, 0 }
|
||||
|
||||
/**
|
||||
* Router capability type. Indicates what kind of input router accepts.
|
||||
*/
|
||||
typedef enum router_capability_t
|
||||
{
|
||||
RCAP_TYPE_UNDEFINED = 0x00,
|
||||
RCAP_TYPE_STMT_INPUT = 0x01, /**< Statement per buffer */
|
||||
RCAP_TYPE_PACKET_INPUT = 0x02, /**< Data as it was read from DCB */
|
||||
RCAP_TYPE_NO_RSESSION = 0x04, /**< Router does not use router sessions */
|
||||
RCAP_TYPE_NO_USERS_INIT = 0x08 /**< Prevent the loading of authenticator
|
||||
users when the service is started */
|
||||
} router_capability_t;
|
||||
|
||||
|
||||
|
||||
#endif
|
59
include/maxscale/secrets.h
Normal file
59
include/maxscale/secrets.h
Normal file
@ -0,0 +1,59 @@
|
||||
#ifndef _SECRETS_H
|
||||
#define _SECRETS_H
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file secrets.h
|
||||
*
|
||||
* @verbatim
|
||||
* Revision History
|
||||
*
|
||||
* Date Who Description
|
||||
* 23/06/2013 Massimiliano Pinto Initial implementation
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <openssl/aes.h>
|
||||
|
||||
#define MAXSCALE_KEYLEN 32
|
||||
#define MAXSCALE_IV_LEN 16
|
||||
|
||||
/**
|
||||
* The key structure held in the secrets file
|
||||
*/
|
||||
typedef struct maxkeys
|
||||
{
|
||||
unsigned char enckey[MAXSCALE_KEYLEN];
|
||||
unsigned char initvector[MAXSCALE_IV_LEN];
|
||||
} MAXKEYS;
|
||||
|
||||
enum
|
||||
{
|
||||
MXS_PASSWORD_MAXLEN = 79
|
||||
};
|
||||
|
||||
extern int secrets_writeKeys(const char *directory);
|
||||
extern char *decryptPassword(const char *);
|
||||
extern char *encryptPassword(const char*, const char *);
|
||||
|
||||
#endif
|
225
include/maxscale/server.h
Normal file
225
include/maxscale/server.h
Normal file
@ -0,0 +1,225 @@
|
||||
#ifndef _SERVER_H
|
||||
#define _SERVER_H
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#include <maxscale/dcb.h>
|
||||
#include <maxscale/resultset.h>
|
||||
|
||||
/**
|
||||
* @file service.h
|
||||
*
|
||||
* The server level definitions within the gateway
|
||||
*
|
||||
* @verbatim
|
||||
* Revision History
|
||||
*
|
||||
* Date Who Description
|
||||
* 14/06/13 Mark Riddoch Initial implementation
|
||||
* 21/06/13 Mark Riddoch Addition of server status flags
|
||||
* 22/07/13 Mark Riddoch Addition of JOINED status for Galera
|
||||
* 18/05/14 Mark Riddoch Addition of unique_name field
|
||||
* 20/05/14 Massimiliano Pinto Addition of server_string field
|
||||
* 20/05/14 Massimiliano Pinto Addition of node_id field
|
||||
* 23/05/14 Massimiliano Pinto Addition of rlag and node_ts fields
|
||||
* 03/06/14 Mark Riddoch Addition of maintainance mode
|
||||
* 20/06/14 Massimiliano Pinto Addition of master_id, depth, slaves fields
|
||||
* 26/06/14 Mark Riddoch Adidtion of server parameters
|
||||
* 30/07/14 Massimiliano Pinto Addition of NDB status for MySQL Cluster
|
||||
* 30/08/14 Massimiliano Pinto Addition of SERVER_STALE_STATUS
|
||||
* 27/10/14 Massimiliano Pinto Addition of SERVER_MASTER_STICKINESS
|
||||
* 19/02/15 Mark Riddoch Addition of serverGetList
|
||||
* 01/06/15 Massimiliano Pinto Addition of server_update_address/port
|
||||
* 19/06/15 Martin Brampton Extra fields for persistent connections, CHK_SERVER
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
|
||||
#define MAX_SERVER_NAME_LEN 1024
|
||||
#define MAX_NUM_SLAVES 128 /**< Maximum number of slaves under a single server*/
|
||||
|
||||
/**
|
||||
* The server parameters used for weighting routing decissions
|
||||
*
|
||||
*/
|
||||
typedef struct server_params
|
||||
{
|
||||
char *name; /**< Parameter name */
|
||||
char *value; /**< Parameter value */
|
||||
struct server_params *next; /**< Next Paramter in the linked list */
|
||||
} SERVER_PARAM;
|
||||
|
||||
/**
|
||||
* The server statistics structure
|
||||
*
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int n_connections; /**< Number of connections */
|
||||
int n_current; /**< Current connections */
|
||||
int n_current_ops; /**< Current active operations */
|
||||
int n_persistent; /**< Current persistent pool */
|
||||
} SERVER_STATS;
|
||||
|
||||
/**
|
||||
* The SERVER structure defines a backend server. Each server has a name
|
||||
* or IP address for the server, a port that the server listens on and
|
||||
* the name of a protocol module that is loaded to implement the protocol
|
||||
* between the gateway and the server.
|
||||
*/
|
||||
typedef struct server
|
||||
{
|
||||
#if defined(SS_DEBUG)
|
||||
skygw_chk_t server_chk_top;
|
||||
#endif
|
||||
SPINLOCK lock; /**< Common access lock */
|
||||
char *unique_name; /**< Unique name for the server */
|
||||
char *name; /**< Server name/IP address*/
|
||||
unsigned short port; /**< Port to listen on */
|
||||
char *protocol; /**< Protocol module to use */
|
||||
char *authenticator; /**< Authenticator module name */
|
||||
void *auth_instance; /**< Authenticator instance */
|
||||
SSL_LISTENER *server_ssl; /**< SSL data structure for server, if any */
|
||||
unsigned int status; /**< Status flag bitmap for the server */
|
||||
char *monuser; /**< User name to use to monitor the db */
|
||||
char *monpw; /**< Password to use to monitor the db */
|
||||
SERVER_STATS stats; /**< The server statistics */
|
||||
struct server *next; /**< Next server */
|
||||
struct server *nextdb; /**< Next server in list attached to a service */
|
||||
char *server_string; /**< Server version string, i.e. MySQL server version */
|
||||
long node_id; /**< Node id, server_id for M/S or local_index for Galera */
|
||||
int rlag; /**< Replication Lag for Master / Slave replication */
|
||||
unsigned long node_ts; /**< Last timestamp set from M/S monitor module */
|
||||
SERVER_PARAM *parameters; /**< Parameters of a server that may be used to weight routing decisions */
|
||||
long master_id; /**< Master server id of this node */
|
||||
int depth; /**< Replication level in the tree */
|
||||
long slaves[MAX_NUM_SLAVES]; /**< Slaves of this node */
|
||||
bool master_err_is_logged; /*< If node failed, this indicates whether it is logged */
|
||||
DCB *persistent; /**< List of unused persistent connections to the server */
|
||||
SPINLOCK persistlock; /**< Lock for adjusting the persistent connections list */
|
||||
long persistpoolmax; /**< Maximum size of persistent connections pool */
|
||||
long persistmaxtime; /**< Maximum number of seconds connection can live */
|
||||
int persistmax; /**< Maximum pool size actually achieved since startup */
|
||||
#if defined(SS_DEBUG)
|
||||
skygw_chk_t server_chk_tail;
|
||||
#endif
|
||||
} SERVER;
|
||||
|
||||
/**
|
||||
* Status bits in the server->status member.
|
||||
*
|
||||
* These are a bitmap of attributes that may be applied to a server
|
||||
*/
|
||||
#define SERVER_RUNNING 0x0001 /**<< The server is up and running */
|
||||
#define SERVER_MASTER 0x0002 /**<< The server is a master, i.e. can handle writes */
|
||||
#define SERVER_SLAVE 0x0004 /**<< The server is a slave, i.e. can handle reads */
|
||||
#define SERVER_JOINED 0x0008 /**<< The server is joined in a Galera cluster */
|
||||
#define SERVER_NDB 0x0010 /**<< The server is part of a MySQL cluster setup */
|
||||
#define SERVER_MAINT 0x0020 /**<< Server is in maintenance mode */
|
||||
#define SERVER_SLAVE_OF_EXTERNAL_MASTER 0x0040 /**<< Server is slave of a Master outside
|
||||
the provided replication topology */
|
||||
#define SERVER_STALE_STATUS 0x0080 /**<< Server stale status, monitor didn't update it */
|
||||
#define SERVER_MASTER_STICKINESS 0x0100 /**<< Server Master stickiness */
|
||||
#define SERVER_AUTH_ERROR 0x1000 /**<< Authentication error from monitor */
|
||||
#define SERVER_STALE_SLAVE 0x2000 /**<< Slave status is possible even without a master */
|
||||
#define SERVER_RELAY_MASTER 0x4000 /**<< Server is a relay master */
|
||||
|
||||
/**
|
||||
* Is the server running - the macro returns true if the server is marked as running
|
||||
* regardless of it's state as a master or slave
|
||||
*/
|
||||
#define SERVER_IS_RUNNING(server) (((server)->status & (SERVER_RUNNING|SERVER_MAINT)) == SERVER_RUNNING)
|
||||
/**
|
||||
* Is the server marked as down - the macro returns true if the server is believed
|
||||
* to be inoperable.
|
||||
*/
|
||||
#define SERVER_IS_DOWN(server) (((server)->status & SERVER_RUNNING) == 0)
|
||||
/**
|
||||
* Is the server a master? The server must be both running and marked as master
|
||||
* in order for the macro to return true
|
||||
*/
|
||||
#define SERVER_IS_MASTER(server) SRV_MASTER_STATUS((server)->status)
|
||||
|
||||
#define SRV_MASTER_STATUS(status) ((status & \
|
||||
(SERVER_RUNNING|SERVER_MASTER|SERVER_MAINT)) == \
|
||||
(SERVER_RUNNING|SERVER_MASTER))
|
||||
|
||||
/**
|
||||
* Is the server valid candidate for root master. The server must be running,
|
||||
* marked as master and not have maintenance bit set.
|
||||
*/
|
||||
#define SERVER_IS_ROOT_MASTER(server) \
|
||||
(((server)->status & (SERVER_RUNNING|SERVER_MASTER|SERVER_MAINT)) == (SERVER_RUNNING|SERVER_MASTER))
|
||||
|
||||
/**
|
||||
* Is the server a slave? The server must be both running and marked as a slave
|
||||
* in order for the macro to return true
|
||||
*/
|
||||
#define SERVER_IS_SLAVE(server) \
|
||||
(((server)->status & (SERVER_RUNNING|SERVER_SLAVE|SERVER_MAINT)) == \
|
||||
(SERVER_RUNNING|SERVER_SLAVE))
|
||||
|
||||
/**
|
||||
* Is the server joined Galera node? The server must be running and joined.
|
||||
*/
|
||||
#define SERVER_IS_JOINED(server) \
|
||||
(((server)->status & (SERVER_RUNNING|SERVER_JOINED|SERVER_MAINT)) == (SERVER_RUNNING|SERVER_JOINED))
|
||||
|
||||
/**
|
||||
* Is the server a SQL node in MySQL Cluster? The server must be running and with NDB status
|
||||
*/
|
||||
#define SERVER_IS_NDB(server) \
|
||||
(((server)->status & (SERVER_RUNNING|SERVER_NDB|SERVER_MAINT)) == (SERVER_RUNNING|SERVER_NDB))
|
||||
|
||||
/**
|
||||
* Is the server in maintenance mode.
|
||||
*/
|
||||
#define SERVER_IN_MAINT(server) ((server)->status & SERVER_MAINT)
|
||||
|
||||
/** server is not master, slave or joined */
|
||||
#define SERVER_NOT_IN_CLUSTER(s) (((s)->status & (SERVER_MASTER|SERVER_SLAVE|SERVER_JOINED|SERVER_NDB)) == 0)
|
||||
|
||||
#define SERVER_IS_IN_CLUSTER(s) (((s)->status & (SERVER_MASTER|SERVER_SLAVE|SERVER_JOINED|SERVER_NDB)) != 0)
|
||||
|
||||
#define SERVER_IS_RELAY_SERVER(server) \
|
||||
(((server)->status & (SERVER_RUNNING|SERVER_MASTER|SERVER_SLAVE|SERVER_MAINT)) == \
|
||||
(SERVER_RUNNING|SERVER_MASTER|SERVER_SLAVE))
|
||||
|
||||
extern SERVER *server_alloc(char *, char *, unsigned short, char*, char*);
|
||||
extern int server_free(SERVER *);
|
||||
extern SERVER *server_find_by_unique_name(char *);
|
||||
extern SERVER *server_find(char *, unsigned short);
|
||||
extern void printServer(SERVER *);
|
||||
extern void printAllServers();
|
||||
extern void dprintAllServers(DCB *);
|
||||
extern void dprintAllServersJson(DCB *);
|
||||
extern void dprintServer(DCB *, SERVER *);
|
||||
extern void dprintPersistentDCBs(DCB *, SERVER *);
|
||||
extern void dListServers(DCB *);
|
||||
extern char *server_status(SERVER *);
|
||||
extern void server_clear_set_status(SERVER *server, int specified_bits, int bits_to_set);
|
||||
extern void server_set_status(SERVER *, int);
|
||||
extern void server_clear_status(SERVER *, int);
|
||||
extern void server_transfer_status(SERVER *dest_server, SERVER *source_server);
|
||||
extern void serverAddMonUser(SERVER *, char *, char *);
|
||||
extern void serverAddParameter(SERVER *, char *, char *);
|
||||
extern char *serverGetParameter(SERVER *, char *);
|
||||
extern void server_update(SERVER *, char *, char *, char *);
|
||||
extern void server_set_unique_name(SERVER *, char *);
|
||||
extern DCB *server_get_persistent(SERVER *, char *, const char *);
|
||||
extern void server_update_address(SERVER *, char *);
|
||||
extern void server_update_port(SERVER *, unsigned short);
|
||||
extern RESULTSET *serverGetList();
|
||||
extern unsigned int server_map_status(char *str);
|
||||
extern bool server_set_version_string(SERVER* server, const char* string);
|
||||
|
||||
#endif
|
225
include/maxscale/service.h
Normal file
225
include/maxscale/service.h
Normal file
@ -0,0 +1,225 @@
|
||||
#ifndef _SERVICE_H
|
||||
#define _SERVICE_H
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
|
||||
#include <time.h>
|
||||
#include <maxscale/gw_protocol.h>
|
||||
#include <maxscale/spinlock.h>
|
||||
#include <maxscale/dcb.h>
|
||||
#include <maxscale/server.h>
|
||||
#include <maxscale/listener.h>
|
||||
#include <maxscale/filter.h>
|
||||
#include <maxscale/hashtable.h>
|
||||
#include <maxscale/resultset.h>
|
||||
#include <maxscale/maxconfig.h>
|
||||
#include <maxscale/queuemanager.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/dh.h>
|
||||
/**
|
||||
* @file service.h
|
||||
*
|
||||
* The service level definitions within the gateway
|
||||
*
|
||||
* @verbatim
|
||||
* Revision History
|
||||
*
|
||||
* Date Who Description
|
||||
* 14/06/13 Mark Riddoch Initial implementation
|
||||
* 18/06/13 Mark Riddoch Addition of statistics and function
|
||||
* prototypes
|
||||
* 23/06/13 Mark Riddoch Added service user and users
|
||||
* 06/02/14 Massimiliano Pinto Added service flag for root user access
|
||||
* 25/02/14 Massimiliano Pinto Added service refresh limit feature
|
||||
* 07/05/14 Massimiliano Pinto Added version_string field to service
|
||||
* struct
|
||||
* 29/05/14 Mark Riddoch Filter API mechanism
|
||||
* 26/06/14 Mark Riddoch Added WeightBy support
|
||||
* 09/09/14 Massimiliano Pinto Added service option for localhost authentication
|
||||
* 09/10/14 Massimiliano Pinto Added service resources via hashtable
|
||||
* 31/05/16 Martin Brampton Add fields to support connection throttling
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
struct server;
|
||||
struct router;
|
||||
struct router_object;
|
||||
struct users;
|
||||
|
||||
/**
|
||||
* The service statistics structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
time_t started; /**< The time when the service was started */
|
||||
int n_failed_starts; /**< Number of times this service has failed to start */
|
||||
int n_sessions; /**< Number of sessions created on service since start */
|
||||
int n_current; /**< Current number of sessions */
|
||||
} SERVICE_STATS;
|
||||
|
||||
/**
|
||||
* The service user structure holds the information that is needed
|
||||
for this service to allow the gateway to login to the backend
|
||||
database and extact information such as the user table or other
|
||||
database status or configuration data.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
char *name; /**< The user name to use to extract information */
|
||||
char *authdata; /**< The authentication data requied */
|
||||
} SERVICE_USER;
|
||||
|
||||
/**
|
||||
* The service refresh rate holds the counter and last load time_t
|
||||
for this service to load users data from the backend database
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int nloads;
|
||||
time_t last;
|
||||
} SERVICE_REFRESH_RATE;
|
||||
|
||||
typedef struct server_ref_t
|
||||
{
|
||||
struct server_ref_t *next;
|
||||
SERVER* server;
|
||||
} SERVER_REF;
|
||||
|
||||
#define SERVICE_MAX_RETRY_INTERVAL 3600 /*< The maximum interval between service start retries */
|
||||
|
||||
/** Value of service timeout if timeout checks are disabled */
|
||||
#define SERVICE_NO_SESSION_TIMEOUT LONG_MAX
|
||||
|
||||
/**
|
||||
* Parameters that are automatically detected but can also be configured by the
|
||||
* user are initially set to this value.
|
||||
*/
|
||||
#define SERVICE_PARAM_UNINIT -1
|
||||
|
||||
/**
|
||||
* Defines a service within the gateway.
|
||||
*
|
||||
* A service is a combination of a set of backend servers, a routing mechanism
|
||||
* and a set of client side protocol/port pairs used to listen for new connections
|
||||
* to the service.
|
||||
*/
|
||||
typedef struct service
|
||||
{
|
||||
char *name; /**< The service name */
|
||||
int state; /**< The service state */
|
||||
int client_count; /**< Number of connected clients */
|
||||
int max_connections; /**< Maximum client connections */
|
||||
QUEUE_CONFIG *queued_connections; /**< Queued connections, if set */
|
||||
SERV_LISTENER *ports; /**< Linked list of ports and protocols
|
||||
* that this service will listen on.
|
||||
*/
|
||||
char *routerModule; /**< Name of router module to use */
|
||||
char **routerOptions; /**< Router specific option strings */
|
||||
struct router_object *router; /**< The router we are using */
|
||||
void *router_instance; /**< The router instance for this service */
|
||||
char *version_string; /** version string for this service listeners */
|
||||
SERVER_REF *dbref; /** server references */
|
||||
SERVICE_USER credentials; /**< The cedentials of the service user */
|
||||
SPINLOCK spin; /**< The service spinlock */
|
||||
SERVICE_STATS stats; /**< The service statistics */
|
||||
int enable_root; /**< Allow root user access */
|
||||
int localhost_match_wildcard_host; /**< Match localhost against wildcard */
|
||||
CONFIG_PARAMETER* svc_config_param;/*< list of config params and values */
|
||||
int svc_config_version; /*< Version number of configuration */
|
||||
bool svc_do_shutdown; /*< tells the service to exit loops etc. */
|
||||
bool users_from_all; /*< Load users from one server or all of them */
|
||||
bool strip_db_esc; /*< Remove the '\' characters from database names
|
||||
* when querying them from the server. MySQL Workbench seems
|
||||
* to escape at least the underscore character. */
|
||||
SPINLOCK users_table_spin; /**< The spinlock for users data refresh */
|
||||
SERVICE_REFRESH_RATE rate_limit; /**< The refresh rate limit for users table */
|
||||
FILTER_DEF **filters; /**< Ordered list of filters */
|
||||
int n_filters; /**< Number of filters */
|
||||
long conn_idle_timeout; /**< Session timeout in seconds */
|
||||
char *weightby;
|
||||
struct service *next; /**< The next service in the linked list */
|
||||
bool retry_start; /*< If starting of the service should be retried later */
|
||||
bool log_auth_warnings; /*< Log authentication failures and warnings */
|
||||
} SERVICE;
|
||||
|
||||
typedef enum count_spec_t
|
||||
{
|
||||
COUNT_NONE = 0,
|
||||
COUNT_ATLEAST,
|
||||
COUNT_EXACT,
|
||||
COUNT_ATMOST
|
||||
} count_spec_t;
|
||||
|
||||
#define SERVICE_STATE_ALLOC 1 /**< The service has been allocated */
|
||||
#define SERVICE_STATE_STARTED 2 /**< The service has been started */
|
||||
#define SERVICE_STATE_FAILED 3 /**< The service failed to start */
|
||||
#define SERVICE_STATE_STOPPED 4 /**< The service has been stopped */
|
||||
|
||||
extern SERVICE *service_alloc(const char *, const char *);
|
||||
extern int service_free(SERVICE *);
|
||||
extern SERVICE *service_find(char *);
|
||||
extern int service_isvalid(SERVICE *);
|
||||
extern int serviceAddProtocol(SERVICE *service, char *name, char *protocol,
|
||||
char *address, unsigned short port,
|
||||
char *authenticator, char *options,
|
||||
SSL_LISTENER *ssl);
|
||||
extern int serviceHasProtocol(SERVICE *service, const char *protocol,
|
||||
const char* address, unsigned short port);
|
||||
extern void serviceAddBackend(SERVICE *, SERVER *);
|
||||
extern int serviceHasBackend(SERVICE *, SERVER *);
|
||||
extern void serviceAddRouterOption(SERVICE *, char *);
|
||||
extern void serviceClearRouterOptions(SERVICE *);
|
||||
extern int serviceStart(SERVICE *);
|
||||
extern int serviceStartAll();
|
||||
extern void serviceStartProtocol(SERVICE *, char *, int);
|
||||
extern int serviceStop(SERVICE *);
|
||||
extern int serviceRestart(SERVICE *);
|
||||
extern int serviceSetUser(SERVICE *, char *, char *);
|
||||
extern int serviceGetUser(SERVICE *, char **, char **);
|
||||
extern bool serviceSetFilters(SERVICE *, char *);
|
||||
extern int serviceSetSSL(SERVICE *service, char* action);
|
||||
extern int serviceSetSSLVersion(SERVICE *service, char* version);
|
||||
extern int serviceSetSSLVerifyDepth(SERVICE* service, int depth);
|
||||
extern void serviceSetCertificates(SERVICE *service, char* cert, char* key, char* ca_cert);
|
||||
extern int serviceEnableRootUser(SERVICE *, int );
|
||||
extern int serviceSetTimeout(SERVICE *, int );
|
||||
extern int serviceSetConnectionLimits(SERVICE *, int, int, int);
|
||||
extern void serviceSetRetryOnFailure(SERVICE *service, char* value);
|
||||
extern void serviceWeightBy(SERVICE *, char *);
|
||||
extern char *serviceGetWeightingParameter(SERVICE *);
|
||||
extern int serviceEnableLocalhostMatchWildcardHost(SERVICE *, int);
|
||||
extern int serviceStripDbEsc(SERVICE* service, int action);
|
||||
extern int serviceAuthAllServers(SERVICE *service, int action);
|
||||
extern void service_update(SERVICE *, char *, char *, char *);
|
||||
extern int service_refresh_users(SERVICE *);
|
||||
extern void printService(SERVICE *);
|
||||
extern void printAllServices();
|
||||
extern void dprintAllServices(DCB *);
|
||||
extern bool service_set_param_value(SERVICE* service,
|
||||
CONFIG_PARAMETER* param,
|
||||
char* valstr,
|
||||
count_spec_t count_spec,
|
||||
config_param_type_t type);
|
||||
extern void dprintService(DCB *, SERVICE *);
|
||||
extern void dListServices(DCB *);
|
||||
extern void dListListeners(DCB *);
|
||||
extern char* service_get_name(SERVICE* svc);
|
||||
extern void service_shutdown();
|
||||
extern int serviceSessionCountAll();
|
||||
extern RESULTSET *serviceGetList();
|
||||
extern RESULTSET *serviceGetListenerList();
|
||||
extern bool service_all_services_have_listeners();
|
||||
|
||||
#endif
|
204
include/maxscale/session.h
Normal file
204
include/maxscale/session.h
Normal file
@ -0,0 +1,204 @@
|
||||
#ifndef _SESSION_H
|
||||
#define _SESSION_H
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file session.h
|
||||
*
|
||||
* @verbatim
|
||||
* Revision History
|
||||
*
|
||||
* Date Who Description
|
||||
* 01-06-2013 Mark Riddoch Initial implementation
|
||||
* 14-06-2013 Massimiliano Pinto Added void *data to session
|
||||
* for session specific data
|
||||
* 01-07-2013 Massimiliano Pinto Removed backends pointer
|
||||
* from struct session
|
||||
* 02-09-2013 Massimiliano Pinto Added session ref counter
|
||||
* 29-05-2014 Mark Riddoch Support for filter mechanism
|
||||
* added
|
||||
* 20-02-2015 Markus Mäkelä Added session timeouts
|
||||
* 27/06/2016 Martin Brampton Modify session struct for list manager
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
#include <time.h>
|
||||
#include <maxscale/atomic.h>
|
||||
#include <maxscale/buffer.h>
|
||||
#include <maxscale/listmanager.h>
|
||||
#include <maxscale/spinlock.h>
|
||||
#include <maxscale/resultset.h>
|
||||
#include <maxscale/skygw_utils.h>
|
||||
#include <maxscale/log_manager.h>
|
||||
|
||||
struct dcb;
|
||||
struct service;
|
||||
struct filter_def;
|
||||
|
||||
/**
|
||||
* The session statistics structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
time_t connect; /**< Time when the session was started */
|
||||
} SESSION_STATS;
|
||||
|
||||
#define SESSION_STATS_INIT {0}
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SESSION_STATE_ALLOC, /*< for all sessions */
|
||||
SESSION_STATE_READY, /*< for router session */
|
||||
SESSION_STATE_ROUTER_READY, /*< for router session */
|
||||
SESSION_STATE_STOPPING, /*< session and router are being closed */
|
||||
SESSION_STATE_LISTENER, /*< for listener session */
|
||||
SESSION_STATE_LISTENER_STOPPED, /*< for listener session */
|
||||
SESSION_STATE_TO_BE_FREED, /*< ready to be freed as soon as there are no references */
|
||||
SESSION_STATE_FREE, /*< for all sessions */
|
||||
SESSION_STATE_DUMMY /*< dummy session for consistency */
|
||||
} session_state_t;
|
||||
|
||||
/**
|
||||
* The downstream element in the filter chain. This may refer to
|
||||
* another filter or to a router.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
void *instance;
|
||||
void *session;
|
||||
int (*routeQuery)(void *instance, void *session, GWBUF *request);
|
||||
} DOWNSTREAM;
|
||||
|
||||
#define DOWNSTREAM_INIT {0}
|
||||
|
||||
/**
|
||||
* The upstream element in the filter chain. This may refer to
|
||||
* another filter or to the protocol implementation.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
void *instance;
|
||||
void *session;
|
||||
int (*clientReply)(void *instance, void *session, GWBUF *response);
|
||||
int (*error)(void *instance, void *session, void *);
|
||||
} UPSTREAM;
|
||||
|
||||
#define UPSTREAM_INIT {0}
|
||||
|
||||
/**
|
||||
* Structure used to track the filter instances and sessions of the filters
|
||||
* that are in use within a session.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
struct filter_def *filter;
|
||||
void *instance;
|
||||
void *session;
|
||||
} SESSION_FILTER;
|
||||
|
||||
#define SESSION_FILTER_INIT {0}
|
||||
|
||||
/**
|
||||
* Filter type for the sessionGetList call
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
SESSION_LIST_ALL,
|
||||
SESSION_LIST_CONNECTION
|
||||
} SESSIONLISTFILTER;
|
||||
|
||||
/**
|
||||
* The session status block
|
||||
*
|
||||
* A session status block is created for each user (client) connection
|
||||
* to the database, it links the descriptors, routing implementation
|
||||
* and originating service together for the client session.
|
||||
*
|
||||
* Note that the first few fields (up to and including "entry_is_ready") must
|
||||
* precisely match the LIST_ENTRY structure defined in the list manager.
|
||||
*/
|
||||
typedef struct session
|
||||
{
|
||||
LIST_ENTRY_FIELDS
|
||||
skygw_chk_t ses_chk_top;
|
||||
SPINLOCK ses_lock;
|
||||
session_state_t state; /*< Current descriptor state */
|
||||
size_t ses_id; /*< Unique session identifier */
|
||||
int enabled_log_priorities; /*< Bitfield of enabled syslog priorities */
|
||||
struct dcb *client_dcb; /*< The client connection */
|
||||
void *router_session; /*< The router instance data */
|
||||
SESSION_STATS stats; /*< Session statistics */
|
||||
struct service *service; /*< The service this session is using */
|
||||
int n_filters; /*< Number of filter sessions */
|
||||
SESSION_FILTER *filters; /*< The filters in use within this session */
|
||||
DOWNSTREAM head; /*< Head of the filter chain */
|
||||
UPSTREAM tail; /*< The tail of the filter chain */
|
||||
int refcount; /*< Reference count on the session */
|
||||
bool ses_is_child; /*< this is a child session */
|
||||
skygw_chk_t ses_chk_tail;
|
||||
} SESSION;
|
||||
|
||||
#define SESSION_INIT {.ses_chk_top = CHK_NUM_SESSION, .ses_lock = SPINLOCK_INIT, \
|
||||
.stats = SESSION_STATS_INIT, .head = DOWNSTREAM_INIT, .tail = UPSTREAM_INIT, \
|
||||
.state = SESSION_STATE_ALLOC, .ses_chk_tail = CHK_NUM_SESSION}
|
||||
|
||||
/** Whether to do session timeout checks */
|
||||
extern bool check_timeouts;
|
||||
|
||||
/** When the next timeout check is done. This is compared to hkheartbeat in
|
||||
* hk_heartbeat.h */
|
||||
extern long next_timeout_check;
|
||||
|
||||
#define SESSION_PROTOCOL(x, type) DCB_PROTOCOL((x)->client_dcb, type)
|
||||
|
||||
/**
|
||||
* A convenience macro that can be used by the protocol modules to route
|
||||
* the incoming data to the first element in the pipeline of filters and
|
||||
* routers.
|
||||
*/
|
||||
#define SESSION_ROUTE_QUERY(sess, buf) \
|
||||
((sess)->head.routeQuery)((sess)->head.instance, \
|
||||
(sess)->head.session, (buf))
|
||||
/**
|
||||
* A convenience macro that can be used by the router modules to route
|
||||
* the replies to the first element in the pipeline of filters and
|
||||
* the protocol.
|
||||
*/
|
||||
#define SESSION_ROUTE_REPLY(sess, buf) \
|
||||
((sess)->tail.clientReply)((sess)->tail.instance, \
|
||||
(sess)->tail.session, (buf))
|
||||
|
||||
SESSION *session_alloc(struct service *, struct dcb *);
|
||||
bool session_pre_alloc(int number);
|
||||
SESSION *session_set_dummy(struct dcb *);
|
||||
bool session_free(SESSION *);
|
||||
int session_isvalid(SESSION *);
|
||||
int session_reply(void *inst, void *session, GWBUF *data);
|
||||
char *session_get_remote(SESSION *);
|
||||
char *session_getUser(SESSION *);
|
||||
void printAllSessions();
|
||||
void printSession(SESSION *);
|
||||
void dprintSessionList(DCB *pdcb);
|
||||
void dprintAllSessions(struct dcb *);
|
||||
void dprintSession(struct dcb *, SESSION *);
|
||||
void dListSessions(struct dcb *);
|
||||
char *session_state(session_state_t);
|
||||
bool session_link_dcb(SESSION *, struct dcb *);
|
||||
SESSION* get_session_by_router_ses(void* rses);
|
||||
void session_enable_log_priority(SESSION* ses, int priority);
|
||||
void session_disable_log_priority(SESSION* ses, int priority);
|
||||
RESULTSET *sessionGetList(SESSIONLISTFILTER);
|
||||
void process_idle_sessions();
|
||||
void enable_session_timeouts();
|
||||
#endif
|
581
include/maxscale/skygw_debug.h
Normal file
581
include/maxscale/skygw_debug.h
Normal file
@ -0,0 +1,581 @@
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
|
||||
#define __USE_UNIX98 1
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#if !defined(SKYGW_DEBUG_H)
|
||||
#define SKYGW_DEBUG_H
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define EXTERN_C_BLOCK_BEGIN extern "C" {
|
||||
#define EXTERN_C_BLOCK_END }
|
||||
#define EXTERN_C_FUNC extern "C"
|
||||
#else
|
||||
#define EXTERN_C_BLOCK_BEGIN
|
||||
#define EXTERN_C_BLOCK_END
|
||||
#define EXTERN_C_FUNC
|
||||
#endif
|
||||
|
||||
#if defined(SS_DEBUG)
|
||||
# define SS_PROF
|
||||
#endif
|
||||
|
||||
#if defined(SS_DEBUG) || defined(SS_PROF)
|
||||
# define ss_prof(exp) exp
|
||||
#else
|
||||
# define ss_prof(exp)
|
||||
#endif /* SS_DEBUG || SS_PROF */
|
||||
|
||||
#if defined(SS_DEBUG) && defined(LOG_ASSERT)
|
||||
#include <maxscale/log_manager.h>
|
||||
# define ss_dassert(exp) do { if(!(exp)){\
|
||||
MXS_ERROR("debug assert %s:%d\n", (char*)__FILE__, __LINE__);\
|
||||
mxs_log_flush_sync(); assert(exp);} } while (false)
|
||||
#define ss_info_dassert(exp,info) do { if(!(exp)){\
|
||||
MXS_ERROR("debug assert %s:%d %s\n", (char*)__FILE__, __LINE__, info);\
|
||||
mxs_log_flush_sync();assert(exp);} } while (false)
|
||||
# define ss_debug(exp) exp
|
||||
# define ss_dfprintf fprintf
|
||||
# define ss_dfflush fflush
|
||||
# define ss_dfwrite fwrite
|
||||
#elif defined(SS_DEBUG)
|
||||
|
||||
# define ss_debug(exp) exp
|
||||
# define ss_dfprintf fprintf
|
||||
# define ss_dfflush fflush
|
||||
# define ss_dfwrite fwrite
|
||||
|
||||
# define ss_dassert(exp) \
|
||||
{ \
|
||||
if (!(exp)) { \
|
||||
ss_dfprintf(stderr, \
|
||||
"debug assert %s:%d\n", \
|
||||
(char*)__FILE__, \
|
||||
__LINE__); \
|
||||
ss_dfflush(stderr); \
|
||||
assert(exp); \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
# define ss_info_dassert(exp, info) \
|
||||
{ \
|
||||
if (!(exp)) { \
|
||||
ss_dfprintf(stderr, "debug assert %s:%d, %s\n", \
|
||||
(char *)__FILE__, \
|
||||
__LINE__, \
|
||||
info); \
|
||||
ss_dfflush(stderr); \
|
||||
assert((exp)); \
|
||||
} \
|
||||
}
|
||||
|
||||
#else /* SS_DEBUG */
|
||||
|
||||
# define ss_debug(exp)
|
||||
# define ss_dfprintf(a, b, ...)
|
||||
# define ss_dfflush(s)
|
||||
# define ss_dfwrite(a, b, c, d)
|
||||
# define ss_dassert(exp)
|
||||
# define ss_info_dassert(exp, info)
|
||||
|
||||
#endif /* SS_DEBUG */
|
||||
|
||||
#define CHK_NUM_BASE 101
|
||||
|
||||
typedef enum skygw_chk_t
|
||||
{
|
||||
CHK_NUM_SLIST = CHK_NUM_BASE,
|
||||
CHK_NUM_SLIST_NODE,
|
||||
CHK_NUM_SLIST_CURSOR,
|
||||
CHK_NUM_MLIST,
|
||||
CHK_NUM_MLIST_NODE,
|
||||
CHK_NUM_MLIST_CURSOR,
|
||||
CHK_NUM_QUERY_TEST,
|
||||
CHK_NUM_LOGFILE,
|
||||
CHK_NUM_FILEWRITER,
|
||||
CHK_NUM_THREAD,
|
||||
CHK_NUM_SIMPLE_MUTEX,
|
||||
CHK_NUM_MESSAGE,
|
||||
CHK_NUM_RWLOCK,
|
||||
CHK_NUM_FNAMES,
|
||||
CHK_NUM_LOGMANAGER,
|
||||
CHK_NUM_FILE,
|
||||
CHK_NUM_BLOCKBUF,
|
||||
CHK_NUM_HASHTABLE,
|
||||
CHK_NUM_DCB,
|
||||
CHK_NUM_PROTOCOL,
|
||||
CHK_NUM_SESSION,
|
||||
CHK_NUM_SERVER,
|
||||
CHK_NUM_ROUTER_SES,
|
||||
CHK_NUM_MY_SESCMD,
|
||||
CHK_NUM_ROUTER_PROPERTY,
|
||||
CHK_NUM_SESCMD_CUR,
|
||||
CHK_NUM_BACKEND,
|
||||
CHK_NUM_BACKEND_REF,
|
||||
CHK_NUM_PREP_STMT,
|
||||
CHK_NUM_PINFO,
|
||||
CHK_NUM_MYSQLSES,
|
||||
CHK_NUM_ADMINSES,
|
||||
CHK_NUM_MANAGED_LIST
|
||||
} skygw_chk_t;
|
||||
|
||||
# define STRBOOL(b) ((b) ? "true" : "false")
|
||||
|
||||
# define STRQTYPE(t) ((t) == QUERY_TYPE_WRITE ? "QUERY_TYPE_WRITE" : \
|
||||
((t) == QUERY_TYPE_READ ? "QUERY_TYPE_READ" : \
|
||||
((t) == QUERY_TYPE_SESSION_WRITE ? "QUERY_TYPE_SESSION_WRITE" : \
|
||||
((t) == QUERY_TYPE_UNKNOWN ? "QUERY_TYPE_UNKNOWN" : \
|
||||
((t) == QUERY_TYPE_LOCAL_READ ? "QUERY_TYPE_LOCAL_READ" : \
|
||||
((t) == QUERY_TYPE_MASTER_READ ? "QUERY_TYPE_MASTER_READ" : \
|
||||
((t) == QUERY_TYPE_USERVAR_READ ? "QUERY_TYPE_USERVAR_READ" : \
|
||||
((t) == QUERY_TYPE_SYSVAR_READ ? "QUERY_TYPE_SYSVAR_READ" : \
|
||||
((t) == QUERY_TYPE_GSYSVAR_READ ? "QUERY_TYPE_GSYSVAR_READ" : \
|
||||
((t) == QUERY_TYPE_GSYSVAR_WRITE ? "QUERY_TYPE_GSYSVAR_WRITE" : \
|
||||
((t) == QUERY_TYPE_BEGIN_TRX ? "QUERY_TYPE_BEGIN_TRX" : \
|
||||
((t) == QUERY_TYPE_ENABLE_AUTOCOMMIT ? "QUERY_TYPE_ENABLE_AUTOCOMMIT" : \
|
||||
((t) == QUERY_TYPE_DISABLE_AUTOCOMMIT ? "QUERY_TYPE_DISABLE_AUTOCOMMIT" : \
|
||||
((t) == QUERY_TYPE_ROLLBACK ? "QUERY_TYPE_ROLLBACK" : \
|
||||
((t) == QUERY_TYPE_COMMIT ? "QUERY_TYPE_COMMIT" : \
|
||||
((t) == QUERY_TYPE_PREPARE_NAMED_STMT ? "QUERY_TYPE_PREPARE_NAMED_STMT" : \
|
||||
((t) == QUERY_TYPE_PREPARE_STMT ? "QUERY_TYPE_PREPARE_STMT" : \
|
||||
((t) == QUERY_TYPE_EXEC_STMT ? "QUERY_TYPE_EXEC_STMT" : \
|
||||
((t) == QUERY_TYPE_CREATE_TMP_TABLE ? "QUERY_TYPE_CREATE_TMP_TABLE" : \
|
||||
((t) == QUERY_TYPE_READ_TMP_TABLE ? "QUERY_TYPE_READ_TMP_TABLE" : \
|
||||
((t) == QUERY_TYPE_SHOW_DATABASES ? "QUERY_TYPE_SHOW_DATABASES" : \
|
||||
((t) == QUERY_TYPE_SHOW_TABLES ? "QUERY_TYPE_SHOW_TABLES" : \
|
||||
"Unknown query type"))))))))))))))))))))))
|
||||
|
||||
#define STRLOGPRIORITYNAME(n)\
|
||||
((n) == LOG_EMERG ? "LOG_EMERG" : \
|
||||
((n) == LOG_ALERT ? "LOG_ALERT" : \
|
||||
((n) == LOG_CRIT ? "LOG_CRIT" : \
|
||||
((n) == LOG_ERR ? "LOG_ERR" : \
|
||||
((n) == LOG_WARNING ? "LOG_WARNING" : \
|
||||
((n) == LOG_NOTICE ? "LOG_NOTICE" : \
|
||||
((n) == LOG_INFO ? "LOG_INFO" : \
|
||||
((n) == LOG_DEBUG ? "LOG_DEBUG" : \
|
||||
"Unknown log priority"))))))))
|
||||
|
||||
#define STRPACKETTYPE(p) ((p) == MYSQL_COM_INIT_DB ? "COM_INIT_DB" : \
|
||||
((p) == MYSQL_COM_CREATE_DB ? "COM_CREATE_DB" : \
|
||||
((p) == MYSQL_COM_DROP_DB ? "COM_DROP_DB" : \
|
||||
((p) == MYSQL_COM_REFRESH ? "COM_REFRESH" : \
|
||||
((p) == MYSQL_COM_DEBUG ? "COM_DEBUG" : \
|
||||
((p) == MYSQL_COM_PING ? "COM_PING" : \
|
||||
((p) == MYSQL_COM_CHANGE_USER ? "COM_CHANGE_USER" : \
|
||||
((p) == MYSQL_COM_QUERY ? "COM_QUERY" : \
|
||||
((p) == MYSQL_COM_SHUTDOWN ? "COM_SHUTDOWN" : \
|
||||
((p) == MYSQL_COM_PROCESS_INFO ? "COM_PROCESS_INFO" : \
|
||||
((p) == MYSQL_COM_CONNECT ? "COM_CONNECT" : \
|
||||
((p) == MYSQL_COM_PROCESS_KILL ? "COM_PROCESS_KILL" : \
|
||||
((p) == MYSQL_COM_TIME ? "COM_TIME" : \
|
||||
((p) == MYSQL_COM_DELAYED_INSERT ? "COM_DELAYED_INSERT" : \
|
||||
((p) == MYSQL_COM_DAEMON ? "COM_DAEMON" : \
|
||||
((p) == MYSQL_COM_QUIT ? "COM_QUIT" : \
|
||||
((p) == MYSQL_COM_STMT_PREPARE ? "MYSQL_COM_STMT_PREPARE" : \
|
||||
((p) == MYSQL_COM_STMT_EXECUTE ? "MYSQL_COM_STMT_EXECUTE" : \
|
||||
"UNKNOWN MYSQL PACKET TYPE"))))))))))))))))))
|
||||
|
||||
#define STRDCBSTATE(s) ((s) == DCB_STATE_ALLOC ? "DCB_STATE_ALLOC" : \
|
||||
((s) == DCB_STATE_POLLING ? "DCB_STATE_POLLING" : \
|
||||
((s) == DCB_STATE_LISTENING ? "DCB_STATE_LISTENING" : \
|
||||
((s) == DCB_STATE_DISCONNECTED ? "DCB_STATE_DISCONNECTED" : \
|
||||
((s) == DCB_STATE_NOPOLLING ? "DCB_STATE_NOPOLLING" : \
|
||||
((s) == DCB_STATE_ZOMBIE ? "DCB_STATE_ZOMBIE" : \
|
||||
((s) == DCB_STATE_UNDEFINED ? "DCB_STATE_UNDEFINED" : "DCB_STATE_UNKNOWN")))))))
|
||||
|
||||
#define STRSESSIONSTATE(s) ((s) == SESSION_STATE_ALLOC ? "SESSION_STATE_ALLOC" : \
|
||||
((s) == SESSION_STATE_DUMMY ? "SESSION_STATE_DUMMY" : \
|
||||
((s) == SESSION_STATE_READY ? "SESSION_STATE_READY" : \
|
||||
((s) == SESSION_STATE_LISTENER ? "SESSION_STATE_LISTENER" : \
|
||||
((s) == SESSION_STATE_ROUTER_READY ? "SESSION_STATE_ROUTER_READY" : \
|
||||
((s) == SESSION_STATE_LISTENER_STOPPED ? "SESSION_STATE_LISTENER_STOPPED" : \
|
||||
(s) == SESSION_STATE_STOPPING ? "SESSION_STATE_STOPPING":\
|
||||
"SESSION_STATE_UNKNOWN"))))))
|
||||
|
||||
#define STRPROTOCOLSTATE(s) ((s) == MXS_AUTH_STATE_INIT ? "MXS_AUTH_STATE_INIT" : \
|
||||
((s) == MXS_AUTH_STATE_PENDING_CONNECT ? "MXS_AUTH_STATE_PENDING_CONNECT" : \
|
||||
((s) == MXS_AUTH_STATE_CONNECTED ? "MXS_AUTH_STATE_CONNECTED" : \
|
||||
((s) == MXS_AUTH_STATE_MESSAGE_READ ? "MXS_AUTH_STATE_MESSAGE_READ" : \
|
||||
((s) == MXS_AUTH_STATE_RESPONSE_SENT ? "MXS_AUTH_STATE_RESPONSE_SENT" : \
|
||||
((s) == MXS_AUTH_STATE_FAILED ? "MXS_AUTH_STATE_FAILED" : \
|
||||
((s) == MXS_AUTH_STATE_COMPLETE ? "MXS_AUTH_STATE_COMPLETE" : \
|
||||
"UNKNOWN AUTH STATE")))))))
|
||||
|
||||
#define STRITEMTYPE(t) ((t) == Item::FIELD_ITEM ? "FIELD_ITEM" : \
|
||||
((t) == Item::FUNC_ITEM ? "FUNC_ITEM" : \
|
||||
((t) == Item::SUM_FUNC_ITEM ? "SUM_FUNC_ITEM" : \
|
||||
((t) == Item::STRING_ITEM ? "STRING_ITEM" : \
|
||||
((t) == Item::INT_ITEM ? "INT_ITEM" : \
|
||||
((t) == Item::REAL_ITEM ? "REAL_ITEM" : \
|
||||
((t) == Item::NULL_ITEM ? "NULL_ITEM" : \
|
||||
((t) == Item::VARBIN_ITEM ? "VARBIN_ITEM" : \
|
||||
((t) == Item::COPY_STR_ITEM ? "COPY_STR_ITEM" : \
|
||||
((t) == Item::FIELD_AVG_ITEM ? "FIELD_AVG_ITEM" : \
|
||||
((t) == Item::DEFAULT_VALUE_ITEM ? "DEFAULT_VALUE_ITEM" : \
|
||||
((t) == Item::PROC_ITEM ? "PROC_ITEM" : \
|
||||
((t) == Item::COND_ITEM ? "COND_ITEM" : \
|
||||
((t) == Item::REF_ITEM ? "REF_ITEM" : \
|
||||
(t) == Item::FIELD_STD_ITEM ? "FIELD_STD_ITEM" : \
|
||||
((t) == Item::FIELD_VARIANCE_ITEM ? "FIELD_VARIANCE_ITEM" : \
|
||||
((t) == Item::INSERT_VALUE_ITEM ? "INSERT_VALUE_ITEM": \
|
||||
((t) == Item::SUBSELECT_ITEM ? "SUBSELECT_ITEM" : \
|
||||
((t) == Item::ROW_ITEM ? "ROW_ITEM" : \
|
||||
((t) == Item::CACHE_ITEM ? "CACHE_ITEM" : \
|
||||
((t) == Item::TYPE_HOLDER ? "TYPE_HOLDER" : \
|
||||
((t) == Item::PARAM_ITEM ? "PARAM_ITEM" : \
|
||||
((t) == Item::TRIGGER_FIELD_ITEM ? "TRIGGER_FIELD_ITEM" : \
|
||||
((t) == Item::DECIMAL_ITEM ? "DECIMAL_ITEM" : \
|
||||
((t) == Item::XPATH_NODESET ? "XPATH_NODESET" : \
|
||||
((t) == Item::XPATH_NODESET_CMP ? "XPATH_NODESET_CMP" : \
|
||||
((t) == Item::VIEW_FIXER_ITEM ? "VIEW_FIXER_ITEM" : \
|
||||
((t) == Item::EXPR_CACHE_ITEM ? "EXPR_CACHE_ITEM" : \
|
||||
"Unknown item")))))))))))))))))))))))))))
|
||||
|
||||
#define STRDCBROLE(r) ((r) == DCB_ROLE_SERVICE_LISTENER ? "DCB_ROLE_SERVICE_LISTENER" : \
|
||||
((r) == DCB_ROLE_CLIENT_HANDLER ? "DCB_ROLE_CLIENT_HANDLER" : \
|
||||
((r) == DCB_ROLE_BACKEND_HANDLER ? "DCB_ROLE_BACKEND_HANDLER" : \
|
||||
"UNKNOWN DCB ROLE")))
|
||||
|
||||
#define STRBETYPE(t) ((t) == BE_MASTER ? "BE_MASTER" : \
|
||||
((t) == BE_SLAVE ? "BE_SLAVE" : \
|
||||
((t) == BE_UNDEFINED ? "BE_UNDEFINED" : \
|
||||
"Unknown backend tpe")))
|
||||
|
||||
#define STRCRITERIA(c) ((c) == UNDEFINED_CRITERIA ? "UNDEFINED_CRITERIA" : \
|
||||
((c) == LEAST_GLOBAL_CONNECTIONS ? "LEAST_GLOBAL_CONNECTIONS" : \
|
||||
((c) == LEAST_ROUTER_CONNECTIONS ? "LEAST_ROUTER_CONNECTIONS" : \
|
||||
((c) == LEAST_BEHIND_MASTER ? "LEAST_BEHIND_MASTER" : \
|
||||
((c) == LEAST_CURRENT_OPERATIONS ? "LEAST_CURRENT_OPERATIONS" : "Unknown criteria")))))
|
||||
|
||||
#define STRSRVSTATUS(s) (SERVER_IS_MASTER(s) ? "RUNNING MASTER" : \
|
||||
(SERVER_IS_SLAVE(s) ? "RUNNING SLAVE" : \
|
||||
(SERVER_IS_JOINED(s) ? "RUNNING JOINED" : \
|
||||
(SERVER_IS_NDB(s) ? "RUNNING NDB" : \
|
||||
((SERVER_IS_RUNNING(s) && SERVER_IN_MAINT(s)) ? "RUNNING MAINTENANCE" : \
|
||||
(SERVER_IS_RELAY_SERVER(s) ? "RUNNING RELAY" : \
|
||||
(SERVER_IS_RUNNING(s) ? "RUNNING (only)" : \
|
||||
(SERVER_IS_DOWN(s) ? "DOWN" : "UNKNOWN STATUS"))))))))
|
||||
|
||||
#define STRTARGET(t) (t == TARGET_ALL ? "TARGET_ALL" : \
|
||||
(t == TARGET_MASTER ? "TARGET_MASTER" : \
|
||||
(t == TARGET_SLAVE ? "TARGET_SLAVE" : \
|
||||
(t == TARGET_NAMED_SERVER ? "TARGET_NAMED_SERVER" : \
|
||||
(t == TARGET_UNDEFINED ? "TARGET_UNDEFINED" : \
|
||||
"Unknown target value")))))
|
||||
|
||||
#define BREFSRV(b) (b->bref_backend->backend_server)
|
||||
|
||||
|
||||
#define STRHINTTYPE(t) (t == HINT_ROUTE_TO_MASTER ? "HINT_ROUTE_TO_MASTER" : \
|
||||
((t) == HINT_ROUTE_TO_SLAVE ? "HINT_ROUTE_TO_SLAVE" : \
|
||||
((t) == HINT_ROUTE_TO_NAMED_SERVER ? "HINT_ROUTE_TO_NAMED_SERVER" : \
|
||||
((t) == HINT_ROUTE_TO_UPTODATE_SERVER ? "HINT_ROUTE_TO_UPTODATE_SERVER" : \
|
||||
((t) == HINT_ROUTE_TO_ALL ? "HINT_ROUTE_TO_ALL" : \
|
||||
((t) == HINT_PARAMETER ? "HINT_PARAMETER" : "UNKNOWN HINT TYPE"))))))
|
||||
|
||||
#define STRDCBREASON(r) ((r) == DCB_REASON_CLOSE ? "DCB_REASON_CLOSE" : \
|
||||
((r) == DCB_REASON_DRAINED ? "DCB_REASON_DRAINED" : \
|
||||
((r) == DCB_REASON_HIGH_WATER ? "DCB_REASON_HIGH_WATER" : \
|
||||
((r) == DCB_REASON_LOW_WATER ? "DCB_REASON_LOW_WATER" : \
|
||||
((r) == DCB_REASON_ERROR ? "DCB_REASON_ERROR" : \
|
||||
((r) == DCB_REASON_HUP ? "DCB_REASON_HUP" : \
|
||||
((r) == DCB_REASON_NOT_RESPONDING ? "DCB_REASON_NOT_RESPONDING" : \
|
||||
"Unknown DCB reason")))))))
|
||||
|
||||
#define CHK_MLIST(l) { \
|
||||
ss_info_dassert((l->mlist_chk_top == CHK_NUM_MLIST && \
|
||||
l->mlist_chk_tail == CHK_NUM_MLIST), \
|
||||
"Single-linked list structure under- or overflow"); \
|
||||
if (l->mlist_first == NULL) { \
|
||||
ss_info_dassert(l->mlist_nodecount == 0, \
|
||||
"List head is NULL but element counter is not zero."); \
|
||||
ss_info_dassert(l->mlist_last == NULL, \
|
||||
"List head is NULL but tail has node"); \
|
||||
} else { \
|
||||
ss_info_dassert(l->mlist_nodecount > 0, \
|
||||
"List head has node but element counter is not " \
|
||||
"positive."); \
|
||||
CHK_MLIST_NODE(l->mlist_first); \
|
||||
CHK_MLIST_NODE(l->mlist_last); \
|
||||
} \
|
||||
if (l->mlist_nodecount == 0) { \
|
||||
ss_info_dassert(l->mlist_first == NULL, \
|
||||
"Element counter is zero but head has node"); \
|
||||
ss_info_dassert(l->mlist_last == NULL, \
|
||||
"Element counter is zero but tail has node"); \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define CHK_MLIST_NODE(n) { \
|
||||
ss_info_dassert((n->mlnode_chk_top == CHK_NUM_MLIST_NODE && \
|
||||
n->mlnode_chk_tail == CHK_NUM_MLIST_NODE), \
|
||||
"Single-linked list node under- or overflow"); \
|
||||
}
|
||||
|
||||
#define CHK_MLIST_CURSOR(c) { \
|
||||
ss_info_dassert(c->mlcursor_chk_top == CHK_NUM_MLIST_CURSOR && \
|
||||
c->mlcursor_chk_tail == CHK_NUM_MLIST_CURSOR, \
|
||||
"List cursor under- or overflow"); \
|
||||
ss_info_dassert(c->mlcursor_list != NULL, \
|
||||
"List cursor doesn't have list"); \
|
||||
ss_info_dassert(c->mlcursor_pos != NULL || \
|
||||
(c->mlcursor_pos == NULL && \
|
||||
c->mlcursor_list->mlist_first == NULL), \
|
||||
"List cursor doesn't have position"); \
|
||||
}
|
||||
|
||||
#define CHK_SLIST(l) { \
|
||||
ss_info_dassert((l->slist_chk_top == CHK_NUM_SLIST && \
|
||||
l->slist_chk_tail == CHK_NUM_SLIST), \
|
||||
"Single-linked list structure under- or overflow"); \
|
||||
if (l->slist_head == NULL) { \
|
||||
ss_info_dassert(l->slist_nelems == 0, \
|
||||
"List head is NULL but element counter is not zero."); \
|
||||
ss_info_dassert(l->slist_tail == NULL, \
|
||||
"List head is NULL but tail has node"); \
|
||||
} else { \
|
||||
ss_info_dassert(l->slist_nelems > 0, \
|
||||
"List head has node but element counter is not " \
|
||||
"positive."); \
|
||||
CHK_SLIST_NODE(l->slist_head); \
|
||||
CHK_SLIST_NODE(l->slist_tail); \
|
||||
} \
|
||||
if (l->slist_nelems == 0) { \
|
||||
ss_info_dassert(l->slist_head == NULL, \
|
||||
"Element counter is zero but head has node"); \
|
||||
ss_info_dassert(l->slist_tail == NULL, \
|
||||
"Element counter is zero but tail has node"); \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define CHK_SLIST_NODE(n) { \
|
||||
ss_info_dassert((n->slnode_chk_top == CHK_NUM_SLIST_NODE && \
|
||||
n->slnode_chk_tail == CHK_NUM_SLIST_NODE), \
|
||||
"Single-linked list node under- or overflow"); \
|
||||
}
|
||||
|
||||
#define CHK_SLIST_CURSOR(c) { \
|
||||
ss_info_dassert(c->slcursor_chk_top == CHK_NUM_SLIST_CURSOR && \
|
||||
c->slcursor_chk_tail == CHK_NUM_SLIST_CURSOR, \
|
||||
"List cursor under- or overflow"); \
|
||||
ss_info_dassert(c->slcursor_list != NULL, \
|
||||
"List cursor doesn't have list"); \
|
||||
ss_info_dassert(c->slcursor_pos != NULL || \
|
||||
(c->slcursor_pos == NULL && \
|
||||
c->slcursor_list->slist_head == NULL), \
|
||||
"List cursor doesn't have position"); \
|
||||
}
|
||||
|
||||
#define CHK_QUERY_TEST(q) { \
|
||||
ss_info_dassert(q->qt_chk_top == CHK_NUM_QUERY_TEST && \
|
||||
q->qt_chk_tail == CHK_NUM_QUERY_TEST, \
|
||||
"Query test under- or overflow."); \
|
||||
}
|
||||
|
||||
#define CHK_LOGFILE(lf) { \
|
||||
ss_info_dassert(lf->lf_chk_top == CHK_NUM_LOGFILE && \
|
||||
lf->lf_chk_tail == CHK_NUM_LOGFILE, \
|
||||
"Logfile struct under- or overflow"); \
|
||||
ss_info_dassert(lf->lf_filepath != NULL && \
|
||||
lf->lf_name_prefix != NULL && \
|
||||
lf->lf_name_suffix != NULL && \
|
||||
lf->lf_full_file_name != NULL, \
|
||||
"NULL in name variable\n"); \
|
||||
}
|
||||
|
||||
#define CHK_FILEWRITER(fwr) { \
|
||||
ss_info_dassert(fwr->fwr_chk_top == CHK_NUM_FILEWRITER && \
|
||||
fwr->fwr_chk_tail == CHK_NUM_FILEWRITER, \
|
||||
"File writer struct under- or overflow"); \
|
||||
}
|
||||
|
||||
#define CHK_THREAD(thr) { \
|
||||
ss_info_dassert(thr->sth_chk_top == CHK_NUM_THREAD && \
|
||||
thr->sth_chk_tail == CHK_NUM_THREAD, \
|
||||
"Thread struct under- or overflow"); \
|
||||
}
|
||||
|
||||
#define CHK_SIMPLE_MUTEX(sm) { \
|
||||
ss_info_dassert(sm->sm_chk_top == CHK_NUM_SIMPLE_MUTEX && \
|
||||
sm->sm_chk_tail == CHK_NUM_SIMPLE_MUTEX, \
|
||||
"Simple mutex struct under- or overflow"); \
|
||||
}
|
||||
|
||||
#define CHK_MESSAGE(mes) { \
|
||||
ss_info_dassert(mes->mes_chk_top == CHK_NUM_MESSAGE && \
|
||||
mes->mes_chk_tail == CHK_NUM_MESSAGE, \
|
||||
"Message struct under- or overflow"); \
|
||||
}
|
||||
|
||||
|
||||
#define CHK_MLIST_ISLOCKED(l) { \
|
||||
ss_info_dassert((l.mlist_uselock && l.mlist_islocked) || \
|
||||
!(l.mlist_uselock || l.mlist_islocked), \
|
||||
("mlist is not locked although it should.")); \
|
||||
CHK_MUTEXED_FOR_THR(l.mlist_uselock,l.mlist_rwlock); \
|
||||
}
|
||||
|
||||
#define CHK_MUTEXED_FOR_THR(b,l) { \
|
||||
ss_info_dassert(!b || \
|
||||
(b && (l->srw_rwlock_thr == pthread_self())), \
|
||||
"rwlock is not acquired although it should be."); \
|
||||
}
|
||||
|
||||
#define CHK_FNAMES_CONF(fn) { \
|
||||
ss_info_dassert(fn->fn_chk_top == CHK_NUM_FNAMES && \
|
||||
fn->fn_chk_tail == CHK_NUM_FNAMES, \
|
||||
"File names confs struct under- or overflow"); \
|
||||
}
|
||||
|
||||
#define CHK_LOGMANAGER(lm) { \
|
||||
ss_info_dassert(lm->lm_chk_top == CHK_NUM_LOGMANAGER && \
|
||||
lm->lm_chk_tail == CHK_NUM_LOGMANAGER, \
|
||||
"Log manager struct under- or overflow"); \
|
||||
}
|
||||
|
||||
#define CHK_FILE(f) { \
|
||||
ss_info_dassert(f->sf_chk_top == CHK_NUM_FILE && \
|
||||
f->sf_chk_tail == CHK_NUM_FILE, \
|
||||
"File struct under- or overflow"); \
|
||||
}
|
||||
|
||||
|
||||
#define CHK_BLOCKBUF(bb) { \
|
||||
ss_info_dassert(bb->bb_chk_top == CHK_NUM_BLOCKBUF, \
|
||||
"Block buf under- or overflow"); \
|
||||
}
|
||||
|
||||
#define CHK_HASHTABLE(t) { \
|
||||
ss_info_dassert(t->ht_chk_top == CHK_NUM_HASHTABLE && \
|
||||
t->ht_chk_tail == CHK_NUM_HASHTABLE, \
|
||||
"Hashtable under- or overflow"); \
|
||||
}
|
||||
|
||||
#define CHK_MANAGED_LIST(l) { \
|
||||
ss_info_dassert(l->list_entry_chk_top == CHK_NUM_MANAGED_LIST && \
|
||||
l->list_entry_chk_tail == CHK_NUM_MANAGED_LIST, \
|
||||
"Managed list under- or overflow"); \
|
||||
}
|
||||
|
||||
#define CHK_DCB(d) { \
|
||||
ss_info_dassert(d->dcb_chk_top == CHK_NUM_DCB && \
|
||||
d->dcb_chk_tail == CHK_NUM_DCB, \
|
||||
"Dcb under- or overflow"); \
|
||||
CHK_MANAGED_LIST(d) \
|
||||
}
|
||||
|
||||
#define CHK_PROTOCOL(p) { \
|
||||
ss_info_dassert(p->protocol_chk_top == CHK_NUM_PROTOCOL && \
|
||||
p->protocol_chk_tail == CHK_NUM_PROTOCOL, \
|
||||
"Protocol under- or overflow"); \
|
||||
}
|
||||
|
||||
#define CHK_SESSION(s) { \
|
||||
ss_info_dassert(s->ses_chk_top == CHK_NUM_SESSION && \
|
||||
s->ses_chk_tail == CHK_NUM_SESSION, \
|
||||
"Session under- or overflow"); \
|
||||
CHK_MANAGED_LIST(s) \
|
||||
}
|
||||
|
||||
#define CHK_SERVER(s) { \
|
||||
ss_info_dassert(s->server_chk_top == CHK_NUM_SERVER && \
|
||||
s->server_chk_tail == CHK_NUM_SERVER, \
|
||||
"Server under- or overflow"); \
|
||||
}
|
||||
|
||||
#define CHK_GWBUF(b) { \
|
||||
ss_info_dassert(((char *)(b)->start <= (char *)(b)->end), \
|
||||
"gwbuf start has passed the endpoint"); \
|
||||
}
|
||||
|
||||
#define CHK_CLIENT_RSES(r) { \
|
||||
ss_info_dassert((r)->rses_chk_top == CHK_NUM_ROUTER_SES && \
|
||||
(r)->rses_chk_tail == CHK_NUM_ROUTER_SES, \
|
||||
"Router client session has invalid check fields"); \
|
||||
}
|
||||
|
||||
#define CHK_RSES_PROP(p) { \
|
||||
ss_info_dassert((p)->rses_prop_chk_top == CHK_NUM_ROUTER_PROPERTY && \
|
||||
(p)->rses_prop_chk_tail == CHK_NUM_ROUTER_PROPERTY, \
|
||||
"Router property has invalid check fields"); \
|
||||
}
|
||||
|
||||
#define CHK_MYSQL_SESCMD(s) { \
|
||||
ss_info_dassert((s)->my_sescmd_chk_top == CHK_NUM_MY_SESCMD && \
|
||||
(s)->my_sescmd_chk_tail == CHK_NUM_MY_SESCMD, \
|
||||
"Session command has invalid check fields"); \
|
||||
}
|
||||
|
||||
#define CHK_SESCMD_CUR(c) { \
|
||||
ss_info_dassert((c)->scmd_cur_chk_top == CHK_NUM_SESCMD_CUR && \
|
||||
(c)->scmd_cur_chk_tail == CHK_NUM_SESCMD_CUR, \
|
||||
"Session command cursor has invalid check fields"); \
|
||||
}
|
||||
|
||||
#define CHK_BACKEND(b) { \
|
||||
ss_info_dassert((b)->be_chk_top == CHK_NUM_BACKEND && \
|
||||
(b)->be_chk_tail == CHK_NUM_BACKEND, \
|
||||
"BACKEND has invalid check fields"); \
|
||||
}
|
||||
|
||||
#define CHK_BACKEND_REF(r) { \
|
||||
ss_info_dassert((r)->bref_chk_top == CHK_NUM_BACKEND_REF && \
|
||||
(r)->bref_chk_tail == CHK_NUM_BACKEND_REF, \
|
||||
"Backend reference has invalid check fields"); \
|
||||
}
|
||||
|
||||
#define CHK_PREP_STMT(p) { \
|
||||
ss_info_dassert((p)->pstmt_chk_top == CHK_NUM_PREP_STMT && \
|
||||
(p)->pstmt_chk_tail == CHK_NUM_PREP_STMT, \
|
||||
"Prepared statement struct has invalid check fields"); \
|
||||
}
|
||||
|
||||
#define CHK_PARSING_INFO(p) { \
|
||||
ss_info_dassert((p)->pi_chk_top == CHK_NUM_PINFO && \
|
||||
(p)->pi_chk_tail == CHK_NUM_PINFO, \
|
||||
"Parsing info struct has invalid check fields"); \
|
||||
}
|
||||
|
||||
#define CHK_MYSQL_SESSION(s) { \
|
||||
ss_info_dassert((s)->myses_chk_top == CHK_NUM_MYSQLSES && \
|
||||
(s)->myses_chk_tail == CHK_NUM_MYSQLSES, \
|
||||
"MYSQL session struct has invalid check fields"); \
|
||||
}
|
||||
|
||||
#define CHK_ADMIN_SESSION(s) { \
|
||||
ss_info_dassert((s)->adminses_chk_top == CHK_NUM_ADMINSES && \
|
||||
(s)->adminses_chk_tail == CHK_NUM_ADMINSES, \
|
||||
"Admin session struct has invalid check fields"); \
|
||||
}
|
||||
|
||||
|
||||
#if defined(FAKE_CODE)
|
||||
static bool conn_open[10240];
|
||||
#endif /* FAKE_CODE */
|
||||
|
||||
#endif /* SKYGW_DEBUG_H */
|
47
include/maxscale/skygw_types.h
Normal file
47
include/maxscale/skygw_types.h
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
|
||||
#if !defined(SKYGW_TYPES_H)
|
||||
#define SKYGW_TYPES_H
|
||||
|
||||
#include <math.h>
|
||||
#include <stdbool.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#define SECOND_USEC (1024*1024L)
|
||||
#define MSEC_USEC (1024L)
|
||||
|
||||
#define KILOBYTE_BYTE (1024L)
|
||||
#define MEGABYTE_BYTE (1024*1024L)
|
||||
#define GIGABYTE_BYTE (1024*1024*1024L)
|
||||
|
||||
#define KB KILOBYTE_BYTE
|
||||
#define MB MEGABYTE_BYTE
|
||||
#define GB GIGABYTE_BYTE
|
||||
|
||||
#define CALCLEN(i) ((size_t)(floor(log10(abs(i))) + 1))
|
||||
|
||||
#define UINTLEN(i) (i<10 ? 1 : (i<100 ? 2 : (i<1000 ? 3 : CALCLEN(i))))
|
||||
|
||||
#if !defined(PATH_MAX)
|
||||
# if defined(__USE_POSIX)
|
||||
# define PATH_MAX _POSIX_PATH_MAX
|
||||
# else
|
||||
# define PATH_MAX 256
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#define MAX_ERROR_MSG PATH_MAX
|
||||
#define array_nelems(a) ((uint)(sizeof(a)/sizeof(a[0])))
|
||||
|
||||
#endif /* SKYGW_TYPES_H */
|
208
include/maxscale/skygw_utils.h
Normal file
208
include/maxscale/skygw_utils.h
Normal file
@ -0,0 +1,208 @@
|
||||
#ifndef _SKYGW_UTILS_H
|
||||
#define _SKYGW_UTILS_H
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* We need a common.h file that is included by every component.
|
||||
*/
|
||||
#if !defined(STRERROR_BUFLEN)
|
||||
#define STRERROR_BUFLEN 512
|
||||
#endif
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a,b) (a<b ? a : b)
|
||||
#endif
|
||||
#ifndef MAX
|
||||
#define MAX(a,b) (a>b ? a : b)
|
||||
#endif
|
||||
#define FSYNCLIMIT 10
|
||||
|
||||
#include <maxscale/skygw_types.h>
|
||||
#include <maxscale/skygw_debug.h>
|
||||
|
||||
#define DISKWRITE_LATENCY (5*MSEC_USEC)
|
||||
|
||||
typedef struct skygw_file_st skygw_file_t;
|
||||
typedef struct skygw_thread_st skygw_thread_t;
|
||||
typedef struct skygw_message_st skygw_message_t;
|
||||
|
||||
typedef struct simple_mutex_st
|
||||
{
|
||||
skygw_chk_t sm_chk_top;
|
||||
pthread_mutex_t sm_mutex;
|
||||
pthread_t sm_lock_thr;
|
||||
bool sm_locked;
|
||||
int sm_enabled; /**< defined as in to minimize mutexing */
|
||||
bool sm_flat;
|
||||
char* sm_name;
|
||||
skygw_chk_t sm_chk_tail;
|
||||
} simple_mutex_t;
|
||||
|
||||
typedef struct skygw_rwlock_st
|
||||
{
|
||||
skygw_chk_t srw_chk_top;
|
||||
pthread_rwlock_t* srw_rwlock;
|
||||
pthread_t srw_rwlock_thr;
|
||||
skygw_chk_t srw_chk_tail;
|
||||
} skygw_rwlock_t;
|
||||
|
||||
|
||||
typedef enum { THR_INIT, THR_RUNNING, THR_STOPPED, THR_DONE } skygw_thr_state_t;
|
||||
typedef enum { MES_RC_FAIL, MES_RC_SUCCESS, MES_RC_TIMEOUT } skygw_mes_rc_t;
|
||||
|
||||
|
||||
static const char* timestamp_formatstr = "%04d-%02d-%02d %02d:%02d:%02d ";
|
||||
/** One for terminating '\0' */
|
||||
static const size_t timestamp_len = (4+1 +2+1 +2+1 +2+1 +2+1 +2+3 +1) * sizeof(char);
|
||||
|
||||
static const char* timestamp_formatstr_hp = "%04d-%02d-%02d %02d:%02d:%02d.%03d ";
|
||||
/** One for terminating '\0' */
|
||||
static const size_t timestamp_len_hp = (4+1 +2+1 +2+1 +2+1 +2+1 +2+1+3+3 +1) * sizeof(char);
|
||||
|
||||
struct skygw_thread_st
|
||||
{
|
||||
skygw_chk_t sth_chk_top;
|
||||
bool sth_must_exit;
|
||||
simple_mutex_t* sth_mutex;
|
||||
pthread_t sth_parent;
|
||||
pthread_t sth_thr;
|
||||
int sth_errno;
|
||||
#if defined(SS_DEBUG)
|
||||
skygw_thr_state_t sth_state;
|
||||
#endif
|
||||
char* sth_name;
|
||||
void* (*sth_thrfun)(void* data);
|
||||
void* sth_data;
|
||||
skygw_chk_t sth_chk_tail;
|
||||
};
|
||||
|
||||
struct skygw_message_st
|
||||
{
|
||||
skygw_chk_t mes_chk_top;
|
||||
bool mes_sent;
|
||||
pthread_mutex_t mes_mutex;
|
||||
pthread_cond_t mes_cond;
|
||||
skygw_chk_t mes_chk_tail;
|
||||
};
|
||||
|
||||
struct skygw_file_st
|
||||
{
|
||||
skygw_chk_t sf_chk_top;
|
||||
char* sf_fname;
|
||||
FILE* sf_file;
|
||||
int sf_fd;
|
||||
skygw_chk_t sf_chk_tail;
|
||||
};
|
||||
|
||||
EXTERN_C_BLOCK_BEGIN
|
||||
|
||||
bool utils_init(); /*< Call this first before using any other function */
|
||||
void utils_end();
|
||||
|
||||
EXTERN_C_BLOCK_END
|
||||
|
||||
/** Skygw thread routines */
|
||||
skygw_thread_t* skygw_thread_init(const char* name,
|
||||
void* (*sth_thrfun)(void* data),
|
||||
void* data);
|
||||
void skygw_thread_done(skygw_thread_t* th);
|
||||
int skygw_thread_start(skygw_thread_t* thr);
|
||||
skygw_thr_state_t skygw_thread_get_state(skygw_thread_t* thr);
|
||||
pthread_t skygw_thread_gettid(skygw_thread_t* thr);
|
||||
|
||||
size_t get_timestamp_len(void);
|
||||
size_t get_timestamp_len_hp(void);
|
||||
size_t snprint_timestamp(char* p_ts, size_t tslen);
|
||||
size_t snprint_timestamp_hp(char* p_ts, size_t tslen);
|
||||
|
||||
EXTERN_C_BLOCK_BEGIN
|
||||
|
||||
void skygw_thread_set_state(skygw_thread_t* thr,
|
||||
skygw_thr_state_t state);
|
||||
void* skygw_thread_get_data(skygw_thread_t* thr);
|
||||
bool skygw_thread_must_exit(skygw_thread_t* thr);
|
||||
bool skygw_thread_set_exitflag(skygw_thread_t* thr,
|
||||
skygw_message_t* sendmes,
|
||||
skygw_message_t* recmes);
|
||||
|
||||
EXTERN_C_BLOCK_END
|
||||
|
||||
/** Skygw thread routines */
|
||||
|
||||
/** Skygw file routines */
|
||||
typedef enum skygw_open_mode
|
||||
{
|
||||
SKYGW_OPEN_APPEND,
|
||||
SKYGW_OPEN_TRUNCATE,
|
||||
} skygw_open_mode_t;
|
||||
|
||||
skygw_file_t* skygw_file_alloc(const char* fname);
|
||||
void skygw_file_free(skygw_file_t* file);
|
||||
skygw_file_t* skygw_file_init(const char* fname,
|
||||
const char* symlinkname,
|
||||
skygw_open_mode_t mode);
|
||||
void skygw_file_close(skygw_file_t* file);
|
||||
int skygw_file_write(skygw_file_t* file,
|
||||
void* data,
|
||||
size_t nbytes,
|
||||
bool flush);
|
||||
/** Skygw file routines */
|
||||
|
||||
EXTERN_C_BLOCK_BEGIN
|
||||
|
||||
void acquire_lock(int* l);
|
||||
void release_lock(int* l);
|
||||
|
||||
simple_mutex_t* simple_mutex_init(simple_mutex_t* mutexptr, const char* name);
|
||||
int simple_mutex_done(simple_mutex_t* sm);
|
||||
int simple_mutex_lock(simple_mutex_t* sm, bool block);
|
||||
int simple_mutex_unlock(simple_mutex_t* sm);
|
||||
|
||||
/** Skygw message routines */
|
||||
skygw_message_t* skygw_message_init(void);
|
||||
void skygw_message_done(skygw_message_t* mes);
|
||||
skygw_mes_rc_t skygw_message_send(skygw_message_t* mes);
|
||||
void skygw_message_wait(skygw_message_t* mes);
|
||||
skygw_mes_rc_t skygw_message_request(skygw_message_t* mes);
|
||||
void skygw_message_reset(skygw_message_t* mes);
|
||||
|
||||
/** Skygw message routines */
|
||||
|
||||
EXTERN_C_BLOCK_END
|
||||
|
||||
int skygw_rwlock_wrlock(skygw_rwlock_t* rwlock);
|
||||
int skygw_rwlock_rdlock(skygw_rwlock_t* rwlock);
|
||||
int skygw_rwlock_unlock(skygw_rwlock_t* rwlock);
|
||||
int skygw_rwlock_init(skygw_rwlock_t** rwlock);
|
||||
|
||||
EXTERN_C_BLOCK_BEGIN
|
||||
|
||||
size_t get_decimal_len(size_t s);
|
||||
|
||||
char* remove_mysql_comments(const char** src, const size_t* srcsize, char** dest,
|
||||
size_t* destsize);
|
||||
char* replace_values(const char** src, const size_t* srcsize, char** dest,
|
||||
size_t* destsize);
|
||||
char* replace_literal(char* haystack,
|
||||
const char* needle,
|
||||
const char* replacement);
|
||||
char* replace_quoted(const char** src, const size_t* srcsize, char** dest, size_t* destsize);
|
||||
bool is_valid_posix_path(char* path);
|
||||
bool strip_escape_chars(char*);
|
||||
char* trim(char *str);
|
||||
char* squeeze_whitespace(char* str);
|
||||
|
||||
EXTERN_C_BLOCK_END
|
||||
|
||||
#endif /* SKYGW_UTILS_H */
|
66
include/maxscale/slist.h
Normal file
66
include/maxscale/slist.h
Normal file
@ -0,0 +1,66 @@
|
||||
#ifndef _SLIST_H
|
||||
#define _SLIST_H
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
|
||||
#include <maxscale/skygw_utils.h>
|
||||
|
||||
EXTERN_C_BLOCK_BEGIN
|
||||
|
||||
typedef struct slist_node_st slist_node_t;
|
||||
typedef struct slist_st slist_t;
|
||||
typedef struct slist_cursor_st slist_cursor_t;
|
||||
|
||||
/** Single-linked list */
|
||||
|
||||
struct slist_node_st
|
||||
{
|
||||
skygw_chk_t slnode_chk_top;
|
||||
slist_t* slnode_list;
|
||||
slist_node_t* slnode_next;
|
||||
void* slnode_data;
|
||||
size_t slnode_cursor_refcount;
|
||||
skygw_chk_t slnode_chk_tail;
|
||||
};
|
||||
|
||||
struct slist_st
|
||||
{
|
||||
skygw_chk_t slist_chk_top;
|
||||
slist_node_t* slist_head;
|
||||
slist_node_t* slist_tail;
|
||||
int slist_nelems;
|
||||
slist_t* slist_cursors_list;
|
||||
skygw_chk_t slist_chk_tail;
|
||||
};
|
||||
|
||||
struct slist_cursor_st
|
||||
{
|
||||
skygw_chk_t slcursor_chk_top;
|
||||
slist_t* slcursor_list;
|
||||
slist_node_t* slcursor_pos;
|
||||
skygw_chk_t slcursor_chk_tail;
|
||||
};
|
||||
|
||||
slist_cursor_t* slist_init(void);
|
||||
void slist_done(slist_cursor_t* c);
|
||||
size_t slist_size(slist_cursor_t* c);
|
||||
|
||||
void slcursor_add_data(slist_cursor_t* c, void* data);
|
||||
void* slcursor_get_data(slist_cursor_t* c);
|
||||
void slcursor_remove_data(slist_cursor_t* c);
|
||||
bool slcursor_move_to_begin(slist_cursor_t* c);
|
||||
bool slcursor_step_ahead(slist_cursor_t* c);
|
||||
|
||||
EXTERN_C_BLOCK_END
|
||||
|
||||
#endif
|
79
include/maxscale/spinlock.h
Normal file
79
include/maxscale/spinlock.h
Normal file
@ -0,0 +1,79 @@
|
||||
#ifndef _SPINLOCK_H
|
||||
#define _SPINLOCK_H
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file spinlock.h
|
||||
*
|
||||
* Spinlock implementation for MaxScale.
|
||||
*
|
||||
* Spinlocks are cheap locks that can be used to protect short code blocks, they are
|
||||
* generally wasteful as any blocked threads will spin, consuming CPU cycles, waiting
|
||||
* for the lock to be released. However they are useful in that they do not involve
|
||||
* system calls and are light weight when the expected wait time for a lock is low.
|
||||
*/
|
||||
#include <maxscale/skygw_debug.h>
|
||||
|
||||
EXTERN_C_BLOCK_BEGIN
|
||||
|
||||
#define SPINLOCK_PROFILE 0
|
||||
|
||||
/**
|
||||
* The spinlock structure.
|
||||
*
|
||||
* In normal builds the structure merely contains a lock value which
|
||||
* is 0 if the spinlock is not taken and greater than zero if it is held.
|
||||
*
|
||||
* In builds with the SPINLOCK_PROFILE option set this structure also holds
|
||||
* a number of profile related fields that count the number of spins, number
|
||||
* of waiting threads and the number of times the lock has been acquired.
|
||||
*/
|
||||
typedef struct spinlock
|
||||
{
|
||||
int lock; /*< Is the lock held? */
|
||||
#if SPINLOCK_PROFILE
|
||||
int spins; /*< Number of spins on this lock */
|
||||
int maxspins; /*< Max no of spins to acquire lock */
|
||||
int acquired; /*< No. of times lock was acquired */
|
||||
int waiting; /*< No. of threads acquiring this lock */
|
||||
int max_waiting; /*< Max no of threads waiting for lock */
|
||||
int contended; /*< No. of times acquire was contended */
|
||||
THREAD owner; /*< Last owner of this lock */
|
||||
#endif
|
||||
} SPINLOCK;
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE true
|
||||
#endif
|
||||
#ifndef FALSE
|
||||
#define FALSE false
|
||||
#endif
|
||||
|
||||
#if SPINLOCK_PROFILE
|
||||
#define SPINLOCK_INIT { 0, 0, 0, 0, 0, 0, 0, 0 }
|
||||
#else
|
||||
#define SPINLOCK_INIT { 0 }
|
||||
#endif
|
||||
|
||||
#define SPINLOCK_IS_LOCKED(l) ((l)->lock != 0 ? true : false)
|
||||
|
||||
extern void spinlock_init(SPINLOCK *lock);
|
||||
extern void spinlock_acquire(const SPINLOCK *lock);
|
||||
extern int spinlock_acquire_nowait(const SPINLOCK *lock);
|
||||
extern void spinlock_release(const SPINLOCK *lock);
|
||||
extern void spinlock_stats(const SPINLOCK *lock, void (*reporter)(void *, char *, int), void *hdl);
|
||||
|
||||
EXTERN_C_BLOCK_END
|
||||
|
||||
#endif
|
71
include/maxscale/statistics.h
Normal file
71
include/maxscale/statistics.h
Normal file
@ -0,0 +1,71 @@
|
||||
#ifndef _STATISTICS_HG
|
||||
#define _STATISTICS_HG
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file statistics.h - Lock-free statistics gathering
|
||||
*
|
||||
* @verbatim
|
||||
* Revision History
|
||||
*
|
||||
* Date Who Description
|
||||
* 21/01/16 Markus Makela Initial implementation
|
||||
* 15/06/16 Martin Brampton Frequently used functions inlined
|
||||
* @endverbatim
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef void* ts_stats_t;
|
||||
|
||||
/** stats_init should be called only once */
|
||||
void ts_stats_init();
|
||||
|
||||
/** No-op for now */
|
||||
void ts_stats_end();
|
||||
|
||||
ts_stats_t ts_stats_alloc();
|
||||
void ts_stats_free(ts_stats_t stats);
|
||||
int64_t ts_stats_sum(ts_stats_t stats);
|
||||
|
||||
/**
|
||||
* @brief Increment thread statistics by one
|
||||
*
|
||||
* @param stats Statistics to add to
|
||||
* @param thread_id ID of thread
|
||||
*/
|
||||
static void inline
|
||||
ts_stats_increment(ts_stats_t stats, int thread_id)
|
||||
{
|
||||
((int64_t*)stats)[thread_id]++;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Assign a value to a statistics element
|
||||
*
|
||||
* This sets the value for the specified thread.
|
||||
*
|
||||
* @param stats Statistics to set
|
||||
* @param value Value to set to
|
||||
* @param thread_id ID of thread
|
||||
*
|
||||
* @note Appears to be unused
|
||||
*/
|
||||
static void inline
|
||||
ts_stats_set(ts_stats_t stats, int value, int thread_id)
|
||||
{
|
||||
((int64_t*)stats)[thread_id] = value;
|
||||
}
|
||||
|
||||
#endif
|
36
include/maxscale/test_utils.h
Normal file
36
include/maxscale/test_utils.h
Normal file
@ -0,0 +1,36 @@
|
||||
#ifndef TEST_UTILS_H
|
||||
#define TEST_UTILS_H
|
||||
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
|
||||
#include <maxscale/poll.h>
|
||||
#include <maxscale/dcb.h>
|
||||
#include <maxscale/housekeeper.h>
|
||||
#include <maxscale/maxscale_test.h>
|
||||
#include <maxscale/log_manager.h>
|
||||
#include <maxscale/statistics.h>
|
||||
|
||||
void init_test_env(char *path)
|
||||
{
|
||||
int argc = 3;
|
||||
|
||||
const char* logdir = path ? path : TEST_LOG_DIR;
|
||||
|
||||
ts_stats_init();
|
||||
mxs_log_init(NULL, logdir, MXS_LOG_TARGET_DEFAULT);
|
||||
poll_init();
|
||||
hkinit();
|
||||
}
|
||||
|
||||
#endif
|
36
include/maxscale/thread.h
Normal file
36
include/maxscale/thread.h
Normal file
@ -0,0 +1,36 @@
|
||||
#ifndef _THREAD_H
|
||||
#define _THREAD_H
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file thread.h The gateway threading interface
|
||||
*
|
||||
* An encapsulation of the threading used by the gateway. This is designed to
|
||||
* isolate the majority of the gateway code from the pthread library, enabling
|
||||
* the gateway to be ported to a different threading package with the minimum
|
||||
* of changes.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Thread type and thread identifier function macros
|
||||
*/
|
||||
#include <pthread.h>
|
||||
#define THREAD pthread_t
|
||||
#define thread_self() pthread_self()
|
||||
|
||||
extern THREAD *thread_start(THREAD *thd, void (*entry)(void *), void *arg);
|
||||
extern void thread_wait(THREAD thd);
|
||||
extern void thread_millisleep(int ms);
|
||||
|
||||
#endif
|
73
include/maxscale/users.h
Normal file
73
include/maxscale/users.h
Normal file
@ -0,0 +1,73 @@
|
||||
#ifndef _USERS_H
|
||||
#define _USERS_H
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#include <maxscale/hashtable.h>
|
||||
#include <maxscale/dcb.h>
|
||||
#include <maxscale/listener.h>
|
||||
#include <openssl/sha.h>
|
||||
|
||||
/**
|
||||
* @file users.h The functions to manipulate the table of users maintained
|
||||
* for each service
|
||||
*
|
||||
* @verbatim
|
||||
* Revision History
|
||||
*
|
||||
* Date Who Description
|
||||
* 23/06/13 Mark Riddoch Initial implementation
|
||||
* 26/02/14 Massimiliano Pinto Added checksum to users' table with SHA1
|
||||
* 27/02/14 Massimiliano Pinto Added USERS_HASHTABLE_DEFAULT_SIZE
|
||||
* 28/02/14 Massimiliano Pinto Added usersCustomUserFormat, optional username format routine
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
|
||||
#define USERS_HASHTABLE_DEFAULT_SIZE 52
|
||||
|
||||
/**
|
||||
* The users table statistics structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int n_entries; /**< The number of entries */
|
||||
int n_adds; /**< The number of inserts */
|
||||
int n_deletes; /**< The number of deletes */
|
||||
int n_fetches; /**< The number of fetchs */
|
||||
} USERS_STATS;
|
||||
|
||||
/**
|
||||
* The user table, this contains the username and authentication data required
|
||||
* for the authentication implementation within the gateway.
|
||||
*/
|
||||
typedef struct users
|
||||
{
|
||||
HASHTABLE *data; /**< The hashtable containing the actual data */
|
||||
char *(*usersCustomUserFormat)(void *); /**< Optional username format routine */
|
||||
USERS_STATS stats; /**< The statistics for the users table */
|
||||
unsigned char cksum[SHA_DIGEST_LENGTH]; /**< The users' table ckecksum */
|
||||
} USERS;
|
||||
|
||||
extern USERS *users_alloc(); /**< Allocate a users table */
|
||||
extern void users_free(USERS *); /**< Free a users table */
|
||||
extern int users_add(USERS *, char *, char *); /**< Add a user to the users table */
|
||||
extern int users_delete(USERS *, char *); /**< Delete a user from the users table */
|
||||
extern char *users_fetch(USERS *, char *); /**< Fetch the authentication data for a user */
|
||||
extern int users_update(USERS *, char *, char *); /**< Change the password data for a user in
|
||||
the users table */
|
||||
extern int users_default_loadusers(SERV_LISTENER *port); /**< A generic implementation of the authenticator
|
||||
* loadusers entry point */
|
||||
extern void usersPrint(USERS *); /**< Print data about the users loaded */
|
||||
extern void dcb_usersPrint(DCB *, USERS *); /**< Print data about the users loaded */
|
||||
|
||||
#endif
|
40
include/maxscale/utils.h
Normal file
40
include/maxscale/utils.h
Normal file
@ -0,0 +1,40 @@
|
||||
#ifndef _UTILS_H
|
||||
#define _UTILS_H
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file utils.h Utility functions headers
|
||||
*
|
||||
* @verbatim
|
||||
* Revision History
|
||||
*
|
||||
* Date Who Description
|
||||
* 22/03/16 Martin Brampton Initial implementation
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
|
||||
int setnonblocking(int fd);
|
||||
char *gw_strend(register const char *s);
|
||||
static char gw_randomchar();
|
||||
int gw_generate_random_str(char *output, int len);
|
||||
int gw_hex2bin(uint8_t *out, const char *in, unsigned int len);
|
||||
char *gw_bin2hex(char *out, const uint8_t *in, unsigned int len);
|
||||
void gw_str_xor(uint8_t *output, const uint8_t *input1, const uint8_t *input2, unsigned int len);
|
||||
void gw_sha1_str(const uint8_t *in, int in_len, uint8_t *out);
|
||||
void gw_sha1_2_str(const uint8_t *in, int in_len, const uint8_t *in2, int in2_len, uint8_t *out);
|
||||
int gw_getsockerrno(int fd);
|
||||
char *create_hex_sha1_sha1_passwd(char *passwd);
|
||||
|
||||
#endif
|
2
include/maxscale/version.h.in
Normal file
2
include/maxscale/version.h.in
Normal file
@ -0,0 +1,2 @@
|
||||
#define MAXSCALE_VERSION "@MAXSCALE_VERSION@"
|
||||
#define MAXSCALE_COMMIT "@MAXSCALE_COMMIT@"
|
Reference in New Issue
Block a user