Develop branch update

Develop branch update
This commit is contained in:
MassimilianoPinto
2016-11-14 17:44:39 +01:00
310 changed files with 16920 additions and 9914 deletions

View File

@ -12,9 +12,9 @@ echo TRAVIS_BUILD_DIR: ${TRAVIS_BUILD_DIR}
mkdir build
cd build
cmake .. -DCMAKE_INSTALL_PREFIX=/usr -DBUILD_TESTS=Y
cmake .. -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTS=Y -DBUILD_AVRO=N
make VERBOSE=1
make
make test
sudo make install

View File

@ -41,7 +41,10 @@ find_package(Git)
find_package(CURL)
find_package(RabbitMQ)
find_package(LibUUID)
find_package(Jansson)
find_package(Avro)
find_package(GSSAPI)
find_package(SQLite)
# Find or build PCRE2
# Read BuildPCRE2 for details about how to add pcre2 as a dependency to a target
@ -113,10 +116,10 @@ if(${MAXSCALE_VERSION} MATCHES "-stable")
endif()
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/server/include)
configure_file(${CMAKE_SOURCE_DIR}/server/include/version.h.in ${CMAKE_BINARY_DIR}/server/include/version.h @ONLY)
configure_file(${CMAKE_SOURCE_DIR}/server/include/gwdirs.h.in ${CMAKE_BINARY_DIR}/server/include/gwdirs.h @ONLY)
configure_file(${CMAKE_SOURCE_DIR}/server/include/adminusers.h.in ${CMAKE_BINARY_DIR}/server/include/adminusers.h @ONLY)
configure_file(${CMAKE_SOURCE_DIR}/server/test/maxscale_test.h.in ${CMAKE_BINARY_DIR}/server/include/maxscale_test.h @ONLY)
configure_file(${CMAKE_SOURCE_DIR}/include/maxscale/version.h.in ${CMAKE_BINARY_DIR}/include/maxscale/version.h @ONLY)
configure_file(${CMAKE_SOURCE_DIR}/include/maxscale/gwdirs.h.in ${CMAKE_BINARY_DIR}/include/maxscale/gwdirs.h @ONLY)
configure_file(${CMAKE_SOURCE_DIR}/include/maxscale/adminusers.h.in ${CMAKE_BINARY_DIR}/include/maxscale/adminusers.h @ONLY)
configure_file(${CMAKE_SOURCE_DIR}/server/test/maxscale_test.h.in ${CMAKE_BINARY_DIR}/include/maxscale/maxscale_test.h @ONLY)
configure_file(${CMAKE_SOURCE_DIR}/etc/postinst.in ${CMAKE_BINARY_DIR}/postinst @ONLY)
configure_file(${CMAKE_SOURCE_DIR}/etc/postrm.in ${CMAKE_BINARY_DIR}/postrm @ONLY)
configure_file(${CMAKE_SOURCE_DIR}/server/test/maxscale_test.cnf ${CMAKE_BINARY_DIR}/maxscale.cnf @ONLY)
@ -151,10 +154,6 @@ if(GCOV)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lgcov")
endif()
if(FAKE_CODE)
set(FLAGS "${FLAGS} -DFAKE_CODE" CACHE STRING "Compilation flags" FORCE)
endif()
if(PROFILE)
message(STATUS "Profiling executables")
set(FLAGS "${FLAGS} -pg " CACHE STRING "Compilation flags" FORCE)
@ -176,16 +175,17 @@ set(CMAKE_CXX_FLAGS_DEBUG "${DEBUG_FLAGS} -DSS_DEBUG -DLOG_ASSERT")
set(CMAKE_CXX_FLAGS_RELEASE "")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-ggdb")
include_directories(avro)
include_directories(server/include)
include_directories(include)
include_directories(server/inih)
include_directories(server/modules/include)
include_directories(${CMAKE_BINARY_DIR}/server/include)
include_directories(${CMAKE_BINARY_DIR}/include)
include_directories(${CURL_INCLUDE_DIRS})
if (BUILD_AVRO)
include_directories(avro)
add_subdirectory(avro)
endif()
add_subdirectory(plugins)
add_subdirectory(query_classifier)
add_subdirectory(server)
@ -221,6 +221,7 @@ endif()
install_file(${CMAKE_SOURCE_DIR}/COPYRIGHT core)
install_file(${CMAKE_SOURCE_DIR}/README core)
install_file(${CMAKE_SOURCE_DIR}/LICENSE.TXT core)
install_file(${CMAKE_SOURCE_DIR}/LICENSE-THIRDPARTY.TXT core)
install_file(etc/lsyncd_example.conf core)
install_manual(Documentation/maxscale.1 1 core)
install_file(${CMAKE_SOURCE_DIR}/server/maxscale_binlogserver_template.cnf core)

View File

@ -32,6 +32,14 @@ Issues [MXS-710](https://jira.mariadb.org/browse/MXS-710) and
Compression is not included in MySQL server handshake
# Authenticator limitations
## Limitations in the GSSAPI authentication
Currently MaxScale only supports GSSAPI authentication when the backend
connections use GSSAPI authentication. Client side GSSAPI authentication with a
different backend authentication module is not supported.
# Monitor limitations
A server can only be monitored by one monitor. If multiple monitors monitor the

View File

@ -0,0 +1,106 @@
# Authentication Modules in MaxScale
This document describes the modular authentication in MaxScale. It contains
protocol specific information on authentication and how it is handled in
MaxScale.
The constants described in this document are defined in the gw_authenticator.h
header unless otherwise mentioned.
## Authenticator initialization
When the authentication module is first loaded, the `initialize` entry point is
called. The return value of this function will be passed as the first argument
to the other entry points.
The `loadUsers` entry point of the client side authenticator is called when a
service starts. The authenticator can load external user data when this entry
point is called. This entry point is also called when user authentication has
failed and the external user data needs to be refreshed.
When a connection is created, the `create` entry point is called to create per
connection data. The return value of this function is stored in the
`dcb->authenticator_data` field of the DCB object. This data is freed in the
`destroy` entry point and the value returned by `create` will be given as the
first parameter.
# MySQL Authentication Moduels
The MySQL protocol authentication starts when the server sends the
[handshake packet](https://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::Handshake)
to the client to which the client responds with a [handshake response packet](https://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::HandshakeResponse).
If the server is using the default _mysql_native_password_ authentication plugin, the server responds with either an
[OK packet](https://dev.mysql.com/doc/internals/en/packet-OK_Packet.html) or an
[ERR packet](https://dev.mysql.com/doc/internals/en/packet-ERR_Packet.html) and
the authentication is complete.
If a different authentication plugin is required to complete the authentication, instead of
sending an OK or ERR packet, the server responds with an
[AuthSwitchRequest packet](https://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::AuthSwitchRequest).
This is where the pluggable authentication in MaxScale starts.
## Client authentication in MaxScale
The first packet the client side authenticator plugins will receive is the
client's handshake response packet.
The client protocol module will call the `extract` entry point of the
authenticator where the authenticator should extract client information. If the
`extract` entry point returns one of the following constants, the `authenticate`
entry point will be called.
- MXS_AUTH_SUCCEEDED
- MXS_AUTH_INCOMPLETE
- MXS_AUTH_SSL_INCOMPLETE
The `authenticate` entry point is where the authenticator plugin should
authenticate the client. If authentication is successful, the `authenticate`
entry point should return MXS_AUTH_SUCCEEDED. If authentication is not yet
complete or if the authentication module should be changed, the `authenticate`
entry point should return MXS_AUTH_INCOMPLETE.
Authenticator plugins which do not use the default _mysql_native_password_
authentication plugin should send an AuthSwitchRequest packet to the client and
return MXS_AUTH_INCOMPLETE. When more data is available, the `extract` and
`authenticate` entry points will be called again.
If either of the aforementioned entry points returns one of the following
constants, the authentication is considered to have failed and the session will
be closed.
- MXS_AUTH_FAILED
- MXS_AUTH_FAILED_DB
- MXS_AUTH_FAILED_SSL
Read the individual authenticator module documentation for more details on the
authentication process of each authentication plugin.
## Backend authentication in MaxScale
The first packet the authentication plugins in MaxScale will receive is either
the AuthSwitchRequest packet or, in case of _mysql_native_password_, the OK
packet. At this point, the protocol plugin will call the `extract` entry point
of the backend authenticator. If the return value of the call is one of the
following constants, the protocol plugin will call the `authenticate` entry
point of the authenticator.
- MXS_AUTH_SUCCEEDED
- MXS_AUTH_INCOMPLETE
- MXS_AUTH_SSL_INCOMPLETE
If the `authenticate` entry point returns MXS_AUTH_SUCCEEDED, then
authentication is complete and any queued queries from the clients will be sent
to the backend server. If the return value is MXS_AUTH_INCOMPLETE or
MXS_AUTH_SSL_INCOMPLETE, the protocol module will continue the authentication by
calling the `extract` entry point once more data is available.
If either of the aforementioned entry points returns one of the following
constants, the authentication is considered to have failed and the session will
be closed.
- MXS_AUTH_FAILED
- MXS_AUTH_FAILED_DB
- MXS_AUTH_FAILED_SSL
Read the individual authenticator module documentation for more details on the
authentication process of each authentication plugin.

View File

@ -0,0 +1,48 @@
# GSSAPI Client Authenticator
GSSAPI is an authentication protocol that is commonly implemented with
Kerberos on Unix or Active Directory on Windows. This document describes
the GSSAPI authentication in MaxScale.
The _GSSAPIAuth_ module implements the client side authentication and the
_GSSAPIBackendAuth_ module implements the backend authentication.
## Authenticator options
The client side GSSAPIAuth authenticator supports one option, the service
principal name that MaxScale sends to the client. The backend authenticator
module has no options.
### `principal_name`
The service principal name to send to the client. This parameter is a
string parameter which is used by the client to request the token.
The default value for this option is _mariadb/localhost.localdomain_.
The parameter must be a valid GSSAPI principal name
e.g. `styx/pluto@EXAMPLE.COM`. The principal name can also be defined
without the realm part in which case the default realm will be used.
## Implementation details
Read the [Authentication Modules](Authentication-Modules.md) document for more
details on how authentication modules work in MaxScale.
### GSSAPI authentication
The GSSAPI plugin authentication starts when the database server sends the
service principal name in the AuthSwitchRequest packet. The principal name will
usually be in the form `service@REALM.COM`.
The client will then request a token for this service from the GSSAPI server and
send the token to the database server. The database server will verify the
authenticity of the token by contacting the GSSAPI server and if the token is
authentic, the server sends the final OK packet.
## Limitations
Client side GSSAPI authentication is only supported when the backend
connections use GSSAPI authentication.
See the [Limitations](../About/Limitations.md) document for more details.

View File

@ -0,0 +1,50 @@
# MySQL Authenticator
The _MySQLAuth_ and _MySQLBackendAuth_ modules implement the client and
backend authentication for the MySQL native password authentication. This
is the default authentication plugin used by both MariaDB and MySQL.
These modules are the default authenticators for all MySQL connections and
needs no further configuration to work.
## Authenticator options
The client authentication module, _MySQLAuth_, supports authenticator
options. The `authenticator_options` parameter is supported by listeners
and servers and expects a comma-separated list of key-value pairs. The
following options contain examples on how to define it.
### `cache_dir`
The location where the user credential cache is stored. The default value
for this is `<cache dir>/<service name>/<listener name>/cache/` where
`<cache dir>` by default is `/var/cache`.
If _cache_dir_ is defined, the user cache file is stored in `<cache
dir>/`. No additional directories are appended to the _cache_dir_ value.
Each listener has its own user cache where the user credential information
queried from the backends is stored. This information is used to
authenticate users if a connection to the backend servers can't be made.
```
authenticator_options=cache_dir=/tmp
```
### `inject_service_user`
Inject service credentials into the list of database users if loading of
users fails. This option takes a boolean value and it is enabled by
default.
When a connection to the backend database cannot be made, the service user
can be injected into the list of allowed users. This allows administrative
operations to be done via the SQL interface with modules that support it
e.g. the Binlogrouter and Maxinfo modules.
If users are loaded successfully, the service user credentials are _not_
injected into the list of users.
```
authenticator_options=inject_service_user=false
```

View File

@ -31,6 +31,7 @@
- [Debug and Diagnostic Support](Reference/Debug-And-Diagnostic-Support.md)
- [Routing Hints](Reference/Hint-Syntax.md)
- [MaxBinlogCheck](Reference/MaxBinlogCheck.md)
- [MaxScale REST API](REST-API/API.md)
## Tutorials
@ -106,6 +107,15 @@ Documentation for MaxScale protocol modules.
- [Change Data Capture (CDC) Protocol](Protocols/CDC.md)
- [Change Data Capture (CDC) Users](Protocols/CDC_users.md)
## Authenticators
A short description of the authentication module type can be found in the
[Authentication Modules](Authenticators/Authentication-Modules.md)
document.
- [MySQL Authenticator](Authenticators/MySQL-Authenticator.md)
- [GSSAPI Authenticator](Authenticators/GSSAPI-Authenticator.md)
## Utilities
- [RabbitMQ Consumer Client](Filters/RabbitMQ-Consumer-Client.md)

View File

@ -106,16 +106,17 @@ An integer value, using which the level of debug logging made by the cache
can be controlled. The value is actually a bitfield with different bits
denoting different logging.
* `0` (`0b0000`) No logging is made.
* `1` (`0b0001`) A matching rule is logged.
* `2` (`0b0010`) A non-matching rule is logged.
* `4` (`0b0100`) A decision to use data from the cache is logged.
* `8` (`0b1000`) A decision not to use data from the cache is logged.
* ` 0` (`0b00000`) No logging is made.
* ` 1` (`0b00001`) A matching rule is logged.
* ` 2` (`0b00010`) A non-matching rule is logged.
* ` 4` (`0b00100`) A decision to use data from the cache is logged.
* ` 8` (`0b01000`) A decision not to use data from the cache is logged.
* '16' (`0b10000`) Higher level decisions are logged.
Default is `0`. To log everything, give `debug` a value of `15`.
Default is `0`. To log everything, give `debug` a value of `31`.
```
debug=2
debug=31
```
# Rules

View File

@ -0,0 +1,70 @@
# Maxrows
## Overview
The maxrows filter is capable of restricting the amount of rows that a SELECT,
a prepared statement or stored procedure could return to the client application.
If a resultset from a backend server has more rows than the configured limit
or the resultset size exceeds the configured size,
an empty result will be sent to the client.
## Configuration
The maxrows filter is easy to configure and to add to any existing service.
```
[MaxRows]
type=filter
module=maxrows
[MaxRows Routing Service]
type=service
...
filters=maxrows
```
### Filter Parameters
The maxrows filter has no mandatory parameters.
Optional parameters are:
#### `max_resultset_rows`
Specifies the maximum number of rows a resultset can have in order to be returned
to the user.
If a resultset is larger than this an empty result will be sent instead.
```
max_resultset_rows=1000
```
Zero or a negative value is interpreted as no limitation.
The default value is `-1`.
#### `max_resultset_size`
Specifies the maximum size a resultset can have, measured in kibibytes,
in order to be sent to the client. A resultset larger than this, will
not be sent: an empty resultset will be sent instead.
```
max_resultset_size=128
```
The default value is 64.
#### `debug`
An integer value, using which the level of debug logging made by the maxrows
filter can be controlled. The value is actually a bitfield with different bits
denoting different logging.
* ` 0` (`0b00000`) No logging is made.
* ` 1` (`0b00001`) A decision to handle data form server is logged.
* ` 2` (`0b00010`) Reached max_resultset_rows or max_resultset_size is logged.
Default is `0`. To log everything, give `debug` a value of `3`.
```
debug=2
```

View File

@ -30,8 +30,10 @@ The QLA filter accepts the following options.
|ignorecase|Use case-insensitive matching |
|case |Use case-sensitive matching |
|extended |Use extended regular expression syntax (ERE)|
To use multiple filter options, list them in a comma-separated list.
|session_file| Use session-specific file (default)|
|unified_file| Use one file for all sessions|
|flush_writes| Flush after every write|
To use multiple filter options, list them in a comma-separated list. If no file settings are given, default will be used. Multiple file settings can be enabled simultaneously.
```
options=case,extended

View File

@ -41,16 +41,28 @@ connection failover| When a connection currently being used between MariaDB MaxS
## Configuration
The MariaDB MaxScale configuration is read from a file that MariaDB MaxScale will look for
in a number of places.
The MariaDB MaxScale configuration is read from a file that MariaDB MaxScale
will look for in the following places:
1. Location given with the --configdir=<path> command line argument
1. By default, the file `maxscale.cnf` in the directory `/etc`
1. The location given with the `--configdir=<path>` command line argument.
2. MariaDB MaxScale will look for a configuration file called `maxscale.cnf` in the directory `/etc/maxscale.cnf`
MariaDB MaxScale will further look for a directory with the same name as the
configuration file, followed by `.d` (for instance `/etc/maxscale.cnf.d`) and
recursively read all files, having a `.cnf` suffix, it finds in the directory
hierarchy. All other files will be ignored.
An explicit path to a configuration file can be passed by using the `-f` option to MariaDB MaxScale.
There are no restrictions on how different configuration sections are arranged,
but the strong suggestion is to place global settings into the configuration
file MariaDB MaxScale is invoked with, and then, if deemed necessary, create
separate configuration files for _servers_, _filters_, etc.
The configuration file itself is based on the ".ini" file format and consists of various sections that are used to build the configuration; these sections define services, servers, listeners, monitors and global settings. Parameters, which expect a comma-separated list of values can be defined on multiple lines. The following is an example of a multi-line definition.
The configuration file itself is based on the [.ini](https://en.wikipedia.org/wiki/INI_file)
file format and consists of various sections that are used to build the
configuration; these sections define services, servers, listeners, monitors and
global settings. Parameters, which expect a comma-separated list of values can
be defined on multiple lines. The following is an example of a multi-line
definition.
```
[MyService]
@ -247,7 +259,11 @@ To disable these messages use the value 0 and to enable them use the value 1.
#### `log_debug`
Enable or disable the logging of messages whose syslog priority is *debug*. This kind of messages are intended for development purposes and are disabled by default.
Enable or disable the logging of messages whose syslog priority is *debug*.
This kind of messages are intended for development purposes and are disabled
by default. Note that if MariaDB MaxScale has been built in release mode, then
debug messages are excluded from the build and this setting will not have any
effect.
```
# Valid options are:
@ -362,6 +378,16 @@ Configure the directory where the executable files reside. All internal processe
execdir=/usr/local/bin/
```
#### `persistdir`
Configure the directory where persisted configurations are stored. When a new
server is created via MaxAdmin, it will be stored in this directory. Do not use
or modify the contents of this directory, use _/etc/maxscale.cnf.d/_ instead.
```
persistdir=/var/lib/maxscale/maxscale.cnf.d/
```
#### `language`
Set the folder where the errmsg.sys file is located in. MariaDB MaxScale will look for the errmsg.sys file installed with MariaDB MaxScale from this folder.
@ -435,6 +461,12 @@ router_options=master,slave
A more complete description of router options and what is available for a given router is included with the documentation of the router itself.
#### `router_options`
Option string given to the router module. The value of this parameter
should be a comma-separated list of key-value pairs. See router specific
documentation for more details.
#### `filters`
The filters option allow a set of filters to be defined for a service; requests from the client are passed through these filters before being sent to the router for dispatch to the backend server. The filters parameter takes one or more filter names, as defined within the filter definition section of the configuration file. Multiple filters are separated using the | character.
@ -833,6 +865,18 @@ The `socket` option may be included in a listener definition, this configures th
If a socket option and an address option is given then the listener will listen on both the specific IP address and the Unix socket.
#### `authenticator`
The authenticator module to use. Each protocol module defines a default
authentication module which is used if no `authenticator` parameter is
found from the configuration.
#### `authenticator_options`
Option string given to the authenticator module. The value of this
parameter should be a comma-separated list of key-value pairs. See
authenticator specific documentation for more details.
#### Available Protocols
The protocols supported by MariaDB MaxScale are implemented as external modules that are loaded dynamically into the MariaDB MaxScale core. They allow MariaDB MaxScale to communicate in various protocols both on the client side and the backend side. Each of the protocols can be either a client protocol or a backend protocol. Client protocols are used for client-MariaDB MaxScale communication and backend protocols are for MariaDB MaxScale-database communication.

View File

@ -64,7 +64,16 @@ use_priority=true
## Interaction with Server Priorities
If the `use_priority` option is set and a server is configured with the `priority=<int>` parameter, galeramon will use that as the basis on which the master node is chosen. This requires the `disable_master_role_setting` to be undefined or disabled. The server with the lowest value in `priority` will be chosen as the master node when a replacement Galera node is promoted to a master server inside MaxScale.
If the `use_priority` option is set and a server is configured with the
`priority=<int>` parameter, galeramon will use that as the basis on which the
master node is chosen. This requires the `disable_master_role_setting` to be
undefined or disabled. The server with the lowest positive value in _priority_
will be chosen as the master node when a replacement Galera node is promoted to
a master server inside MaxScale.
Nodes with a non-positive value (_priority_ <= 0) will never be chosen as the master. This allows
you to mark some servers as permanent slaves by assigning a non-positive value
into _priority_.
Here is an example with two servers.
@ -86,8 +95,21 @@ type=server
address=192.168.122.103
port=3306
priority=2
[node-4]
type=server
address=192.168.122.104
port=3306
priority=0
```
In this example `node-1` is always used as the master if available. If `node-1` is not available, then the next node with the highest priority rank is used. In this case it would be `node-3`. If both `node-1` and `node-3` were down, then `node-2` would be used. Nodes without priority are considered as having the lowest priority rank and will be used only if all nodes with priority ranks are not available.
In this example `node-1` is always used as the master if available. If `node-1`
is not available, then the next node with the highest priority rank is used. In
this case it would be `node-3`. If both `node-1` and `node-3` were down, then
`node-2` would be used. Because `node-4` has a value of 0 in _priority_, it will
never be the master. Nodes without priority are considered as having the lowest
priority rank and will be used only if all nodes with priority ranks are not
available.
With priority ranks you can control the order in which MaxScale chooses the master node. This will allow for a controlled failure and replacement of nodes.
With priority ranks you can control the order in which MaxScale chooses the
master node. This will allow for a controlled failure and replacement of nodes.

View File

@ -0,0 +1,453 @@
# REST API design document
This document describes the version 1 of the MaxScale REST API.
## Table of Contents
- [HTTP Headers](#http-headers)
- [Request Headers](#request-headers)
- [Response Headers](#response-headers)
- [Response Codes](#response-codes)
- [2xx Success](#2xx-success)
- [3xx Redirection](#3xx-redirection)
- [4xx Client Error](#4xx-client-error)
- [5xx Server Error](#5xx-server-error)
- [Resources](#resources)
- [Common Request Parameter](#common-request-parameters)
## HTTP Headers
### Request Headers
REST makes use of the HTTP protocols in its aim to provide a natural way to
understand the workings of an API. The following request headers are understood
by this API.
#### Accept-Charset
Acceptable character sets.
#### Authorization
Credentials for authentication.
#### Content-Type
All PUT and POST requests must use the `Content-Type: application/json` media
type and the request body must be a valid JSON representation of a resource. All
PATCH requests must use the `Content-Type: application/json-patch` media type
and the request body must be a valid JSON Patch document which is applied to the
resource. Curently, only _add_, _remove_, _replace_ and _test_ operations are
supported.
Read the [JSON Patch](https://tools.ietf.org/html/draft-ietf-appsawg-json-patch-08)
draft for more details on how to use it with PATCH.
#### Date
This header is required and should be in the RFC 1123 standard form, e.g. Mon,
18 Nov 2013 08:14:29 -0600. Please note that the date must be in English. It
will be checked by the API for being close to the current date and time.
#### Host
The address and port of the server.
#### If-Match
The request is performed only if the provided ETag value matches the one on the
server. This field should be used with PUT requests to prevent concurrent
updates to the same resource.
The value of this header must be a value from the `ETag` header retrieved from
the same resource at an earlier point in time.
#### If-Modified-Since
If the content has not changed the server responds with a 304 status code. If
the content has changed the server responds with a 200 status code and the
requested resource.
The value of this header must be a date value in the
["HTTP-date"](https://www.ietf.org/rfc/rfc2822.txt) format.
#### If-None-Match
If the content has not changed the server responds with a 304 status code. If
the content has changed the server responds with a 200 status code and the
requested resource.
The value of this header must be a value from the `ETag` header retrieved from
the same resource at an earlier point in time.
#### If-Unmodified-Since
The request is performed only if the requested resource has not been modified
since the provided date.
The value of this header must be a date value in the
["HTTP-date"](https://www.ietf.org/rfc/rfc2822.txt) format.
#### X-HTTP-Method-Override
Some clients only support GET and PUT requests. By providing the string value of
the intended method in the `X-HTTP-Method-Override` header, a client can perform
a POST, PATCH or DELETE request with the PUT method
(e.g. `X-HTTP-Method-Override: PATCH`).
_TODO: Add API version header?_
### Response Headers
#### Allow
All resources return the Allow header with the supported HTTP methods. For
example the resource `/service` will always return the `Accept: GET, PATCH, PUT`
header.
#### Accept-Patch
All PATCH capable resources return the `Accept-Patch: application/json-patch`
header.
#### Date
Returns the RFC 1123 standard form date when the reply was sent. The date is in
English and it uses the server's local timezone.
#### ETag
An identifier for a specific version of a resource. The value of this header
changes whenever a resource is modified.
When the client sends the `If-Match` or `If-None-Match` header, the provided
value should be the value of the `ETag` header of an earlier GET.
#### Last-Modified
The date when the resource was last modified in "HTTP-date" format.
#### Location
If an out of date resource location is requested, a HTTP return code of 3XX with
the `Location` header is returned. The value of the header contains the new
location of the requested resource as a relative URI.
#### WWW-Authenticate
The requested authentication method. For example, `WWW-Authenticate: Basic`
would require basic HTTP authentication.
## Response Codes
Every HTTP response starts with a line with a return code which indicates the
outcome of the request. The API uses some of the standard HTTP values:
### 2xx Success
- 200 OK
- Successful HTTP requests, response has a body.
- 201 Created
- A new resource was created.
- 202 Accepted
- The request has been accepted for processing, but the processing has not
been completed.
- 204 No Content
- Successful HTTP requests, response has no body.
### 3xx Redirection
This class of status code indicates the client must take additional action to
complete the request.
- 301 Moved Permanently
- This and all future requests should be directed to the given URI.
- 302 Found
- The response to the request can be found under another URI using the same
method as in the original request.
- 303 See Other
- The response to the request can be found under another URI using a GET
method.
- 304 Not Modified
- Indicates that the resource has not been modified since the version
specified by the request headers If-Modified-Since or If-None-Match.
- 307 Temporary Redirect
- The request should be repeated with another URI but future requests should
use the original URI.
- 308 Permanent Redirect
- The request and all future requests should be repeated using another URI.
### 4xx Client Error
The 4xx class of status code is when the client seems to have erred. Except when
responding to a HEAD request, the body of the response contains a JSON
representation of the error in the following format.
```
{
"error": "Method not supported",
"description": "The `/service` resource does not support POST."
}
```
The _error_ field contains a short error description and the _description_ field
contains a more detailed version of the error message.
- 400 Bad Request
- The server cannot or will not process the request due to client error.
- 401 Unauthorized
- Authentication is required. The response includes a WWW-Authenticate header.
- 403 Forbidden
- The request was a valid request, but the client does not have the necessary
permissions for the resource.
- 404 Not Found
- The requested resource could not be found.
- 405 Method Not Allowed
- A request method is not supported for the requested resource.
- 406 Not Acceptable
- The requested resource is capable of generating only content not acceptable
according to the Accept headers sent in the request.
- 409 Conflict
- Indicates that the request could not be processed because of conflict in the
request, such as an edit conflict be tween multiple simultaneous updates.
- 411 Length Required
- The request did not specify the length of its content, which is required by
the requested resource.
- 412 Precondition Failed
- The server does not meet one of the preconditions that the requester put on
the request.
- 413 Payload Too Large
- The request is larger than the server is willing or able to process.
- 414 URI Too Long
- The URI provided was too long for the server to process.
- 415 Unsupported Media Type
- The request entity has a media type which the server or resource does not
support.
- 422 Unprocessable Entity
- The request was well-formed but was unable to be followed due to semantic
errors.
- 423 Locked
- The resource that is being accessed is locked.
- 428 Precondition Required
- The origin server requires the request to be conditional. This error code is
returned when none of the `Modified-Since` or `Match` type headers are used.
- 431 Request Header Fields Too Large
- The server is unwilling to process the request because either an individual
header field, or all the header fields collectively, are too large.
### 5xx Server Error
The server failed to fulfill an apparently valid request.
Response status codes beginning with the digit "5" indicate cases in which the
server is aware that it has encountered an error or is otherwise incapable of
performing the request. Except when responding to a HEAD request, the server
includes an entity containing an explanation of the error situation.
```
{
"error": "Log rotation failed",
"description": "Failed to rotate log files: 13, Permission denied"
}
```
The _error_ field contains a short error description and the _description_ field
contains a more detailed version of the error message.
- 500 Internal Server Error
- A generic error message, given when an unexpected condition was encountered
and no more specific message is suitable.
- 501 Not Implemented
- The server either does not recognize the request method, or it lacks the
ability to fulfill the request.
- 502 Bad Gateway
- The server was acting as a gateway or proxy and received an invalid response
from the upstream server.
- 503 Service Unavailable
- The server is currently unavailable (because it is overloaded or down for
maintenance). Generally, this is a temporary state.
- 504 Gateway Timeout
- The server was acting as a gateway or proxy and did not receive a timely
response from the upstream server.
- 505 HTTP Version Not Supported
- The server does not support the HTTP protocol version used in the request.
- 506 Variant Also Negotiates
- Transparent content negotiation for the request results in a circular
reference.
- 507 Insufficient Storage
- The server is unable to store the representation needed to complete the
request.
- 508 Loop Detected
- The server detected an infinite loop while processing the request (sent in
lieu of 208 Already Reported).
- 510 Not Extended
- Further extensions to the request are required for the server to fulfil it.
### Response Headers Reserved for Future Use
The following response headers are not currently in use. Future versions of the
API could return them.
- 206 Partial Content
- The server is delivering only part of the resource (byte serving) due to a
range header sent by the client.
- 300 Multiple Choices
- Indicates multiple options for the resource from which the client may choose
(via agent-driven content negotiation).
- 407 Proxy Authentication Required
- The client must first authenticate itself with the proxy.
- 408 Request Timeout
- The server timed out waiting for the request. According to HTTP
specifications: "The client did not produce a request within the time that
the server was prepared to wait. The client MAY repeat the request without
modifications at any later time."
- 410 Gone
- Indicates that the resource requested is no longer available and will not be
available again.
- 416 Range Not Satisfiable
- The client has asked for a portion of the file (byte serving), but the
server cannot supply that portion.
- 417 Expectation Failed
- The server cannot meet the requirements of the Expect request-header field.
- 421 Misdirected Request
- The request was directed at a server that is not able to produce a response.
- 424 Failed Dependency
- The request failed due to failure of a previous request.
- 426 Upgrade Required
- The client should switch to a different protocol such as TLS/1.0, given in
the Upgrade header field.
- 429 Too Many Requests
- The user has sent too many requests in a given amount of time. Intended for
use with rate-limiting schemes.
## Resources
The MaxScale REST API provides the following resources.
- [/maxscale](Resources-MaxScale.md)
- [/services](Resources-Service.md)
- [/servers](Resources-Server.md)
- [/filters](Resources-Filter.md)
- [/monitors](Resources-Monitor.md)
- [/sessions](Resources-Session.md)
- [/users](Resources-User.md)
## Common Request Parameters
Most of the resources that support GET also support the following
parameters. See the resource documentation for a list of supported request
parameters.
- `fields`
- A list of fields to return.
This allows the returned object to be filtered so that only needed
parts are returned. The value of this parameter is a comma separated
list of fields to return.
For example, the parameter `?fields=id,name` would return object which
would only contain the _id_ and _name_ fields.
- `range`
- Return a subset of the object array.
The value of this parameter is the range of objects to return given as
a inclusive range separated by a hyphen. If the size of the array is
less than the end of the range, only the objects between the requested
start of the range and the actual end of the array are returned. This
means that
For example, the parameter `?range=10-20` would return objects 10
through 20 from the object array if the actual size of the original
array is greater than or equal to 20.

View File

@ -0,0 +1,151 @@
# Filter Resource
A filter resource represents an instance of a filter inside MaxScale. Multiple
services can use the same filter and a single service can use multiple filters.
## Resource Operations
### Get a filter
Get a single filter. The _:name_ in the URI must be a valid filter name with all
whitespace replaced with hyphens. The filter names are case-insensitive.
```
GET /filters/:name
```
#### Response
```
Status: 200 OK
{
"name": "Query Logging Filter",
"module": "qlafilter",
"parameters": {
"filebase": {
"value": "/var/log/maxscale/qla/log.",
"configurable": false
},
"match": {
"value": "select.*from.*t1",
"configurable": true
}
},
"services": [
"/services/my-service",
"/services/my-second-service"
]
}
```
#### Supported Request Parameter
- `fields`
### Get all filters
Get all filters.
```
GET /filters
```
#### Response
```
Status: 200 OK
[
{
"name": "Query Logging Filter",
"module": "qlafilter",
"parameters": {
"filebase": {
"value": "/var/log/maxscale/qla/log.",
"configurable": false
},
"match": {
"value": "select.*from.*t1",
"configurable": true
}
},
"services": [
"/services/my-service",
"/services/my-second-service
]
},
{
"name": "DBFW Filter",
"module": "dbfwfilter",
"parameters": {
{
"name": "rules",
"value": "/etc/maxscale-rules",
"configurable": false
}
},
"services": [
"/services/my-second-service
]
}
]
```
#### Supported Request Parameter
- `fields`
- `range`
### Update a filter
**Note**: The update mechanisms described here are provisional and most likely
will change in the future. This description is only for design purposes and
does not yet work.
Partially update a filter. The _:name_ in the URI must map to a filter name
and the request body must be a valid JSON Patch document which is applied to the
resource.
```
PATCH /filter/:name
```
### Modifiable Fields
|Field |Type |Description |
|------------|-------|---------------------------------|
|parameters |object |Module specific filter parameters|
```
[
{ "op": "replace", "path": "/parameters/rules/value", "value": "/etc/new-rules" },
{ "op": "add", "path": "/parameters/action/value", "value": "allow" }
]
```
#### Response
Response contains the modified resource.
```
Status: 200 OK
{
"name": "DBFW Filter",
"module": "dbfwfilter",
"parameters": {
"rules": {
"value": "/etc/new-rules",
"configurable": false
},
"action": {
"value": "allow",
"configurable": true
}
}
"services": [
"/services/my-second-service"
]
}
```

View File

@ -0,0 +1,216 @@
# MaxScale Resource
The MaxScale resource represents a MaxScale instance and it is the core on top
of which the modules build upon.
## Resource Operations
## Get global information
Retrieve global information about a MaxScale instance. This includes various
file locations, configuration options and version information.
```
GET /maxscale
```
#### Response
```
Status: 200 OK
{
"config": "/etc/maxscale.cnf",
"cachedir": "/var/cache/maxscale/",
"datadir": "/var/lib/maxscale/"
"libdir": "/usr/lib64/maxscale/",
"piddir": "/var/run/maxscale/",
"execdir": "/usr/bin/",
"languagedir": "/var/lib/maxscale/",
"user": "maxscale",
"threads": 4,
"version": "2.1.0",
"commit": "12e7f17eb361e353f7ac413b8b4274badb41b559"
"started": "Wed, 31 Aug 2016 23:29:26 +0300"
}
```
#### Supported Request Parameter
- `fields`
## Get thread information
Get detailed information and statistics about the threads.
```
GET /maxscale/threads
```
#### Response
```
Status: 200 OK
{
"load_average": {
"historic": 1.05,
"current": 1.00,
"1min": 0.00,
"5min": 0.00,
"15min": 0.00
},
"threads": [
{
"id": 0,
"state": "processing",
"file_descriptors": 1,
"event": [
"in",
"out"
],
"run_time": 300
},
{
"id": 1,
"state": "polling",
"file_descriptors": 0,
"event": [],
"run_time": 0
}
]
}
```
#### Supported Request Parameter
- `fields`
## Get logging information
Get information about the current state of logging, enabled log files and the
location where the log files are stored.
```
GET /maxscale/logs
```
#### Response
```
Status: 200 OK
{
"logdir": "/var/log/maxscale/",
"maxlog": true,
"syslog": false,
"log_levels": {
"error": true,
"warning": true,
"notice": true,
"info": false,
"debug": false
},
"log_augmentation": {
"function": true
},
"log_throttling": {
"limit": 8,
"window": 2000,
"suppression": 10000
},
"last_flushed": "Wed, 31 Aug 2016 23:29:26 +0300"
}
```
#### Supported Request Parameter
- `fields`
## Flush and rotate log files
Flushes any pending messages to disk and reopens the log files. The body of the
message is ignored.
```
POST /maxscale/logs/flush
```
#### Response
```
Status: 204 No Content
```
## Get task schedule
Retrieve all pending tasks that are queued for execution.
```
GET /maxscale/tasks
```
#### Response
```
Status: 200 OK
[
{
"name": "Load Average",
"type": "repeated",
"frequency": 10,
"next_due": "Fri Sep 9 14:12:37 2016"
}
}
```
#### Supported Request Parameter
- `fields`
## Get loaded modules
Retrieve information about all loaded modules. This includes version, API and
maturity information.
```
GET /maxscale/modules
```
#### Response
```
Status: 200 OK
[
{
"name": "MySQLBackend",
"type": "Protocol",
"version": "V2.0.0",
"api_version": "1.1.0",
"maturity": "GA"
},
{
"name": "qlafilter",
"type": "Filter",
"version": "V1.1.1",
"api_version": "1.1.0",
"maturity": "GA"
},
{
"name": "readwritesplit",
"type": "Router",
"version": "V1.1.0",
"api_version": "1.0.0",
"maturity": "GA"
}
}
```
#### Supported Request Parameter
- `fields`
- `range`
TODO: Add epoll statistics and rest of the supported methods.

View File

@ -0,0 +1,176 @@
# Monitor Resource
A monitor resource represents a monitor inside MaxScale that monitors one or
more servers.
## Resource Operations
### Get a monitor
Get a single monitor. The _:name_ in the URI must be a valid monitor name with
all whitespace replaced with hyphens. The monitor names are case-insensitive.
```
GET /monitors/:name
```
#### Response
```
Status: 200 OK
{
"name": "MySQL Monitor",
"module": "mysqlmon",
"state": "started",
"monitor_interval": 2500,
"connect_timeout": 5,
"read_timeout": 2,
"write_timeout": 3,
"servers": [
"/servers/db-serv-1",
"/servers/db-serv-2",
"/servers/db-serv-3"
]
}
```
#### Supported Request Parameter
- `fields`
### Get all monitors
Get all monitors.
```
GET /monitors
```
#### Response
```
Status: 200 OK
[
{
"name": "MySQL Monitor",
"module": "mysqlmon",
"state": "started",
"monitor_interval": 2500,
"connect_timeout": 5,
"read_timeout": 2,
"write_timeout": 3,
"servers": [
"/servers/db-serv-1",
"/servers/db-serv-2",
"/servers/db-serv-3"
]
},
{
"name": "Galera Monitor",
"module": "galeramon",
"state": "started",
"monitor_interval": 5000,
"connect_timeout": 10,
"read_timeout": 5,
"write_timeout": 5,
"servers": [
"/servers/db-galera-1",
"/servers/db-galera-2",
"/servers/db-galera-3"
]
}
]
```
#### Supported Request Parameter
- `fields`
- `range`
### Stop a monitor
Stops a started monitor.
```
PUT /monitor/:name/stop
```
#### Response
```
Status: 204 No Content
```
### Start a monitor
Starts a stopped monitor.
```
PUT /monitor/:name/start
```
#### Response
```
Status: 204 No Content
```
### Update a monitor
**Note**: The update mechanisms described here are provisional and most likely
will change in the future. This description is only for design purposes and
does not yet work.
Partially update a monitor. The _:name_ in the URI must map to a monitor name
and the request body must be a valid JSON Patch document which is applied to the
resource.
```
PATCH /monitor/:name
```
### Modifiable Fields
The following values can be modified with the PATCH method.
|Field |Type |Description |
|-----------------|------------|---------------------------------------------------|
|servers |string array|Servers monitored by this monitor |
|monitor_interval |number |Monitoring interval in milliseconds |
|connect_timeout |number |Connection timeout in seconds |
|read_timeout |number |Read timeout in seconds |
|write_timeout |number |Write timeout in seconds |
```
[
{ "op": "remove", "path": "/servers/0" },
{ "op": "replace", "path": "/monitor_interval", "value": 2000 },
{ "op": "replace", "path": "/connect_timeout", "value": 2 },
{ "op": "replace", "path": "/read_timeout", "value": 2 },
{ "op": "replace", "path": "/write_timeout", "value": 2 }
]
```
#### Response
Response contains the modified resource.
```
Status: 200 OK
{
"name": "MySQL Monitor",
"module": "mysqlmon",
"servers": [
"/servers/db-serv-2",
"/servers/db-serv-3"
],
"state": "started",
"monitor_interval": 2000,
"connect_timeout": 2,
"read_timeout": 2,
"write_timeout": 2
}
```

View File

@ -0,0 +1,207 @@
# Server Resource
A server resource represents a backend database server.
## Resource Operations
### Get a server
Get a single server. The _:name_ in the URI must be a valid server name with all
whitespace replaced with hyphens. The server names are case-insensitive.
```
GET /servers/:name
```
#### Response
```
Status: 200 OK
{
"name": "db-serv-1",
"address": "192.168.121.58",
"port": 3306,
"protocol": "MySQLBackend",
"status": [
"master",
"running"
],
"parameters": {
"report_weight": 10,
"app_weight": 2
}
}
```
**Note**: The _parameters_ field contains all custom parameters for
servers, including the server weighting parameters.
#### Supported Request Parameter
- `fields`
### Get all servers
```
GET /servers
```
#### Response
```
Status: 200 OK
[
{
"name": "db-serv-1",
"address": "192.168.121.58",
"port": 3306,
"protocol": "MySQLBackend",
"status": [
"master",
"running"
],
"parameters": {
"report_weight": 10,
"app_weight": 2
}
},
{
"name": "db-serv-2",
"address": "192.168.121.175",
"port": 3306,
"status": [
"slave",
"running"
],
"protocol": "MySQLBackend",
"parameters": {
"app_weight": 6
}
}
]
```
#### Supported Request Parameter
- `fields`
- `range`
### Update a server
**Note**: The update mechanisms described here are provisional and most likely
will change in the future. This description is only for design purposes and
does not yet work.
Partially update a server. The _:name_ in the URI must map to a server name with
all whitespace replaced with hyphens and the request body must be a valid JSON
Patch document which is applied to the resource.
```
PATCH /servers/:name
```
### Modifiable Fields
|Field |Type |Description |
|-----------|------------|-----------------------------------------------------------------------------|
|address |string |Server address |
|port |number |Server port |
|parameters |object |Server extra parameters |
|state |string array|Server state, array of `master`, `slave`, `synced`, `running` or `maintenance`. An empty array is interpreted as a server that is down.|
```
{
{ "op": "replace", "path": "/address", "value": "192.168.0.100" },
{ "op": "replace", "path": "/port", "value": 4006 },
{ "op": "add", "path": "/state/0", "value": "maintenance" },
{ "op": "replace", "path": "/parameters/report_weight", "value": 1 }
}
```
#### Response
Response contains the modified resource.
```
Status: 200 OK
{
"name": "db-serv-1",
"protocol": "MySQLBackend",
"address": "192.168.0.100",
"port": 4006,
"state": [
"maintenance",
"running"
],
"parameters": {
"report_weight": 1,
"app_weight": 2
}
}
```
### Get all connections to a server
Get all connections that are connected to a server.
```
GET /servers/:name/connections
```
#### Response
```
Status: 200 OK
[
{
"state": "DCB in the polling loop",
"role": "Backend Request Handler",
"server": "/servers/db-serv-01",
"service": "/services/my-service",
"statistics": {
"reads": 2197
"writes": 1562
"buffered_writes": 0
"high_water_events": 0
"low_water_events": 0
}
},
{
"state": "DCB in the polling loop",
"role": "Backend Request Handler",
"server": "/servers/db-serv-01",
"service": "/services/my-second-service"
"statistics": {
"reads": 0
"writes": 0
"buffered_writes": 0
"high_water_events": 0
"low_water_events": 0
}
}
]
```
#### Supported Request Parameter
- `fields`
- `range`
### Close all connections to a server
Close all connections to a particular server. This will forcefully close all
backend connections.
```
DELETE /servers/:name/connections
```
#### Response
```
Status: 204 No Content
```

View File

@ -0,0 +1,272 @@
# Service Resource
A service resource represents a service inside MaxScale. A service is a
collection of network listeners, filters, a router and a set of backend servers.
## Resource Operations
### Get a service
Get a single service. The _:name_ in the URI must be a valid service name with
all whitespace replaced with hyphens. The service names are case-insensitive.
```
GET /services/:name
```
#### Response
```
Status: 200 OK
{
"name": "My Service",
"router": "readwritesplit",
"router_options": {
"disable_sescmd_history": "true"
},
"state": "started",
"total_connections": 10,
"current_connections": 2,
"started": "2016-08-29T12:52:31+03:00",
"filters": [
"/filters/Query-Logging-Filter"
],
"servers": [
"/servers/db-serv-1",
"/servers/db-serv-2",
"/servers/db-serv-3"
]
}
```
#### Supported Request Parameter
- `fields`
### Get all services
Get all services.
```
GET /services
```
#### Response
```
Status: 200 OK
[
{
"name": "My Service",
"router": "readwritesplit",
"router_options": {
"disable_sescmd_history": "true"
},
"state": "started",
"total_connections": 10,
"current_connections": 2,
"started": "2016-08-29T12:52:31+03:00",
"filters": [
"/filters/Query-Logging-Filter"
],
"servers": [
"/servers/db-serv-1",
"/servers/db-serv-2",
"/servers/db-serv-3"
]
},
{
"name": "My Second Service",
"router": "readconnroute",
"router_options": {
"type": "master"
},
"state": "started",
"total_connections": 10,
"current_connections": 2,
"started": "2016-08-29T12:52:31+03:00",
"servers": [
"/servers/db-serv-1",
"/servers/db-serv-2"
]
}
]
```
#### Supported Request Parameter
- `fields`
- `range`
### Get service listeners
Get the listeners of a service. The _:name_ in the URI must be a valid service
name with all whitespace replaced with hyphens. The service names are
case-insensitive.
```
GET /services/:name/listeners
```
#### Response
```
Status: 200 OK
[
{
"name": "My Listener",
"protocol": "MySQLClient",
"address": "0.0.0.0",
"port": 4006
},
{
"name": "My SSL Listener",
"protocol": "MySQLClient",
"address": "127.0.0.1",
"port": 4006,
"ssl": "required",
"ssl_cert": "/home/markusjm/newcerts/server-cert.pem",
"ssl_key": "/home/markusjm/newcerts/server-key.pem",
"ssl_ca_cert": "/home/markusjm/newcerts/ca.pem"
}
]
```
#### Supported Request Parameter
- `fields`
- `range`
### Update a service
**Note**: The update mechanisms described here are provisional and most likely
will change in the future. This description is only for design purposes and
does not yet work.
Partially update a service. The _:name_ in the URI must map to a service name
and the request body must be a valid JSON Patch document which is applied to the
resource.
```
PATCH /services/:name
```
### Modifiable Fields
|Field |Type |Description |
|--------------|------------|---------------------------------------------------|
|servers |string array|Servers used by this service, must be relative links to existing server resources|
|router_options|object |Router specific options|
|filters |string array|Service filters, configured in the same order they are declared in the array (`filters[0]` => first filter, `filters[1]` => second filter)|
|user |string |The username for the service user|
|password |string |The password for the service user|
|root_user |boolean |Allow root user to connect via this service|
|version_string|string |Custom version string given to connecting clients|
|weightby |string |Name of a server weigting parameter which is used for connection weighting|
|connection_timeout|number |Client idle timeout in seconds|
|max_connection|number |Maximum number of allowed connections|
|strip_db_esc|boolean |Strip escape characters from default database name|
```
[
{ "op": "replace", "path": "/servers", "value": ["/servers/db-serv-2","/servers/db-serv-3"] },
{ "op": "add", "path": "/router_options/master_failover_mode", "value": "fail_on_write" },
{ "op": "remove", "path": "/filters" }
]
```
#### Response
Response contains the modified resource.
```
Status: 200 OK
{
"name": "My Service",
"router": "readwritesplit",
"router_options": {
"disable_sescmd_history=false",
"master_failover_mode": "fail_on_write"
}
"state": "started",
"total_connections": 10,
"current_connections": 2,
"started": "2016-08-29T12:52:31+03:00",
"servers": [
"/servers/db-serv-2",
"/servers/db-serv-3"
]
}
```
### Stop a service
Stops a started service.
```
PUT /service/:name/stop
```
#### Response
```
Status: 204 No Content
```
### Start a service
Starts a stopped service.
```
PUT /service/:name/start
```
#### Response
```
Status: 204 No Content
```
### Get all sessions for a service
Get all sessions for a particular service.
```
GET /services/:name/sessions
```
#### Response
Relative links to all sessions for this service.
```
Status: 200 OK
[
"/sessions/1",
"/sessions/2"
]
```
#### Supported Request Parameter
- `range`
### Close all sessions for a service
Close all sessions for a particular service. This will forcefully close all
client connections and any backend connections they have made.
```
DELETE /services/:name/sessions
```
#### Response
```
Status: 204 No Content
```

View File

@ -0,0 +1,138 @@
# Session Resource
A session consists of a client connection, any number of related backend
connections, a router module session and possibly filter module sessions. Each
session is created on a service and a service can have multiple sessions.
## Resource Operations
### Get a session
Get a single session. _:id_ must be a valid session ID.
```
GET /sessions/:id
```
#### Response
```
Status: 200 OK
{
"id": 1,
"state": "Session ready for routing",
"user": "jdoe",
"address": "192.168.0.200",
"service": "/services/my-service",
"connected": "Wed Aug 31 03:03:12 2016",
"idle": 260
}
```
#### Supported Request Parameter
- `fields`
### Get all sessions
Get all sessions.
```
GET /sessions
```
#### Response
```
Status: 200 OK
[
{
"id": 1,
"state": "Session ready for routing",
"user": "jdoe",
"address": "192.168.0.200",
"service": "/services/My-Service",
"connected": "Wed Aug 31 03:03:12 2016",
"idle": 260
},
{
"id": 2,
"state": "Session ready for routing",
"user": "dba",
"address": "192.168.0.201",
"service": "/services/My-Service",
"connected": "Wed Aug 31 03:10:00 2016",
"idle": 1
}
]
```
#### Supported Request Parameter
- `fields`
- `range`
### Get all connections created by a session
Get all backend connections created by a session. _:id_ must be a valid session ID.
```
GET /sessions/:id/connections
```
#### Response
```
Status: 200 OK
[
{
"state": "DCB in the polling loop",
"role": "Backend Request Handler",
"server": "/servers/db-serv-01",
"service": "/services/my-service",
"statistics": {
"reads": 2197
"writes": 1562
"buffered_writes": 0
"high_water_events": 0
"low_water_events": 0
}
},
{
"state": "DCB in the polling loop",
"role": "Backend Request Handler",
"server": "/servers/db-serv-02",
"service": "/services/my-service",
"statistics": {
"reads": 0
"writes": 0
"buffered_writes": 0
"high_water_events": 0
"low_water_events": 0
}
}
]
```
#### Supported Request Parameter
- `fields`
- `range`
### Close a session
Close a session. This will forcefully close the client connection and any
backend connections.
```
DELETE /sessions/:id
```
#### Response
```
Status: 204 No Content
```

View File

@ -0,0 +1,81 @@
# Admin User Resource
Admin users represent administrative users that are able to query and change
MaxScale's configuration.
## Resource Operations
### Get all users
Get all administrative users.
```
GET /users
```
#### Response
```
Status: 200 OK
[
{
"name": "jdoe"
},
{
"name": "dba"
},
{
"name": "admin"
}
]
#### Supported Request Parameter
- `fields`
- `range`
### Create a user
Create a new administrative user.
```
PUT /users
```
### Modifiable Fields
All of the following fields need to be defined in the request body.
|Field |Type |Description |
|---------|------|-------------------------|
|name |string|Username, consisting of alphanumeric characters|
|password |string|Password for the new user|
```
{
"name": "foo",
"password": "bar"
}
```
#### Response
```
Status: 204 No Content
```
### Delete a user
Delete a user. The _:name_ part of the URI must be a valid user name. The user
names are case-insensitive.
```
DELETE /users/:name
```
#### Response
```
Status: 204 No Content
```

View File

@ -287,13 +287,22 @@ Then simply set this file to have execute permissions and it may be run like any
## The .maxadmin file
MaxAdmin supports a mechanism to set defaults for all the command line switches via a file in the home directory of the user. If a file named .maxadmin exists it will be read and parameters set according to the lies in this files. The parameter that can be set is: socket. An example of a .maxadmin file that will alter the default password and user name arguments would be
MaxAdmin supports a mechanism to set defaults for the command line switches via a file in the home directory of the user. If a file named `.maxadmin` exists, it will be read and parameters set according to the entries in that file.
This mechanism can be used to provide defaults to the command line options. If a command line option is provided, it will still override the value in the `.maxadmin` file.
The parameters than can be set are:
* `1.4`: _hostname_, _port_, _user_ and _passwd_
* `2.0.0` and `2.0.1`: _socket_
* `2.0.2` onwards: _socket_, _hostname_, _port_, _user_ and _passwd_ (and as synonym _password_)
An example of a `.maxadmin` file that will alter the default socket path is:
socket=/somepath/maxadmin.socket
This mechanism can be used to provide a means of passwords entry into maxadmin or to override any of the command line option defaults. If a command line option is given that will still override the value in the .maxadmin file.
Note that if in `2.0.2` or later, a value for _socket_ as well as any of the internet socket related options, such as _hostname_, is provided in `.maxadmin`, then _socket_ takes precedense. In that case, provide at least one internet socket related option on the command line to force MaxAdmin to use an internet socket and thus the internet socket related options from `.maxadmin`.
The .maxadmin file may be made read only to protect any passwords written to that file.
The `.maxadmin` file may be made read only to protect any passwords written to that file.
<a name="help"></a>
# Getting Help

View File

@ -8,7 +8,19 @@ release 2.0.X.
For any problems you encounter, please consider submitting a bug
report at [Jira](https://jira.mariadb.org).
## Changes Features
## Changed Features
### Configuration Files
From 2.1.0 onwards MariaDB MaxScale supports hierarchical configuration
files. When invoked with a configuration file, e.g. `maxscale.cnf`, MariaDB
MaxScale looks for a directory `maxscale.cnf.d` in the same directory as the
configuration file, and reads all `.cnf` files it finds in that directory
hierarchy. All other files will be ignored.
Please see the
[Configuration Guide](../Getting-Started/Configuration-Guide.md#configuration)
for details.
### Logging
@ -45,8 +57,25 @@ by default, is configured using the new global configuration entry `log_throttli
For more information about this configuration entry, please see
[Global Settings](../Getting-Started/Configuration-Guide.md#global-settings).
### Persistent Connections
Starting with the 2.1 version of MariaDB MaxScale, when a MySQL protocol
persistent connection is taken from the persistent connection pool, the
state of the MySQL session will be reset when the the connection is used
for the first time. This allows persistent connections to be used with no
functional limitations and makes them behave like normal MySQL
connections.
For more information about persistent connections, please read the
[Administration Tutorial](../Tutorials/Administration-Tutorial.md).
### User data cache
The user data cache stores the cached credentials that are used by some router
modules. In 2.1.0, the authenticator modules are responsible for the persisting
of the user data cache. Currently, only the MySQLAuth module implements user
data caching.
The user data loaded from the backend databases is now stored on a per listener
basis instead of a per service basis. In earlier versions, each service had its own
cache directory in `/var/cache/maxscale`. This directory contains cached user
@ -58,6 +87,23 @@ removed if they are no longer used by older versions of MaxScale.
## New Features
### Dynamic server configuration
MaxScale can now change the servers of a service or a monitor at run-time. New
servers can also be created and they will persisted even after a restart. The
following new commands were added to maxadmin, see output of `maxadmin help
<command>` for more details.
- `create server`: Creates a new server
- `destroy server`: Destroys a created server
- `add server`: Adds a server to a service or a monitor
- `remove server`: Removes a server from a service or a monitor
- `alter server`: Alter server configuration
- `alter monitor`: Alter monitor configuration
With these new features, you can start MaxScale without the servers and define
them later.
### Amazon RDS Aurora monitor
The new [Aurora Monitor](../Monitors/Aurora-Monitor.md) module allows monitoring

View File

@ -16,8 +16,21 @@ Binlogrouter is configured with a comma-separated list of key-value pairs. The f
### `binlogdir`
This parameter allows the location that MariaDB MaxScale uses to store binlog files to be set. If this parameter is not set to a directory name then MariaDB MaxScale will store the binlog files in the directory /var/cache/maxscale/<Service Name>.
In the binlog dir there is also the 'cache' directory that contains data retrieved from the master during registration phase and the master.ini file which contains the configuration of current configured master.
This parameter allows the location that MariaDB MaxScale uses to store binlog
files to be set. If this parameter is not set to a directory name then MariaDB
MaxScale will store the binlog files in the directory
/var/cache/maxscale/<Service Name>. In the binlog dir there is also the 'cache'
directory that contains data retrieved from the master during registration phase
and the master.ini file which contains the configuration of current configured
master.
From 2.1 onwards, the 'cache' directory is stored in the same location as other
user credential caches. This means that with the default options, the user
credential cache is stored in /var/cache/maxscale/<Service Name>/<Listener Name>/cache/.
Read the [MySQL Authenticator](../Authenticators/MySQL-Authenticator.md)
documentation for instructions on how to define a custom location for the user
cache.
### `uuid`
@ -52,6 +65,10 @@ This is the user name that MariaDB MaxScale uses when it connects to the master.
This user is the only one available for MySQL connection to MaxScale Binlog Server for administration when master connection is not done yet.
In MaxScale 2.1, the service user injection is done by the MySQLAuth
authenticator module. Read the [MySQL Authenticator](../Authenticators/MySQL-Authenticator.md)
documentation for more details.
The user that is used for replication, either defined using the user= option in the router options or using the username and password defined of the service must be granted replication privileges on the database server.
```

View File

@ -106,13 +106,22 @@ than `persistmaxtime` seconds. It was also be discarded if it has been disconne
by the back end server. Connections will be selected that match the user name and
protocol for the new request.
**Please note** that because persistent connections have previously been in use, they
may give a different environment from a fresh connection. For example, if the
previous use of the connection issued "use mydatabase" then this setting will be
carried over into the reuse of the same connection. For many applications this will
not be noticeable, since each request will assume that nothing has been set and
will issue fresh requests such as "use" to establish the desired configuration. In
exceptional cases this feature could be a problem.
Starting with the 2.1 version of MaxScale, when a MySQL protocol connection is
taken from the pool the backend protocol module resets the session state. This
allows persistent connections to be used with no functional limitations.
The session state is reset when the first outgoing network transmission is
done. This _lazy initialization_ of the persistent connections allows
MaxScale to take multiple new connections into use but only initialize the
ones that it actually needs.
**Please note** that in versions before 2.1 the persistent connections may give
a different environment when compared to a fresh connection. For example, if the
previous use of the connection issued a "USE mydatabase;" statement then this
setting will be carried over into the reuse of the same connection. For many
applications this will not be noticeable, since each request will assume that
nothing has been set and will issue fresh requests such as "USE" to establish
the desired configuration. In exceptional cases this feature could be a problem.
It is possible to have pools for as many servers as you wish, with configuration
values in each server section.

86
LICENSE-THIRDPARTY.TXT Normal file
View File

@ -0,0 +1,86 @@
The following software may be included by this product:
FindGSSAPI.cmake
Copyright (c) 2006, Pino Toscano, <toscano.pino@tiscali.it>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The "inih" library is distributed under the New BSD license:
Copyright (c) 2009, Brush Technology
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Brush Technology nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY BRUSH TECHNOLOGY ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL BRUSH TECHNOLOGY BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Release 10 of PCRE2 is distributed under the terms of the "BSD" licence.
THE "BSD" LICENCE
-----------------
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the University of Cambridge nor the names of any
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

View File

@ -1,8 +1,10 @@
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
add_library(maxavro maxavro.c maxavro_schema.c maxavro_record.c maxavro_file.c)
target_link_libraries(maxavro maxscale-common jansson)
if (AVRO_FOUND AND JANSSON_FOUND)
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
add_library(maxavro maxavro.c maxavro_schema.c maxavro_record.c maxavro_file.c)
target_link_libraries(maxavro maxscale-common jansson)
add_executable(maxavrocheck maxavrocheck.c)
target_link_libraries(maxavrocheck maxavro)
install_executable(maxavrocheck core)
add_subdirectory(test)
add_executable(maxavrocheck maxavrocheck.c)
target_link_libraries(maxavrocheck maxavro)
install_executable(maxavrocheck core)
add_subdirectory(test)
endif()

View File

@ -15,7 +15,7 @@
#include <string.h>
#include <stdbool.h>
#include "maxavro.h"
#include <log_manager.h>
#include <maxscale/log_manager.h>
#include <errno.h>
/** Maximum byte size of an integer value */

View File

@ -18,7 +18,7 @@
#include <stdint.h>
#include <stdbool.h>
#include <jansson.h>
#include <buffer.h>
#include <maxscale/buffer.h>
/** File magic and sync marker sizes block sizes */
#define AVRO_MAGIC_SIZE 4

View File

@ -14,7 +14,7 @@
#include "maxavro.h"
#include <errno.h>
#include <string.h>
#include <log_manager.h>
#include <maxscale/log_manager.h>
static bool maxavro_read_sync(FILE *file, uint8_t* sync)

View File

@ -11,11 +11,11 @@
* Public License.
*/
#include <maxscale/cdefs.h>
#include "maxavro.h"
#include "skygw_utils.h"
#include <string.h>
#include <skygw_debug.h>
#include <log_manager.h>
#include <maxscale/debug.h>
#include <maxscale/log_manager.h>
#include <errno.h>
bool maxavro_read_datablock_start(MAXAVRO_FILE *file);
@ -324,7 +324,7 @@ GWBUF* maxavro_record_read_binary(MAXAVRO_FILE *file)
{
if (ferror(file->file))
{
char err[STRERROR_BUFLEN];
char err[MXS_STRERROR_BUFLEN];
MXS_ERROR("Failed to read %ld bytes: %d, %s", data_size, errno,
strerror_r(errno, err, sizeof(err)));
file->last_error = MAXAVRO_ERR_IO;

View File

@ -14,8 +14,8 @@
#include "maxavro.h"
#include <jansson.h>
#include <string.h>
#include <skygw_debug.h>
#include <log_manager.h>
#include <maxscale/debug.h>
#include <maxscale/log_manager.h>
static const MAXAVRO_SCHEMA_FIELD types[MAXAVRO_TYPE_MAX] =
{

View File

@ -15,7 +15,7 @@
#include <string.h>
#include <stdbool.h>
#include "maxavro.h"
#include <log_manager.h>
#include <maxscale/log_manager.h>
#include <errno.h>
/**

View File

@ -23,7 +23,7 @@
#include <errno.h>
#include <limits.h>
#include <getopt.h>
#include <skygw_debug.h>
#include <maxscale/debug.h>
static int verbose = 0;
static uint64_t seekto = 0;

View File

@ -48,13 +48,13 @@
#include <getopt.h>
#include <stdbool.h>
#include <version.h>
#include <maxscale/version.h>
#ifdef HISTORY
#include <histedit.h>
#endif
#include <maxadmin.h>
#include <maxscale/maxadmin.h>
/*
* We need a common.h file that is included by every component.
*/
@ -75,7 +75,9 @@ static void DoSource(int so, char *cmd);
static void DoUsage(const char*);
static int isquit(char *buf);
static void PrintVersion(const char *progname);
static void read_inifile(char **, int*);
static void read_inifile(char **socket,
char **hostname, char **port, char **user, char **passwd,
int *editor);
static bool getPassword(char *password, size_t length);
#ifdef HISTORY
@ -89,12 +91,11 @@ prompt(EditLine *el __attribute__((__unused__)))
}
#endif
static struct option long_options[] =
{
{"host", required_argument, 0, 'h'},
{"user", required_argument, 0, 'u'},
{"password", required_argument, 0, 'p'},
{"password", optional_argument, 0, 'p'},
{"port", required_argument, 0, 'P'},
{"socket", required_argument, 0, 'S'},
{"version", no_argument, 0, 'v'},
@ -106,6 +107,7 @@ static struct option long_options[] =
#define MAXADMIN_DEFAULT_HOST "localhost"
#define MAXADMIN_DEFAULT_PORT "6603"
#define MAXADMIN_DEFAULT_USER "admin"
#define MAXADMIN_BUFFER_SIZE 2048
/**
* The main for the maxadmin client
@ -116,10 +118,6 @@ static struct option long_options[] =
int
main(int argc, char **argv)
{
const char* vi = "vi";
const char* emacs = "emacs";
int i, num, rv;
#ifdef HISTORY
char *buf;
EditLine *el = NULL;
@ -127,45 +125,55 @@ main(int argc, char **argv)
History *hist;
HistEvent ev;
#else
char buf[1024];
char buf[MAXADMIN_BUFFER_SIZE];
#endif
char *hostname = NULL;
char *port = NULL;
char *user = NULL;
char *passwd = NULL;
char *conn_socket = NULL;
char *default_socket = MAXADMIN_DEFAULT_SOCKET;
char *socket_path = NULL;
int use_emacs = 0;
int so;
read_inifile(&socket_path, &hostname, &port, &user, &passwd, &use_emacs);
bool use_inet_socket = false;
bool use_unix_socket = false;
int option_index = 0;
char c;
read_inifile(&conn_socket, &use_emacs);
while ((c = getopt_long(argc, argv, "h:p:P:u:S:v?e",
while ((c = getopt_long(argc, argv, "h:p::P:u:S:v?e",
long_options, &option_index)) >= 0)
{
switch (c)
{
case 'h':
use_inet_socket = true;
hostname = strdup(optarg);
break;
case 'p':
use_inet_socket = true;
// If password was not given, ask for it later
if (optarg != NULL)
{
passwd = strdup(optarg);
memset(optarg, '\0', strlen(optarg));
}
break;
case 'P':
use_inet_socket = true;
port = strdup(optarg);
break;
case 'u':
use_inet_socket = true;
user = strdup(optarg);
break;
case 'S':
conn_socket = strdup(optarg);
use_unix_socket = true;
socket_path = strdup(optarg);
break;
case 'v':
@ -182,16 +190,20 @@ main(int argc, char **argv)
}
}
if ((hostname || port || user || passwd) && (conn_socket))
if (use_inet_socket && use_unix_socket)
{
// Either socket or any parameters related to hostname/port.
// Both unix socket path and at least of the internet socket
// options have been provided.
DoUsage(argv[0]);
exit(EXIT_FAILURE);
}
if (hostname || port || user || passwd)
if (use_inet_socket || (!socket_path && (hostname || port || user || passwd)))
{
assert(!conn_socket);
// If any of the internet socket options have explicitly been provided, or
// .maxadmin does not contain "socket" but does contain at least one of
// the internet socket options, we use an internet socket. Note that if
// -S is provided, then socket_path will be non-NULL.
if (!hostname)
{
@ -210,23 +222,29 @@ main(int argc, char **argv)
}
else
{
if (!conn_socket)
use_unix_socket = true;
if (!socket_path)
{
conn_socket = MAXADMIN_DEFAULT_SOCKET;
socket_path = MAXADMIN_DEFAULT_SOCKET;
}
}
assert(!((hostname || port) && conn_socket));
int so;
if (conn_socket)
if (use_unix_socket)
{
if ((so = connectUsingUnixSocket(conn_socket)) == -1)
assert(socket_path);
if ((so = connectUsingUnixSocket(socket_path)) == -1)
{
exit(EXIT_FAILURE);
}
}
else
{
assert(hostname && user && port);
char password[MAX_PASSWORD_LEN];
if (passwd == NULL)
@ -301,11 +319,11 @@ main(int argc, char **argv)
if (use_emacs)
{
el_set(el, EL_EDITOR, emacs); /** Editor is emacs */
el_set(el, EL_EDITOR, "emacs"); /** Editor is emacs */
}
else
{
el_set(el, EL_EDITOR, vi); /* Default editor is vi */
el_set(el, EL_EDITOR, "vi"); /* Default editor is vi */
}
el_set(el, EL_SIGNAL, 1); /* Handle signals gracefully */
el_set(el, EL_PROMPT, prompt); /* Set the prompt function */
@ -325,15 +343,16 @@ main(int argc, char **argv)
*/
el_source(el, NULL);
int num;
while ((buf = (char *) el_gets(el, &num)) != NULL && num != 0)
{
#else
while (printf("MaxScale> ") && fgets(buf, 1024, stdin) != NULL)
{
num = strlen(buf);
int num = strlen(buf);
#endif
/* Strip trailing \n\r */
for (i = num - 1; buf[i] == '\r' || buf[i] == '\n'; i--)
for (int i = num - 1; buf[i] == '\r' || buf[i] == '\n'; i--)
{
buf[i] = 0;
}
@ -350,6 +369,7 @@ main(int argc, char **argv)
else if (!strcasecmp(buf, "history"))
{
#ifdef HISTORY
int rv;
for (rv = history(hist, &ev, H_LAST); rv != -1;
rv = history(hist, &ev, H_PREV))
{
@ -394,11 +414,11 @@ main(int argc, char **argv)
/**
* Connect to the MaxScale server
*
* @param conn_socket The UNIX socket to connect to
* @param socket_path The UNIX socket to connect to
* @return The connected socket or -1 on error
*/
static int
connectUsingUnixSocket(const char *conn_socket)
connectUsingUnixSocket(const char *socket_path)
{
int so = -1;
@ -408,7 +428,7 @@ connectUsingUnixSocket(const char *conn_socket)
memset(&local_addr, 0, sizeof local_addr);
local_addr.sun_family = AF_UNIX;
strncpy(local_addr.sun_path, conn_socket, sizeof(local_addr.sun_path) - 1);
strncpy(local_addr.sun_path, socket_path, sizeof(local_addr.sun_path) - 1);
if (connect(so, (struct sockaddr *) &local_addr, sizeof(local_addr)) == 0)
{
@ -441,7 +461,7 @@ connectUsingUnixSocket(const char *conn_socket)
{
char errbuf[STRERROR_BUFLEN];
fprintf(stderr, "Unable to connect to MaxScale at %s: %s\n",
conn_socket, strerror_r(errno, errbuf, sizeof(errbuf)));
socket_path, strerror_r(errno, errbuf, sizeof(errbuf)));
close(so);
so = -1;
}
@ -853,13 +873,16 @@ rtrim(char *str)
* Read defaults for hostname, port, user and password from
* the .maxadmin file in the users home directory.
*
* @param hostname Pointer the hostname to be updated
* @param socket Pointer to the socket to be updated.
* @param hostname Pointer to the hostname to be updated
* @param port Pointer to the port to be updated
* @param user Pointer to the user to be updated
* @param passwd Pointer to the password to be updated
*/
static void
read_inifile(char **conn_socket, int* editor)
read_inifile(char **socket,
char **hostname, char** port, char **user, char **passwd,
int* editor)
{
char pathname[400];
char *home, *brkt;
@ -893,11 +916,26 @@ read_inifile(char **conn_socket, int* editor)
{
if (strcmp(name, "socket") == 0)
{
*conn_socket = strdup(value);
*socket = strdup(value);
}
else if (strcmp(name, "hostname") == 0)
{
*hostname = strdup(value);
}
else if (strcmp(name, "port") == 0)
{
*port = strdup(value);
}
else if (strcmp(name, "user") == 0)
{
*user = strdup(value);
}
else if ((strcmp(name, "passwd") == 0) || (strcmp(name, "password") == 0))
{
*passwd = strdup(value);
}
else if (strcmp(name, "editor") == 0)
{
if (strcmp(value, "vi") == 0)
{
*editor = 0;

98
cmake/FindGSSAPI.cmake Normal file
View File

@ -0,0 +1,98 @@
# - Try to detect the GSSAPI support
# Once done this will define
#
# GSSAPI_FOUND - system supports GSSAPI
# GSSAPI_INCS - the GSSAPI include directory
# GSSAPI_LIBS - the libraries needed to use GSSAPI
# GSSAPI_FLAVOR - the type of API - MIT or HEIMDAL
# Copyright (c) 2006, Pino Toscano, <toscano.pino@tiscali.it>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. The name of the author may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
if(GSSAPI_LIBS AND GSSAPI_FLAVOR)
# in cache already
set(GSSAPI_FOUND TRUE)
else(GSSAPI_LIBS AND GSSAPI_FLAVOR)
find_program(KRB5_CONFIG NAMES krb5-config heimdal-krb5-config PATHS
/opt/local/bin
ONLY_CMAKE_FIND_ROOT_PATH # this is required when cross compiling with cmake 2.6 and ignored with cmake 2.4, Alex
)
mark_as_advanced(KRB5_CONFIG)
#reset vars
set(GSSAPI_INCS)
set(GSSAPI_LIBS)
set(GSSAPI_FLAVOR)
if(KRB5_CONFIG)
set(HAVE_KRB5_GSSAPI TRUE)
exec_program(${KRB5_CONFIG} ARGS --libs gssapi RETURN_VALUE _return_VALUE OUTPUT_VARIABLE GSSAPI_LIBS)
if(_return_VALUE)
message(STATUS "GSSAPI configure check failed.")
set(HAVE_KRB5_GSSAPI FALSE)
endif(_return_VALUE)
exec_program(${KRB5_CONFIG} ARGS --cflags gssapi RETURN_VALUE _return_VALUE OUTPUT_VARIABLE GSSAPI_INCS)
string(REGEX REPLACE "(\r?\n)+$" "" GSSAPI_INCS "${GSSAPI_INCS}")
string(REGEX REPLACE " *-I" ";" GSSAPI_INCS "${GSSAPI_INCS}")
exec_program(${KRB5_CONFIG} ARGS --vendor RETURN_VALUE _return_VALUE OUTPUT_VARIABLE gssapi_flavor_tmp)
set(GSSAPI_FLAVOR_MIT)
if(gssapi_flavor_tmp MATCHES ".*Massachusetts.*")
set(GSSAPI_FLAVOR "MIT")
else(gssapi_flavor_tmp MATCHES ".*Massachusetts.*")
set(GSSAPI_FLAVOR "HEIMDAL")
endif(gssapi_flavor_tmp MATCHES ".*Massachusetts.*")
if(NOT HAVE_KRB5_GSSAPI)
if (gssapi_flavor_tmp MATCHES "Sun Microsystems.*")
message(STATUS "Solaris Kerberos does not have GSSAPI; this is normal.")
set(GSSAPI_LIBS)
set(GSSAPI_INCS)
else(gssapi_flavor_tmp MATCHES "Sun Microsystems.*")
message(WARNING "${KRB5_CONFIG} failed unexpectedly.")
endif(gssapi_flavor_tmp MATCHES "Sun Microsystems.*")
endif(NOT HAVE_KRB5_GSSAPI)
if(GSSAPI_LIBS) # GSSAPI_INCS can be also empty, so don't rely on that
set(GSSAPI_FOUND TRUE CACHE STRING "")
message(STATUS "Found GSSAPI: ${GSSAPI_LIBS}")
set(GSSAPI_INCS ${GSSAPI_INCS} CACHE STRING "")
set(GSSAPI_LIBS ${GSSAPI_LIBS} CACHE STRING "")
set(GSSAPI_FLAVOR ${GSSAPI_FLAVOR} CACHE STRING "")
mark_as_advanced(GSSAPI_INCS GSSAPI_LIBS GSSAPI_FLAVOR)
endif(GSSAPI_LIBS)
endif(KRB5_CONFIG)
endif(GSSAPI_LIBS AND GSSAPI_FLAVOR)

16
cmake/FindJansson.cmake Normal file
View File

@ -0,0 +1,16 @@
# This CMake file locates the Jansson libraries and headers
#
# The following variables are set:
# JANSSON_FOUND - If the Jansson library was found
# JANSSON_LIBRARIES - Path to the static library
# JANSSON_INCLUDE_DIR - Path to Jansson headers
find_path(JANSSON_INCLUDE_DIR jansson.h)
find_library(JANSSON_LIBRARIES NAMES libjansson.so libjansson.a)
if (JANSSON_INCLUDE_DIR AND JANSSON_LIBRARIES)
message(STATUS "Found Jansson: ${JANSSON_LIBRARIES}")
set(JANSSON_FOUND TRUE)
else()
message(STATUS "Could not find Jansson")
endif()

23
cmake/FindSQLite.cmake Normal file
View File

@ -0,0 +1,23 @@
# This CMake file locates the SQLite3 development libraries
#
# The following variables are set:
# SQLITE_FOUND - If the SQLite library was found
# SQLITE_LIBRARIES - Path to the static library
# SQLITE_INCLUDE_DIR - Path to SQLite headers
# SQLITE_VERSION - Library version
find_path(SQLITE_INCLUDE_DIR sqlite3.h)
find_library(SQLITE_LIBRARIES NAMES libsqlite3.so)
if (SQLITE_INCLUDE_DIR AND SQLITE_LIBRARIES)
execute_process(COMMAND grep ".*#define.*SQLITE_VERSION " ${SQLITE_INCLUDE_DIR}/sqlite3.h
COMMAND sed "s/.*\"\\(.*\\)\".*/\\1/"
OUTPUT_VARIABLE SQLITE_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE)
message(STATUS "Found SQLite version ${SQLITE_VERSION}: ${SQLITE_LIBRARIES}")
set(SQLITE_FOUND TRUE)
else()
message(STATUS "Could not find SQLite")
endif()

View File

@ -22,7 +22,7 @@ set(BUILD_RABBITMQ TRUE CACHE BOOL "Build RabbitMQ components")
set(BUILD_BINLOG TRUE CACHE BOOL "Build binlog router")
# Build the Avro router
set(BUILD_AVRO FALSE CACHE BOOL "Build Avro router")
set(BUILD_AVRO TRUE CACHE BOOL "Build Avro router")
# Build the multimaster monitor
set(BUILD_MMMON TRUE CACHE BOOL "Build multimaster monitor")

View File

@ -20,6 +20,7 @@ set(DEFAULT_CACHE_SUBPATH "cache/maxscale" CACHE PATH "Default cache subpath")
set(DEFAULT_LANG_SUBPATH "lib/maxscale" CACHE PATH "Default language file subpath")
set(DEFAULT_EXEC_SUBPATH "${MAXSCALE_BINDIR}" CACHE PATH "Default executable subpath")
set(DEFAULT_CONFIG_SUBPATH "etc" CACHE PATH "Default configuration subpath")
set(DEFAULT_CONFIG_PERSIST_SUBPATH "maxscale.cnf.d" CACHE PATH "Default persisted configuration subpath")
set(DEFAULT_PIDDIR ${MAXSCALE_VARDIR}/${DEFAULT_PID_SUBPATH} CACHE PATH "Default PID file directory")
set(DEFAULT_LOGDIR ${MAXSCALE_VARDIR}/${DEFAULT_LOG_SUBPATH} CACHE PATH "Default log directory")
@ -29,6 +30,7 @@ set(DEFAULT_CACHEDIR ${MAXSCALE_VARDIR}/${DEFAULT_CACHE_SUBPATH} CACHE PATH "Def
set(DEFAULT_LANGDIR ${MAXSCALE_VARDIR}/${DEFAULT_LANG_SUBPATH} CACHE PATH "Default language file directory")
set(DEFAULT_EXECDIR ${CMAKE_INSTALL_PREFIX}/${DEFAULT_EXEC_SUBPATH} CACHE PATH "Default executable directory")
set(DEFAULT_CONFIGDIR /${DEFAULT_CONFIG_SUBPATH} CACHE PATH "Default configuration directory")
set(DEFAULT_CONFIG_PERSISTDIR ${DEFAULT_DATADIR}/${DEFAULT_CONFIG_PERSIST_SUBPATH} CACHE PATH "Default persisted configuration directory")
# Massage TARGET_COMPONENT into a list
if (TARGET_COMPONENT)

View File

@ -5,9 +5,18 @@ After=network.target
[Service]
Type=forking
Restart=on-abort
PIDFile=@MAXSCALE_VARDIR@/run/maxscale/maxscale.pid
# Make sure /var/run/maxscale exists
PermissionsStartOnly=true
ExecStartPre=/usr/bin/install -d @MAXSCALE_VARDIR@/run/maxscale -o maxscale -g maxscale
ExecStart=@CMAKE_INSTALL_PREFIX@/@MAXSCALE_BINDIR@/maxscale --user=maxscale
PIDFile=@MAXSCALE_VARDIR@/run/maxscale/maxscale.pid
# Use the default user and group
User=maxscale
Group=maxscale
ExecStart=@CMAKE_INSTALL_PREFIX@/@MAXSCALE_BINDIR@/maxscale
TimeoutStartSec=120
LimitNOFILE=65535

View File

@ -1,5 +1,4 @@
#ifndef _ADMINUSERS_H
#define _ADMINUSERS_H
#pragma once
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
@ -24,7 +23,11 @@
*
* @endverbatim
*/
#include <dcb.h>
#include <maxscale/cdefs.h>
#include <maxscale/dcb.h>
MXS_BEGIN_DECLS
#define ADMIN_SALT "$1$MXS"
@ -63,4 +66,4 @@ extern bool admin_verify_inet_user(const char *uname, const char *passwor
extern void dcb_PrintAdminUsers(DCB *dcb);
#endif
MXS_END_DECLS

View File

@ -1,5 +1,4 @@
#ifndef _MAXSCALE_ALLOC_H
#define _MAXSCALE_ALLOC_H
#pragma once
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
@ -13,11 +12,11 @@
* Public License.
*/
#include <maxscale/cdefs.h>
#include <stdlib.h>
#include <string.h>
#include <skygw_debug.h>
EXTERN_C_BLOCK_BEGIN
MXS_BEGIN_DECLS
/*
* NOTE: Do not use these functions directly, use the macros below.
@ -77,6 +76,4 @@ char *mxs_strndup_a(const char *s, size_t n/*, const char *caller*/);
*/
#define MXS_ABORT_IF_FALSE(b) do { if (!b) { abort(); } } while (false)
EXTERN_C_BLOCK_END
#endif
MXS_END_DECLS

70
include/maxscale/atomic.h Normal file
View File

@ -0,0 +1,70 @@
#pragma once
/*
* 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
*/
#include <maxscale/cdefs.h>
MXS_BEGIN_DECLS
/**
* Implementation of an atomic add operation for the GCC environment, or the
* X86 processor. If we are working within GNU C then we can use the GCC
* atomic add built in function, which is portable across platforms that
* implement GCC. Otherwise, this function currently supports only X86
* architecture (without further development).
*
* Adds a value to the contents of a location pointed to by the first parameter.
* The add operation is atomic and the return value is the value stored in the
* location prior to the operation. The number that is added may be signed,
* therefore atomic_subtract is merely an atomic add with a negative value.
*
* @param variable Pointer the the variable to add to
* @param value Value to be added
* @return The value of variable before the add occurred
*/
int atomic_add(int *variable, int value);
/**
* @brief Impose a full memory barrier
*
* A full memory barrier guarantees that all store and load operations complete
* before the function is called.
*
* Currently, only the GNUC __sync_synchronize() is used. C11 introduces
* standard functions for atomic memory operations and should be taken into use.
*
* @see https://www.kernel.org/doc/Documentation/memory-barriers.txt
*/
static inline void atomic_synchronize()
{
#ifdef __GNUC__
__sync_synchronize(); /* Memory barrier. */
#else
#error "No GNUC atomics available."
#endif
}
MXS_END_DECLS

View File

@ -1,5 +1,4 @@
#ifndef _BUFFER_H
#define _BUFFER_H
#pragma once
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
@ -42,13 +41,15 @@
*
* @endverbatim
*/
#include <maxscale/cdefs.h>
#include <string.h>
#include <skygw_debug.h>
#include <hint.h>
#include <spinlock.h>
#include <maxscale/debug.h>
#include <maxscale/hint.h>
#include <maxscale/spinlock.h>
#include <stdint.h>
EXTERN_C_BLOCK_BEGIN
MXS_BEGIN_DECLS
/**
* Buffer properties - used to store properties related to the buffer
@ -214,7 +215,5 @@ 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
MXS_END_DECLS

76
include/maxscale/cdefs.h Normal file
View File

@ -0,0 +1,76 @@
#pragma once
/*
* 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 cdefs.h
*
* This file has several purposes.
*
* - Its purpose is the same as that of x86_64-linux-gnu/sys/cdefs.h, that is,
* it defines things that are dependent upon the compilation environment.
* - Since this *must* be included as the very first header by all other MaxScale
* headers, it allows you to redfine things globally, should that be necessary,
* for instance, when debugging something.
* - Global constants applicable across the line can be defined here.
*/
#ifdef __cplusplus
# define MXS_BEGIN_DECLS extern "C" {
# define MXS_END_DECLS }
#else
# define MXS_BEGIN_DECLS
# define MXS_END_DECLS
#endif
#define _XOPEN_SOURCE 700
#define OPENSSL_THREAD_DEFINES
/**
* Define intended for use with strerror.
*
* char errbuf[MXS_STRERROR_BUFLEN];
* strerror_r(errno, errbuf, sizeof(errbuf))
*/
#define MXS_STRERROR_BUFLEN 512
/**
* Returns the smaller of two items.
*
* @param a A value.
* @param b Another value.
*
* @return a if a is smaller than b, b otherwise.
*
* @note This a macro, so the arguments will be evaluated more than once.
*/
#define MXS_MIN(a,b) ((a)<(b) ? (a) : (b))
/**
* Returns the larger of two items.
*
* @param a A value.
* @param b Another value.
*
* @return a if a is larger than b, b otherwise.
*
* @note This a macro, so the arguments will be evaluated more than once.
*/
#define MXS_MAX(a,b) ((a)>(b) ? (a) : (b))
/**
* COMMON INCLUDE FILES
*/
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>

View File

@ -1,5 +1,4 @@
#ifndef _MAXSCALE_CONFIG_H
#define _MAXSCALE_CONFIG_H
#pragma once
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
@ -12,11 +11,7 @@
* of this software will be governed by version 2 or later of the General
* Public License.
*/
#include <skygw_utils.h>
#include <sys/utsname.h>
#include <stdint.h>
#include <openssl/sha.h>
#include <spinlock.h>
/**
* @file config.h The configuration handling elements
*
@ -33,6 +28,13 @@
* @endverbatim
*/
#include <maxscale/cdefs.h>
#include <limits.h>
#include <sys/utsname.h>
#include <openssl/sha.h>
MXS_BEGIN_DECLS
#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 */
@ -127,31 +129,31 @@ typedef struct
} GATEWAY_CONF;
char* config_clean_string_list(char* str);
CONFIG_PARAMETER* config_clone_param(CONFIG_PARAMETER* param);
char* config_clean_string_list(const char* str);
CONFIG_PARAMETER* config_clone_param(const 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);
config_param_type_t config_get_paramtype(const CONFIG_PARAMETER* param);
bool config_get_valint(int* val,
CONFIG_PARAMETER* param,
const 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 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 CONFIG_PARAMETER* param,
const char* name, /*< if NULL examine current param only */
config_param_type_t ptype);
bool config_load(char *);
bool config_load(const char *);
unsigned int config_nbpolls();
double config_percentage_value(char *str);
double config_percentage_value(const char *str);
unsigned int config_pollsleep();
int config_reload();
bool config_reload();
bool config_set_qualified_param(CONFIG_PARAMETER* param,
void* val,
config_param_type_t type);
@ -160,4 +162,4 @@ int config_truth_value(char *);
void free_config_parameter(CONFIG_PARAMETER* p1);
bool is_internal_service(const char *router);
#endif
MXS_END_DECLS

View File

@ -1,5 +1,4 @@
#ifndef _DCB_H
#define _DCB_H
#pragma once
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
@ -12,23 +11,6 @@
* of this software will be governed by version 2 or later of the General
* Public License.
*/
#include <spinlock.h>
#include <buffer.h>
#include <listmanager.h>
#include <gw_protocol.h>
#include <gw_authenticator.h>
#include <gw_ssl.h>
#include <modinfo.h>
#include <gwbitmask.h>
#include <skygw_utils.h>
#include <netinet/in.h>
#define ERRHANDLE
struct session;
struct server;
struct service;
struct servlistener;
/**
* @file dcb.h The Descriptor Control Block
@ -63,6 +45,26 @@ struct servlistener;
* @endverbatim
*/
#include <maxscale/cdefs.h>
#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 <netinet/in.h>
MXS_BEGIN_DECLS
#define ERRHANDLE
struct session;
struct server;
struct service;
struct servlistener;
struct dcb;
/**
@ -156,6 +158,11 @@ typedef enum
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.
*/
@ -247,7 +254,8 @@ typedef struct dcb
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 */
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 */
@ -268,6 +276,7 @@ typedef struct dcb
bool ssl_write_want_read; /*< Flag */
bool ssl_write_want_write; /*< Flag */
int dcb_port; /**< port of target server */
bool was_persistent; /**< Whether this DCB was in the persistent pool */
skygw_chk_t dcb_chk_tail;
} DCB;
@ -277,7 +286,8 @@ typedef struct dcb
.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}
.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
@ -292,15 +302,6 @@ typedef enum
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)
@ -362,4 +363,5 @@ void dcb_append_readqueue(DCB *dcb, GWBUF *buffer);
#define DCB_IS_CLONE(d) ((d)->flags & DCBF_CLONE)
#define DCB_REPLIED(d) ((d)->flags & DCBF_REPLIED)
#endif /* _DCB_H */
MXS_END_DECLS

View File

@ -1,3 +1,4 @@
#pragma once
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
@ -11,29 +12,15 @@
* Public License.
*/
#include <stdio.h>
#include <stdlib.h>
#include <maxscale/cdefs.h>
#include <assert.h>
#include <limits.h>
#define __USE_UNIX98 1
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <stdbool.h>
#include <maxscale/log_manager.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
MXS_BEGIN_DECLS
#if defined(SS_DEBUG)
# define SS_PROF
@ -46,7 +33,7 @@
#endif /* SS_DEBUG || SS_PROF */
#if defined(SS_DEBUG) && defined(LOG_ASSERT)
#include <log_manager.h>
#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)
@ -213,14 +200,14 @@ typedef enum skygw_chk_t
(s) == SESSION_STATE_STOPPING ? "SESSION_STATE_STOPPING":\
"SESSION_STATE_UNKNOWN"))))))
#define STRPROTOCOLSTATE(s) ((s) == MYSQL_ALLOC ? "MYSQL_ALLOC" : \
((s) == MYSQL_PENDING_CONNECT ? "MYSQL_PENDING_CONNECT" : \
((s) == MYSQL_CONNECTED ? "MYSQL_CONNECTED" : \
((s) == MYSQL_AUTH_SENT ? "MYSQL_AUTH_SENT" : \
((s) == MYSQL_AUTH_RECV ? "MYSQL_AUTH_RECV" : \
((s) == MYSQL_AUTH_FAILED ? "MYSQL_AUTH_FAILED" : \
((s) == MYSQL_IDLE ? "MYSQL_IDLE" : \
"UNKNOWN MYSQL STATE")))))))
#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" : \
@ -574,8 +561,4 @@ typedef enum skygw_chk_t
}
#if defined(FAKE_CODE)
static bool conn_open[10240];
#endif /* FAKE_CODE */
#endif /* SKYGW_DEBUG_H */
MXS_END_DECLS

View File

@ -1,5 +1,4 @@
#ifndef _EXTERN_CMD_HG
#define _EXTERN_CMD_HG
#pragma once
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
@ -13,12 +12,14 @@
* Public License.
*/
#include <maxscale/cdefs.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <skygw_utils.h>
#include <log_manager.h>
#include <maxscale_pcre2.h>
#include <maxscale/log_manager.h>
#include <maxscale/pcre2.h>
MXS_BEGIN_DECLS
#define MAXSCALE_EXTCMD_ARG_MAX 256
@ -38,4 +39,4 @@ bool externcmd_substitute_arg(EXTERNCMD* cmd, const char* re, const char* replac
bool externcmd_can_execute(const char* argstr);
bool externcmd_matches(const EXTERNCMD* cmd, const char* match);
#endif
MXS_END_DECLS

View File

@ -1,5 +1,4 @@
#ifndef _FILTER_H
#define _FILTER_H
#pragma once
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
@ -22,11 +21,16 @@
* 27/05/2014 Mark Riddoch Initial implementation
*
*/
#include <dcb.h>
#include <session.h>
#include <buffer.h>
#include <maxscale/cdefs.h>
#include <maxscale/routing.h>
#include <maxscale/dcb.h>
#include <maxscale/session.h>
#include <maxscale/buffer.h>
#include <stdint.h>
MXS_BEGIN_DECLS
/**
* The FILTER handle points to module specific data, so the best we can do
* is to make it a void * externally.
@ -78,6 +82,8 @@ typedef struct filter_object
int (*routeQuery)(FILTER *instance, void *fsession, GWBUF *queue);
int (*clientReply)(FILTER *instance, void *fsession, GWBUF *queue);
void (*diagnostics)(FILTER *instance, void *fsession, DCB *dcb);
uint64_t (*getCapabilities)(void);
void (*destroyInstance)(FILTER *instance);
} FILTER_OBJECT;
/**
@ -85,7 +91,7 @@ typedef struct filter_object
* is changed these values must be updated in line with the rules in the
* file modinfo.h.
*/
#define FILTER_VERSION {2, 1, 0}
#define FILTER_VERSION {2, 2, 0}
/**
* The definition of a filter from the configuration file.
* This is basically the link between a plugin to load and the
@ -116,4 +122,20 @@ void dprintAllFilters(DCB *);
void dprintFilter(DCB *, FILTER_DEF *);
void dListFilters(DCB *);
#endif
/**
* Specifies capabilities specific for filters. Common capabilities
* are defined by @c routing_capability_t.
*
* @see routing_capability_t
*
* @note The values of the capabilities here *must* be between 0x000100000000
* and 0x800000000000, that is, bits 32 to 47.
*/
/*
typedef enum filter_capability
{
} filter_capability_t;
*/
MXS_END_DECLS

View File

@ -0,0 +1,140 @@
#pragma once
/*
* 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_authenticator.h
*
* The authenticator module interface definitions for MaxScale
*
* @verbatim
* Revision History
*
* Date Who Description
* 17/02/16 Martin Brampton Initial implementation
*
* @endverbatim
*/
#include <maxscale/cdefs.h>
#include <maxscale/buffer.h>
#include <openssl/crypto.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/dh.h>
MXS_BEGIN_DECLS
/** 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 /**< Temporary error, service is started */
#define MXS_AUTH_LOADUSERS_FATAL 2 /**< Fatal error, service is not started */
/**
* 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);
const char* get_default_authenticator(const char *protocol);
MXS_END_DECLS

View File

@ -1,5 +1,4 @@
#ifndef GW_PROTOCOL_H
#define GW_PROTOCOL_H
#pragma once
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
@ -28,7 +27,10 @@
* @endverbatim
*/
#include <buffer.h>
#include <maxscale/cdefs.h>
#include <maxscale/buffer.h>
MXS_BEGIN_DECLS
struct dcb;
struct server;
@ -81,6 +83,4 @@ typedef struct gw_protocol
*/
#define GWPROTOCOL_VERSION {1, 1, 0}
#endif /* GW_PROTOCOL_H */
MXS_END_DECLS

View File

@ -1,5 +1,4 @@
#ifndef _GW_SSL_H
#define _GW_SSL_H
#pragma once
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
@ -27,12 +26,15 @@
* @endverbatim
*/
#include <gw_protocol.h>
#include <maxscale/cdefs.h>
#include <maxscale/gw_protocol.h>
#include <openssl/crypto.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/dh.h>
MXS_BEGIN_DECLS
struct dcb;
typedef enum ssl_method_type
@ -78,4 +80,4 @@ 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 */
MXS_END_DECLS

View File

@ -1,5 +1,4 @@
#ifndef _GWBITMASK_H
#define _GWBITMASK_H
#pragma once
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
@ -13,9 +12,6 @@
* Public License.
*/
#include <spinlock.h>
#include <maxscale/limits.h>
/**
* @file gwbitmask.h An implementation of an arbitrarily long bitmask
*
@ -29,6 +25,12 @@
* @endverbatim
*/
#include <maxscale/cdefs.h>
#include <maxscale/spinlock.h>
#include <maxscale/limits.h>
MXS_BEGIN_DECLS
/* This number MUST an be exact multiple of 8 */
#define MXS_BITMASK_LENGTH (MXS_MAX_THREADS + 1) /**< Number of bits in the bitmask */
@ -55,4 +57,4 @@ extern int bitmask_isallclear(GWBITMASK *);
extern void bitmask_copy(GWBITMASK *, GWBITMASK *);
extern char *bitmask_render_readable(GWBITMASK *);
#endif
MXS_END_DECLS

View File

@ -1,5 +1,4 @@
#ifndef _GW_DIRS_HG
#define _GW_DIRS_HG
#pragma once
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
@ -15,11 +14,12 @@
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#include <maxscale/cdefs.h>
#include <stdlib.h>
#include <string.h>
#include <skygw_utils.h>
EXTERN_C_BLOCK_BEGIN
MXS_BEGIN_DECLS
/**
* All of the following DEFAULT_* variables are defined in cmake/install_layout.cmake
@ -32,10 +32,12 @@ EXTERN_C_BLOCK_BEGIN
#define MXS_DEFAULT_LANG_SUBPATH "@DEFAULT_LANG_SUBPATH@"
#define MXS_DEFAULT_EXEC_SUBPATH "@DEFAULT_EXEC_SUBPATH@"
#define MXS_DEFAULT_CONFIG_SUBPATH "@DEFAULT_CONFIG_SUBPATH@"
#define MXS_DEFAULT_CONFIG_PERSIST_SUBPATH "@DEFAULT_CONFIG_PERSIST_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.*/
@ -46,8 +48,10 @@ 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 const char* default_config_persistdir = "@DEFAULT_CONFIG_PERSISTDIR@";
static char* configdir = NULL;
static char* configdir = NULL; /*< Where the config file is found e.g. /etc/ */
static char* config_persistdir = NULL;/*< Persisted configs e.g. /var/lib/maxscale.cnf.d/ */
static char* logdir = NULL;
static char* libdir = NULL;
static char* cachedir = NULL;
@ -62,6 +66,7 @@ void set_datadir(char* param);
void set_process_datadir(char* param);
void set_cachedir(char* param);
void set_configdir(char* param);
void set_config_persistdir(char* param);
void set_logdir(char* param);
void set_langdir(char* param);
void set_piddir(char* param);
@ -71,11 +76,10 @@ char* get_datadir();
char* get_process_datadir();
char* get_cachedir();
char* get_configdir();
char* get_config_persistdir();
char* get_piddir();
char* get_logdir();
char* get_langdir();
char* get_execdir();
EXTERN_C_BLOCK_END
#endif
MXS_END_DECLS

View File

@ -1,5 +1,4 @@
#ifndef _HASTABLE_H
#define _HASTABLE_H
#pragma once
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
@ -28,10 +27,11 @@
*
* @endverbatim
*/
#include <skygw_debug.h>
#include <spinlock.h>
#include <maxscale/cdefs.h>
#include <maxscale/debug.h>
#include <maxscale/spinlock.h>
EXTERN_C_BLOCK_BEGIN
MXS_BEGIN_DECLS
/**
* The entries within a hashtable.
@ -150,6 +150,4 @@ 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
MXS_END_DECLS

View File

@ -1,5 +1,4 @@
#ifndef _HINT_H
#define _HINT_H
#pragma once
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
@ -25,8 +24,10 @@
* @endverbatim
*/
#include <skygw_debug.h>
#include <maxscale/cdefs.h>
#include <maxscale/debug.h>
MXS_BEGIN_DECLS
/**
* The types of hint that are supported by the generic hinting mechanism.
@ -63,4 +64,5 @@ 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
MXS_END_DECLS

View File

@ -1,6 +1,4 @@
#ifndef _HK_HEARTBEAT_H
#define _HK_HEARTBEAT_H
#pragma once
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
@ -14,6 +12,10 @@
* Public License.
*/
#include <maxscale/cdefs.h>
MXS_BEGIN_DECLS
/**
* The global housekeeper heartbeat value. This value is incremented
* every 100 milliseconds and may be used for crude timing etc.
@ -21,4 +23,4 @@
extern long hkheartbeat;
#endif
MXS_END_DECLS

View File

@ -1,5 +1,4 @@
#ifndef _HOUSEKEEPER_H
#define _HOUSEKEEPER_H
#pragma once
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
@ -12,9 +11,14 @@
* of this software will be governed by version 2 or later of the General
* Public License.
*/
#include <maxscale/cdefs.h>
#include <time.h>
#include <dcb.h>
#include <hk_heartbeat.h>
#include <maxscale/dcb.h>
#include <maxscale/hk_heartbeat.h>
MXS_BEGIN_DECLS
/**
* @file housekeeper.h A mechanism to have task run periodically
*
@ -47,11 +51,34 @@ typedef struct hktask
struct hktask *next; /*< Next task in the list */
} HKTASK;
extern void hkinit();
/**
* Initialises the housekeeper mechanism.
*
* A call to any of the other housekeeper functions can be made only if
* this function returns successfully.
*
* @return True if the housekeeper mechanism was initialized, false otherwise.
*/
extern bool hkinit();
/**
* Shuts down the housekeeper mechanism.
*
* Should be called @b only if @c hkinit() returned successfully.
*
* @see hkinit hkfinish
*/
extern void hkshutdown();
/**
* Waits for the housekeeper thread to finish. Should be called only after
* hkshutdown() has been called.
*/
extern void hkfinish();
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
MXS_END_DECLS

74
include/maxscale/limits.h Normal file
View File

@ -0,0 +1,74 @@
#pragma once
/*
* 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/cdefs.h>
MXS_BEGIN_DECLS
/**
* @file lmits.h
*
* This file contains defines for hard limits of MaxScale.
*/
/**
* MXS_BACKEND_SO_RCVBUF
*
* The value used when setting SO_RCVBUF of backend sockets.
*/
#define MXS_BACKEND_SO_RCVBUF (128 * 1024)
/**
* MXS_BACKEND_SO_SNDBUF
*
* The value used when setting SO_SNDBUF of backend sockets.
*/
#define MXS_BACKEND_SO_SNDBUF (128 * 1024)
/**
* MXS_CLIENT_SO_RCVBUF
*
* The value used when setting SO_RCVBUF of client sockets.
*/
#define MXS_CLIENT_SO_RCVBUF (128 * 1024)
/**
* MXS_CLIENT_SO_SNDBUF
*
* The value used when setting SO_SNDBUF of client sockets.
*/
#define MXS_CLIENT_SO_SNDBUF (128 * 1024)
/**
* MXS_MAX_NW_READ_BUFFER_SIZE
*
* The maximum amount of data read in one gofrom a client DCB.
*
* TODO: Consider removing altogether so that we always read
* whatever is available in the socket.
*/
#define MXS_MAX_NW_READ_BUFFER_SIZE (32 * 1024)
/**
* MXS_MAX_THREADS
*
* 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
MXS_END_DECLS

View File

@ -1,5 +1,4 @@
#ifndef _LISTENER_H
#define _LISTENER_H
#pragma once
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
@ -27,9 +26,12 @@
* @endverbatim
*/
#include <gw_protocol.h>
#include <gw_ssl.h>
#include <hashtable.h>
#include <maxscale/cdefs.h>
#include <maxscale/gw_protocol.h>
#include <maxscale/gw_ssl.h>
#include <maxscale/hashtable.h>
MXS_BEGIN_DECLS
struct dcb;
struct service;
@ -47,6 +49,7 @@ typedef struct servlistener
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 */
@ -58,10 +61,10 @@ typedef struct servlistener
SERV_LISTENER *listener_alloc(struct service* service, char *name, char *protocol,
char *address, unsigned short port, char *authenticator,
SSL_LISTENER *ssl);
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
MXS_END_DECLS

View File

@ -1,5 +1,4 @@
#ifndef _LISTMANAGER_H
#define _LISTMANAGER_H
#pragma once
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
@ -26,8 +25,11 @@
* @endverbatim
*/
#include <spinlock.h>
#include <skygw_debug.h>
#include <maxscale/cdefs.h>
#include <maxscale/spinlock.h>
#include <maxscale/debug.h>
MXS_BEGIN_DECLS
struct dcb;
@ -115,5 +117,4 @@ void list_map(LIST_CONFIG *list_config, bool (*callback)(void *, ...));
list_entry_t *list_remove_first(LIST_CONFIG *list_config);
list_entry_t *list_remove_last(LIST_CONFIG *list_config);
#endif /* LISTMANAGER_H */
MXS_END_DECLS

View File

@ -1,3 +1,4 @@
#pragma once
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
@ -10,23 +11,14 @@
* 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 <maxscale/cdefs.h>
#include <assert.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
MXS_BEGIN_DECLS
/**
* If MXS_MODULE_NAME is defined before log_manager.h is included, then all
@ -118,6 +110,12 @@ void mxs_log_set_throttling(const MXS_LOG_THROTTLING* throttling);
void mxs_log_get_throttling(MXS_LOG_THROTTLING* throttling);
static inline bool mxs_log_priority_is_enabled(int priority)
{
assert((priority & ~LOG_PRIMASK) == 0);
return MXS_LOG_PRIORITY_IS_ENABLED(priority);
}
int mxs_log_message(int priority,
const char* modname,
const char* file, int line, const char* function,
@ -133,7 +131,9 @@ int mxs_log_message(int priority,
* 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__)
(mxs_log_priority_is_enabled(priority) ? \
mxs_log_message(priority, MXS_MODULE_NAME, __FILE__, __LINE__, __func__, format, ##__VA_ARGS__) :\
0)
/**
* Log an alert, error, warning, notice, info, or debug message.
@ -154,7 +154,12 @@ int mxs_log_message(int priority,
#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__)
#if defined(SS_DEBUG)
#define MXS_DEBUG(format, ...) MXS_LOG_MESSAGE(LOG_DEBUG, format, ##__VA_ARGS__)
#else
#define MXS_DEBUG(format, ...)
#endif
/**
* Log an out of memory error using custom message.
@ -195,8 +200,4 @@ enum
trailing NULL. If longer, it will be cut. */
};
#if defined(__cplusplus)
}
#endif
#endif /** LOG_MANAGER_H */
MXS_END_DECLS

View File

@ -1,5 +1,4 @@
#ifndef _MAXADMIN_H
#define _MAXADMIN_H
#pragma once
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
@ -13,6 +12,10 @@
* Public License.
*/
#include <maxscale/cdefs.h>
MXS_BEGIN_DECLS
#define MAXADMIN_DEFAULT_SOCKET "/tmp/maxadmin.sock"
#define MAXADMIN_CONFIG_DEFAULT_SOCKET_TAG_LEN 7
@ -28,4 +31,4 @@
#define MAXADMIN_AUTH_PASSWORD_PROMPT "PASSWORD"
#define MAXADMIN_AUTH_PASSWORD_PROMPT_LEN 8
#endif
MXS_END_DECLS

View File

@ -1,5 +1,4 @@
#ifndef _MAXSCALE_H
#define _MAXSCALE_H
#pragma once
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
@ -27,8 +26,10 @@
* @endverbatim
*/
#include <maxscale/cdefs.h>
#include <time.h>
MXS_BEGIN_DECLS
/* Exit status for MaxScale */
#define MAXSCALE_SHUTDOWN 0 /* Good shutdown */
@ -43,4 +44,14 @@ void maxscale_reset_starttime(void);
time_t maxscale_started(void);
int maxscale_uptime(void);
#endif
/**
* Initiate shutdown of MaxScale.
*
* This functions informs all threads that they should stop the
* processing and exit.
*
* @return How many times maxscale_shutdown() has been called.
*/
int maxscale_shutdown(void);
MXS_END_DECLS

View File

@ -1,5 +1,4 @@
#ifndef _MEMLOG_H
#define _MEMLOG_H
#pragma once
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
@ -24,7 +23,11 @@
*
* @endverbatim
*/
#include <spinlock.h>
#include <maxscale/cdefs.h>
#include <maxscale/spinlock.h>
MXS_BEGIN_DECLS
typedef enum { ML_INT, ML_LONG, ML_LONGLONG, ML_STRING } MEMLOGTYPE;
@ -59,4 +62,4 @@ extern void memlog_log(MEMLOG *, void *);
extern void memlog_flush_all();
extern void memlog_flush(MEMLOG *);
#endif
MXS_END_DECLS

View File

@ -1,5 +1,4 @@
#ifndef _MODINFO_H
#define _MODINFO_H
#pragma once
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
@ -25,6 +24,10 @@
* @endverbatim
*/
#include <maxscale/cdefs.h>
MXS_BEGIN_DECLS
/**
* The status of the module. This gives some idea of the module
* maturity.
@ -83,4 +86,5 @@ typedef struct
MODULE_VERSION api_version;
char *description;
} MODULE_INFO;
#endif
MXS_END_DECLS

View File

@ -1,5 +1,4 @@
#ifndef _MODULES_H
#define _MODULES_H
#pragma once
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
@ -12,12 +11,6 @@
* of this software will be governed by version 2 or later of the General
* Public License.
*/
#include <dcb.h>
#include <modinfo.h>
#include <resultset.h>
#include <skygw_debug.h>
EXTERN_C_BLOCK_BEGIN
/**
* @file modules.h Utilities for loading modules
@ -38,6 +31,14 @@ EXTERN_C_BLOCK_BEGIN
* @endverbatim
*/
#include <maxscale/cdefs.h>
#include <maxscale/dcb.h>
#include <maxscale/modinfo.h>
#include <maxscale/resultset.h>
#include <maxscale/debug.h>
MXS_BEGIN_DECLS
typedef struct modules
{
char *module; /**< The name of the module */
@ -71,6 +72,4 @@ extern RESULTSET *moduleGetList();
extern void module_feedback_send(void*);
extern void moduleShowFeedbackReport(DCB *dcb);
EXTERN_C_BLOCK_END
#endif
MXS_END_DECLS

View File

@ -1,5 +1,4 @@
#ifndef _MODUTIL_H
#define _MODUTIL_H
#pragma once
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
@ -26,10 +25,14 @@
*
* @endverbatim
*/
#include <buffer.h>
#include <dcb.h>
#include <maxscale/cdefs.h>
#include <maxscale/buffer.h>
#include <maxscale/dcb.h>
#include <string.h>
#include <maxscale_pcre2.h>
#include <maxscale/pcre2.h>
MXS_BEGIN_DECLS
#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)
@ -70,4 +73,4 @@ 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
MXS_END_DECLS

View File

@ -1,5 +1,4 @@
#ifndef _MONITOR_H
#define _MONITOR_H
#pragma once
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
@ -12,14 +11,6 @@
* of this software will be governed by version 2 or later of the General
* Public License.
*/
#include <mysql.h>
#include <server.h>
#include <dcb.h>
#include <log_manager.h>
#include <resultset.h>
#include <maxconfig.h>
#include <externcmd.h>
#include <secrets.h>
/**
* @file monitor.h The interface to the monitor module
@ -43,6 +34,18 @@
* @endverbatim
*/
#include <maxscale/cdefs.h>
#include <mysql.h>
#include <maxscale/server.h>
#include <maxscale/dcb.h>
#include <maxscale/log_manager.h>
#include <maxscale/resultset.h>
#include <maxscale/config.h>
#include <maxscale/externcmd.h>
#include <maxscale/secrets.h>
MXS_BEGIN_DECLS
/**
* The "Module Object" for a monitor module.
*
@ -134,6 +137,9 @@ typedef enum
#define MONITOR_INTERVAL 10000 // in milliseconds
#define MONITOR_DEFAULT_ID 1UL // unsigned long value
#define MAX_MONITOR_USER_LEN 512
#define MAX_MONITOR_PASSWORD_LEN 512
/*
* 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
@ -174,8 +180,8 @@ typedef struct monitor_servers
struct monitor
{
char *name; /**< The name of the monitor module */
char *user; /*< Monitor username */
char *password; /*< Monitor password */
char user[MAX_MONITOR_USER_LEN]; /*< Monitor username */
char password[MAX_MONITOR_PASSWORD_LEN]; /*< Monitor password */
SPINLOCK lock;
CONFIG_PARAMETER* parameters; /*< configuration parameters */
MONITOR_SERVERS* databases; /*< List of databases the monitor monitors */
@ -198,7 +204,8 @@ struct monitor
extern MONITOR *monitor_alloc(char *, char *);
extern void monitor_free(MONITOR *);
extern MONITOR *monitor_find(char *);
extern void monitorAddServer(MONITOR *, SERVER *);
extern void monitorAddServer(MONITOR *mon, SERVER *server);
extern void monitorRemoveServer(MONITOR *mon, SERVER *server);
extern void monitorAddUser(MONITOR *, char *, char *);
extern void monitorAddParameters(MONITOR *monitor, CONFIG_PARAMETER *params);
extern void monitorStop(MONITOR *);
@ -226,4 +233,11 @@ 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
/**
* Check if a monitor uses @c servers
* @param server Server that is queried
* @return True if server is used by at least one monitor
*/
bool monitor_server_in_use(const SERVER *server);
MXS_END_DECLS

View File

@ -1,5 +1,4 @@
#ifndef MYSQL_BINLOG_H
#define MYSQL_BINLOG_H
#pragma once
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
@ -17,10 +16,13 @@
* @file mysql_binlog.h - Extracting information from binary logs
*/
#include <maxscale/cdefs.h>
#include <stdint.h>
#include <stdbool.h>
#include <time.h>
MXS_BEGIN_DECLS
/** Maximum GTID string length */
#define GTID_MAX_LEN 64
@ -91,4 +93,4 @@ uint64_t unpack_bit(uint8_t *ptr, uint8_t *null_mask, uint32_t col_count,
void format_temporal_value(char *str, size_t size, uint8_t type, struct tm *tm);
#endif /* MYSQL_BINLOG_H */
MXS_END_DECLS

View File

@ -1,5 +1,4 @@
#ifndef _MYSQL_UTILS_H
#define _MYSQL_UTILS_H
#pragma once
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
@ -13,10 +12,13 @@
* Public License.
*/
#include <maxscale/cdefs.h>
#include <stdlib.h>
#include <stdint.h>
#include <mysql.h>
#include <server.h>
#include <maxscale/server.h>
MXS_BEGIN_DECLS
/** Length-encoded integers */
size_t leint_bytes(uint8_t* ptr);
@ -27,7 +29,6 @@ uint64_t leint_consume(uint8_t ** c);
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
MXS_END_DECLS

View File

@ -1,5 +1,4 @@
#ifndef _NOTIFICATION_SERVICE_H
#define _NOTIFICATION_SERVICE_H
#pragma once
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
@ -27,6 +26,10 @@
* @endverbatim
*/
#include <maxscale/cdefs.h>
MXS_BEGIN_DECLS
#define _NOTIFICATION_CONNECT_TIMEOUT 30
#define _NOTIFICATION_OPERATION_TIMEOUT 30
#define _NOTIFICATION_SEND_PENDING 0
@ -57,4 +60,5 @@ typedef struct
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
MXS_END_DECLS

View File

@ -1,5 +1,4 @@
#ifndef _MAXSCALE_PCRE2_H
#define _MAXSCALE_PCRE2_H
#pragma once
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
@ -14,14 +13,8 @@
*
*/
#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
* @file pcre2.h - Utility functions for regular expression matching
* with the bundled PCRE2 library.
*
* @verbatim
@ -32,6 +25,18 @@
* @endverbatim
*/
#include <maxscale/cdefs.h>
MXS_BEGIN_DECLS
#if defined(PCRE2_CODE_UNIT_WIDTH)
#error PCRE2_CODE_UNIT_WIDTH already defined. Do not define, and include <maxscale/pcre2.h>.
#else
#define PCRE2_CODE_UNIT_WIDTH 8
#endif
#include <pcre2.h>
typedef enum
{
MXS_PCRE2_MATCH,
@ -44,4 +49,4 @@ mxs_pcre2_result_t mxs_pcre2_substitute(pcre2_code *re, const char *subject,
mxs_pcre2_result_t mxs_pcre2_simple_match(const char* pattern, const char* subject,
int options, int* error);
#endif
MXS_END_DECLS

View File

@ -1,5 +1,4 @@
#ifndef _PLATFORM_H
#define _PLATFORM_H
#pragma once
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
@ -13,6 +12,10 @@
* Public License.
*/
#include <maxscale/cdefs.h>
MXS_BEGIN_DECLS
#if !defined(__cplusplus)
#if __STDC_VERSION__ >= 201112
@ -48,4 +51,4 @@
#endif // __cplusplus
#endif // _PLATFORM_H
MXS_END_DECLS

View File

@ -1,5 +1,4 @@
#ifndef _POLL_H
#define _POLL_H
#pragma once
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
@ -12,10 +11,6 @@
* of this software will be governed by version 2 or later of the General
* Public License.
*/
#include <dcb.h>
#include <gwbitmask.h>
#include <resultset.h>
#include <sys/epoll.h>
/**
* @file poll.h The poll related functionality
@ -29,6 +24,15 @@
*
* @endverbatim
*/
#include <maxscale/cdefs.h>
#include <maxscale/dcb.h>
#include <maxscale/gwbitmask.h>
#include <maxscale/resultset.h>
#include <sys/epoll.h>
MXS_BEGIN_DECLS
#define MAX_EVENTS 1000
/**
@ -67,4 +71,5 @@ 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
MXS_END_DECLS

View File

@ -1,5 +1,4 @@
#ifndef _MYSQL_PROTOCOL_H
#define _MYSQL_PROTOCOL_H
#pragma once
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
@ -36,6 +35,7 @@
*
*/
#include <maxscale/cdefs.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
@ -54,15 +54,17 @@
#include <openssl/crypto.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <service.h>
#include <router.h>
#include <poll.h>
#include <users.h>
#include <dbusers.h>
#include <version.h>
#include <housekeeper.h>
#include <maxscale/service.h>
#include <maxscale/router.h>
#include <maxscale/poll.h>
#include <maxscale/users.h>
#include <maxscale/version.h>
#include <maxscale/housekeeper.h>
#include <maxscale/utils.h>
#include <mysql.h>
MXS_BEGIN_DECLS
#define GW_MYSQL_VERSION "5.5.5-10.0.0 " MAXSCALE_VERSION "-maxscale"
#define GW_MYSQL_LOOP_TIMEOUT 300000000
#define GW_MYSQL_READ 0
@ -70,6 +72,16 @@
#define MYSQL_HEADER_LEN 4L
#define MYSQL_CHECKSUM_LEN 4L
/**
* Offsets and sizes of various parts of the client packet. If the offset is
* defined but not the size, the size of the value is one byte.
*/
#define MYSQL_SEQ_OFFSET 3
#define MYSQL_COM_OFFSET 4
#define MYSQL_CHARSET_OFFSET 12
#define MYSQL_CLIENT_CAP_OFFSET 4
#define MYSQL_CLIENT_CAP_SIZE 4
#define GW_MYSQL_PROTOCOL_VERSION 10 // version is 10
#define GW_MYSQL_HANDSHAKE_FILLER 0x00
#define GW_MYSQL_SERVER_CAPABILITIES_BYTE1 0xff
@ -79,7 +91,11 @@
#define GW_MYSQL_SCRAMBLE_SIZE 20
#define GW_SCRAMBLE_LENGTH_323 8
#define DEFAULT_AUTH_PLUGIN_NAME "mysql_native_password"
/** Name of the default server side authentication plugin */
#define DEFAULT_MYSQL_AUTH_PLUGIN "mysql_native_password"
/** All authentication responses are at least this many bytes long */
#define MYSQL_AUTH_PACKET_BASE_SIZE 36
/** Maximum length of a MySQL packet */
#define MYSQL_PACKET_LENGTH_MAX 0x00ffffff
@ -88,7 +104,12 @@
# define MYSQL_SCRAMBLE_LEN GW_MYSQL_SCRAMBLE_SIZE
#endif
#define MYSQL_HOSTNAME_MAXLEN 60
/* 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
#define GW_NOINTR_CALL(A) do { errno = 0; A; } while (errno == EINTR)
#define SMALL_CHUNK 1024
@ -97,28 +118,6 @@
#define COM_QUIT_PACKET_SIZE (4+1)
struct dcb;
typedef enum
{
MYSQL_ALLOC, /* Initial state of protocol auth state */
/* The following are used only for backend connections */
MYSQL_PENDING_CONNECT,
MYSQL_CONNECTED,
/* The following can be used for either client or backend */
/* The comments have only been checked for client use at present */
MYSQL_AUTH_SENT,
MYSQL_AUTH_RECV, /* This is only ever a transient value */
MYSQL_AUTH_FAILED, /* Once this is set, the connection */
/* will be ended, so this is transient */
/* The following is used only for backend connections */
MYSQL_HANDSHAKE_FAILED,
/* The following are obsolete and will be removed */
MYSQL_AUTH_SSL_REQ, /*< client requested SSL but SSL_accept hasn't beed called */
MYSQL_AUTH_SSL_HANDSHAKE_DONE, /*< SSL handshake has been fully completed */
MYSQL_AUTH_SSL_HANDSHAKE_FAILED, /*< SSL handshake failed for any reason */
MYSQL_AUTH_SSL_HANDSHAKE_ONGOING, /*< SSL_accept has been called but the
* SSL handshake hasn't been completed */
MYSQL_IDLE
} mysql_auth_state_t;
typedef enum
{
@ -266,28 +265,29 @@ typedef struct
skygw_chk_t protocol_chk_top;
#endif
int fd; /*< The socket descriptor */
struct dcb *owner_dcb; /*< The DCB of the socket
* we are running on */
SPINLOCK protocol_lock;
mysql_server_cmd_t current_command; /**< Current command being executed */
struct dcb* owner_dcb; /*< The DCB of the socket we are running on */
SPINLOCK protocol_lock; /*< Protocol lock */
mysql_server_cmd_t current_command; /*< Current command being executed */
server_command_t protocol_command; /*< session command list */
server_command_t* protocol_cmd_history; /*< session command history */
mysql_auth_state_t protocol_auth_state; /*< Authentication status */
mxs_auth_state_t protocol_auth_state; /*< Authentication status */
mysql_protocol_state_t protocol_state; /*< Protocol struct status */
uint8_t scramble[MYSQL_SCRAMBLE_LEN]; /*< server scramble,
* created or received */
uint32_t server_capabilities; /*< server capabilities,
* created or received */
uint32_t client_capabilities; /*< client capabilities,
* created or received */
unsigned long tid; /*< MySQL Thread ID, in
* handshake */
uint8_t scramble[MYSQL_SCRAMBLE_LEN]; /*< server scramble, created or received */
uint32_t server_capabilities; /*< server capabilities, created or received */
uint32_t client_capabilities; /*< client capabilities, created or received */
unsigned long tid; /*< MySQL Thread ID, in handshake */
unsigned int charset; /*< MySQL character set at connect time */
bool ignore_reply; /*< If the reply should be discarded */
GWBUF* stored_query; /*< Temporarily stored queries */
#if defined(SS_DEBUG)
skygw_chk_t protocol_chk_tail;
#endif
} MySQLProtocol;
/** Defines for response codes */
#define MYSQL_REPLY_ERR 0xff
#define MYSQL_REPLY_OK 0x00
#define MYSQL_REPLY_AUTHSWITCHREQUEST 0xfe
/*
* Let's try this with proper enums instead of numbers
@ -307,12 +307,16 @@ typedef struct
#define MYSQL_GET_ERRCODE(payload) (gw_mysql_get_byte2(&payload[5]))
#define MYSQL_GET_STMTOK_NPARAM(payload) (gw_mysql_get_byte2(&payload[9]))
#define MYSQL_GET_STMTOK_NATTR(payload) (gw_mysql_get_byte2(&payload[11]))
#define MYSQL_IS_ERROR_PACKET(payload) ((int)MYSQL_GET_COMMAND(payload)==0xff)
#define MYSQL_IS_ERROR_PACKET(payload) ((int)MYSQL_GET_COMMAND(payload)==MYSQL_REPLY_ERR)
#define MYSQL_IS_COM_QUIT(payload) (MYSQL_GET_COMMAND(payload)==MYSQL_COM_QUIT)
#define MYSQL_IS_COM_INIT_DB(payload) (MYSQL_GET_COMMAND(payload)==MYSQL_COM_INIT_DB)
#define MYSQL_IS_CHANGE_USER(payload) (MYSQL_GET_COMMAND(payload)==MYSQL_COM_CHANGE_USER)
#define MYSQL_GET_NATTR(payload) ((int)payload[4])
/* The following can be compared using memcmp to detect a null password */
extern uint8_t null_client_sha1[MYSQL_SCRAMBLE_LEN];
MYSQL_session* mysql_session_alloc();
MySQLProtocol* mysql_protocol_init(DCB* dcb, int fd);
void mysql_protocol_done (DCB* dcb);
@ -346,27 +350,8 @@ int mysql_send_auth_error (
int in_affected_rows,
const char* mysql_message);
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);
void gw_str_xor(
uint8_t *output,
const uint8_t *input1,
const uint8_t *input2,
unsigned int len);
char *gw_bin2hex(char *out, const uint8_t *in, unsigned int len);
int gw_hex2bin(uint8_t *out, const char *in, unsigned int len);
int gw_generate_random_str(char *output, int len);
int setnonblocking(int fd);
int setipaddress(struct in_addr *a, char *p);
GWBUF* gw_MySQL_get_next_packet(GWBUF** p_readbuf);
GWBUF* gw_MySQL_get_packets(GWBUF** p_readbuf, int* npackets);
GWBUF* gw_MySQL_discard_packets(GWBUF* buf, int npackets);
void protocol_add_srv_command(MySQLProtocol* p, mysql_server_cmd_t cmd);
void protocol_remove_srv_command(MySQLProtocol* p);
bool protocol_waits_response(MySQLProtocol* p);
@ -383,5 +368,19 @@ void init_response_status (
mysql_server_cmd_t cmd,
int* npackets,
ssize_t* nbytes);
bool read_complete_packet(DCB *dcb, GWBUF **readbuf);
bool gw_get_shared_session_auth_info(DCB* dcb, MYSQL_session* session);
#endif /** _MYSQL_PROTOCOL_H */
/** Read the backend server's handshake */
bool gw_read_backend_handshake(DCB *dcb, GWBUF *buffer);
/** Send the server handshake response packet to the backend server */
mxs_auth_state_t gw_send_backend_auth(DCB *dcb);
/** Write an OK packet to a DCB */
int mxs_mysql_send_ok(DCB *dcb, int sequence, int affected_rows, const char* message);
/** Check for OK packet */
bool mxs_mysql_is_ok_packet(GWBUF *buffer);
MXS_END_DECLS

View File

@ -0,0 +1,466 @@
#pragma once
/*
* 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/cdefs.h>
#include <maxscale/buffer.h>
MXS_BEGIN_DECLS
#define QUERY_CLASSIFIER_VERSION {1, 1, 0}
/**
* qc_query_type_t defines bits that provide information about a
* particular statement.
*
* Note that more than one bit may be set for a single statement.
*/
typedef enum qc_query_type
{
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;
/**
* qc_query_op_t defines the operations a particular statement can perform.
*/
typedef enum qc_query_op
{
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;
/**
* qc_parse_result_t defines the possible outcomes when a statement is parsed.
*/
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;
/**
* qc_field_usage_t defines where a particular field appears.
*
* QC_USED_IN_SELECT : The field appears on the left side of FROM in a top-level SELECT statement.
* QC_USED_IN_SUBSELECT: The field appears on the left side of FROM in a sub-select SELECT statement.
* QC_USED_IN_WHERE : The field appears in a WHERE clause.
* QC_USED_IN_SET : The field appears in the SET clause of an UPDATE statement.
* QC_USED_IN_GROUP_BY : The field appears in a GROUP BY clause.
*
* Note that multiple bits may be set at the same time. For instance, for a statement like
* "SELECT fld FROM tbl WHERE fld = 1 GROUP BY fld", the bits QC_USED_IN_SELECT, QC_USED_IN_WHERE
* and QC_USED_IN_GROUP_BY will be set.
*/
typedef enum qc_field_usage
{
QC_USED_IN_SELECT = 0x01, /*< SELECT fld FROM... */
QC_USED_IN_SUBSELECT = 0x02, /*< SELECT 1 FROM ... SELECT fld ... */
QC_USED_IN_WHERE = 0x04, /*< SELECT ... FROM ... WHERE fld = ... */
QC_USED_IN_SET = 0x08, /*< UPDATE ... SET fld = ... */
QC_USED_IN_GROUP_BY = 0x10, /*< ... GROUP BY fld */
} qc_field_usage_t;
/**
* QC_FIELD_INFO contains information about a field used in a statement.
*/
typedef struct qc_field_info
{
char* database; /** Present if the field is of the form "a.b.c", NULL otherwise. */
char* table; /** Present if the field is of the form "a.b", NULL otherwise. */
char* column; /** Always present. */
uint32_t usage; /** Bitfield denoting where the column appears. */
} QC_FIELD_INFO;
/**
* QUERY_CLASSIFIER defines the object a query classifier plugin must
* implement and return.
*
* To a user of the query classifier functionality, it can in general
* be ignored.
*/
typedef 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* stmt);
uint32_t (*qc_get_type)(GWBUF* stmt);
qc_query_op_t (*qc_get_operation)(GWBUF* stmt);
char* (*qc_get_created_table_name)(GWBUF* stmt);
bool (*qc_is_drop_table_query)(GWBUF* stmt);
bool (*qc_is_real_query)(GWBUF* stmt);
char** (*qc_get_table_names)(GWBUF* stmt, int* tblsize, bool fullnames);
char* (*qc_get_canonical)(GWBUF* stmt);
bool (*qc_query_has_clause)(GWBUF* stmt);
char** (*qc_get_database_names)(GWBUF* stmt, int* size);
char* (*qc_get_prepare_name)(GWBUF* stmt);
qc_query_op_t (*qc_get_prepare_operation)(GWBUF* stmt);
void (*qc_get_field_info)(GWBUF* stmt, const QC_FIELD_INFO** infos, size_t* n_infos);
} QUERY_CLASSIFIER;
/**
* Loads and initializes the default query classifier.
*
* This must be called once during the execution of a process. The query
* classifier functions can only be used if this function returns true.
* MaxScale calls this function, so plugins should not do that.
*
* @param plugin_name The name of the plugin from which the query classifier
* should be loaded.
* @param plugin_args The arguments to be provided to the query classifier.
*
* @return True if the query classifier could be loaded and initialized,
* false otherwise.
*
* @see qc_end qc_thread_init
*/
bool qc_init(const char* plugin_name, const char* plugin_args);
/**
* Finalizes and unloads the query classifier.
*
* A successful call of qc_init() should before program exit be followed
* by a call to this function. MaxScale calls this function, so plugins
* should not do that.
*
* @see qc_init qc_thread_end
*/
void qc_end(void);
/**
* Loads a particular query classifier.
*
* In general there is no need to use this function, but rely upon qc_init().
* However, if there is a need to use multiple query classifiers concurrently
* then this function provides the means for that. Note that after a query
* classifier has been loaded, it must explicitly be initialized before it
* can be used.
*
* @param plugin_name The name of the plugin from which the query classifier
* should be loaded.
*
* @return A QUERY_CLASSIFIER object if successful, NULL otherwise.
*
* @see qc_unload
*/
QUERY_CLASSIFIER* qc_load(const char* plugin_name);
/**
* Unloads an explicitly loaded query classifier.
*
* @see qc_load
*/
void qc_unload(QUERY_CLASSIFIER* classifier);
/**
* Performs thread initialization needed by the query classifier.
* Should be called in every thread, except the one where qc_init()
* was called. MaxScale calls this function, so plugins should not
* do that.
*
* @return True if the initialization succeeded, false otherwise.
*
* @see qc_thread_end
*/
bool qc_thread_init(void);
/**
* Performs thread finalization needed by the query classifier.
* A successful call to qc_thread_init() should at some point be followed
* by a call to this function. MaxScale calls this function, so plugins
* should not do that.
*
* @see qc_thread_init
*/
void qc_thread_end(void);
/**
* Parses the statement in the provided buffer and returns a value specifying
* to what extent the statement could be parsed.
*
* There is no need to call this function explicitly before calling any of
* the other functions; e.g. qc_get_type(). When some particular property of
* a statement is asked for, the statement will be parsed if it has not been
* parsed yet. Also, if the statement in the provided buffer has been parsed
* already then this function will only return the result of that parsing;
* the statement will not be parsed again.
*
* @param stmt A buffer containing an COM_QUERY packet.
*
* @return To what extent the statement could be parsed.
*/
qc_parse_result_t qc_parse(GWBUF* stmt);
/**
* Convert a qc_field_usage_t enum to corresponding string.
*
* @param usage The value to be converted
*
* @return The corresponding string. Must @b not be freed.
*/
const char* qc_field_usage_to_string(qc_field_usage_t usage);
/**
* Convert a mask of qc_field_usage_t enum values to corresponding string.
*
* @param usage_mask Mask of qc_field_usage_t values.
*
* @return The corresponding string, or NULL if memory allocation fails.
* @b Must be freed by the caller.
*/
char* qc_field_usage_mask_to_string(uint32_t usage_mask);
/**
* Returns information about affected fields.
*
* @param stmt A buffer containing a COM_QUERY packet.
* @param infos Pointer to pointer that after the call will point to an
* array of QC_FIELD_INFO:s.
* @param n_infos Pointer to size_t variable where the number of items
* in @c infos will be returned.
*
* @note The returned array belongs to the GWBUF and remains valid for as
* long as the GWBUF is valid. If the data is needed for longer than
* that, it must be copied.
*/
void qc_get_field_info(GWBUF* stmt, const QC_FIELD_INFO** infos, size_t* n_infos);
/**
* Returns the statement, with literals replaced with question marks.
*
* @param stmt A buffer containing a COM_QUERY packet.
*
* @return A statement in its canonical form, or NULL if a memory
* allocation fails. The string must be freed by the caller.
*/
char* qc_get_canonical(GWBUF* stmt);
/**
* Returns the name of the created table.
*
* @param stmt A buffer containing a COM_QUERY packet.
*
* @return The name of the created table or NULL if the statement
* does not create a table or a memory allocation failed.
* The string must be freed by the caller.
*/
char* qc_get_created_table_name(GWBUF* stmt);
/**
* Returns the databases accessed by the statement. Note that a
* possible default database is not returned.
*
* @param stmt A buffer containing a COM_QUERY packet.
* @param size Pointer to integer where the number of databases
* is stored.
*
* @return Array of strings or NULL if a memory allocation fails.
*
* @note The returned array and the strings pointed to @b must be freed
* by the caller.
*/
char** qc_get_database_names(GWBUF* stmt, int* size);
/**
* Returns the operation of the statement.
*
* @param stmt A buffer containing a COM_QUERY packet.
*
* @return The operation of the statement.
*/
qc_query_op_t qc_get_operation(GWBUF* stmt);
/**
* Returns the name of the prepared statement, if the statement
* is a PREPARE or EXECUTE statement.
*
* @param stmt A buffer containing a COM_QUERY packet.
*
* @return The name of the prepared statement, if the statement
* is a PREPARE or EXECUTE statement; otherwise NULL.
*
* @note The returned string @b must be freed by the caller.
*
* @note Even though a COM_STMT_PREPARE can be given to the query
* classifier for parsing, this function will in that case
* return NULL since the id of the statement is provided by
* the server.
*/
char* qc_get_prepare_name(GWBUF* stmt);
/**
* Returns the operator of the prepared statement, if the statement
* is a PREPARE statement.
*
* @param stmt A buffer containing a COM_QUERY packet.
*
* @return The operator of the prepared statement, if the statement
* is a PREPARE statement; otherwise QUERY_OP_UNDEFINED.
*/
qc_query_op_t qc_get_prepare_operation(GWBUF* stmt);
/**
* Returns the tables accessed by the statement.
*
* @param stmt A buffer containing a COM_QUERY packet.
* @param tblsize Pointer to integer where the number of tables is stored.
* @param fullnames If true, a table names will include the database name
* as well (if explicitly referred to in the statement).
*
* @return Array of strings or NULL if a memory allocation fails.
*
* @note The returned array and the strings pointed to @b must be freed
* by the caller.
*/
char** qc_get_table_names(GWBUF* stmt, int* size, bool fullnames);
/**
* Returns a bitmask specifying the type(s) of the statement. The result
* should be tested against specific qc_query_type_t values* using the
* bitwise & operator, never using the == operator.
*
* @param stmt A buffer containing a COM_QUERY packet.
*
* @return A bitmask with the type(s) the query.
*
* @see qc_query_is_type
*/
uint32_t qc_get_type(GWBUF* stmt);
/**
* Returns whether the statement is a DROP TABLE statement.
*
* @param stmt A buffer containing a COM_QUERY packet.
*
* @return True if the statement is a DROP TABLE statement, false otherwise.
*
* @todo This function is far too specific.
*/
bool qc_is_drop_table_query(GWBUF* stmt);
/**
* Returns whether the statement is a "real" statement. Statements that affect
* the underlying database are considered real statements, while statements that
* target specific rows or variable data are regarded as real statement. That is,
* a real statement is SELECT, UPDATE, INSERT, DELETE or a variation thereof.
*
* @param stmt A buffer containing a COM_QUERY.
*
* @return True if the statement is a real query, false otherwise.
*
* @todo Consider whether the function name should be changed or the function
* removed altogether.
*/
bool qc_is_real_query(GWBUF* stmt);
/**
* Returns the string representation of a query operation.
*
* @param op A query operation.
*
* @return The corresponding string.
*
* @note The returned string is statically allocated and must *not* be freed.
*/
const char* qc_op_to_string(qc_query_op_t op);
/**
* Returns whether the typemask contains a particular type.
*
* @param typemask A bitmask of query types.
* @param type A particular qc_query_type_t value.
*
* @return True, if the type is in the mask.
*/
static inline bool qc_query_is_type(uint32_t typemask, qc_query_type_t type)
{
return (typemask & (uint32_t)type) == (uint32_t)type;
}
/**
* Returns whether the statement has a WHERE or a USING clause.
*
* @param stmt A buffer containing a COM_QUERY.
*
* @return True, if the statement has a WHERE or USING clause, false
* otherwise.
*/
bool qc_query_has_clause(GWBUF* stmt);
/**
* Returns the string representation of a query type.
*
* @param type A query type (not a bitmask of several).
*
* @return The corresponding string.
*
* @note The returned string is statically allocated and must @b not be freed.
*/
const char* qc_type_to_string(qc_query_type_t type);
/**
* Returns a string representation of a type bitmask.
*
* @param typemask A bit mask of query types.
*
* @return The corresponding string or NULL if the allocation fails.
*
* @note The returned string is dynamically allocated and @b must be freed.
*/
char* qc_typemask_to_string(uint32_t typemask);
MXS_END_DECLS

View File

@ -1,5 +1,4 @@
#ifndef _QUEUEMANAGER_H
#define _QUEUEMANAGER_H
#pragma once
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
@ -26,8 +25,11 @@
* @endverbatim
*/
#include <maxscale/cdefs.h>
#include <stdbool.h>
#include <spinlock.h>
#include <maxscale/spinlock.h>
MXS_BEGIN_DECLS
#define CONNECTION_QUEUE_LIMIT 1000
@ -67,4 +69,4 @@ mxs_queue_count(QUEUE_CONFIG *queue_config)
return count < 0 ? (count + queue_config->queue_limit + 1): count;
}
#endif /* QUEUEMANAGER_H */
MXS_END_DECLS

View File

@ -1,5 +1,4 @@
#ifndef RANDOM_JKISS_H
#define RANDOM_JKISS_H
#pragma once
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
@ -20,14 +19,10 @@
* Created on 26 August 2015, 15:34
*/
#ifdef __cplusplus
extern "C" {
#endif
#include <maxscale/cdefs.h>
MXS_BEGIN_DECLS
extern unsigned int random_jkiss(void);
#ifdef __cplusplus
}
#endif
#endif /* RANDOM_H */
MXS_END_DECLS

View File

@ -1,5 +1,4 @@
#ifndef _RDTSC_H
#define _RDTSC_H
#pragma once
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
@ -31,6 +30,10 @@
* @endverbatim
*/
#include <maxscale/cdefs.h>
MXS_BEGIN_DECLS
typedef unsigned long long CYCLES;
/**
@ -53,4 +56,5 @@ static __inline__ CYCLES rdtsc(void)
__asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
return x;
}
#endif
MXS_END_DECLS

View File

@ -1,5 +1,4 @@
#ifndef _RESULTSET_H
#define _RESULTSET_H
#pragma once
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
@ -24,8 +23,11 @@
*
* @endverbatim
*/
#include <dcb.h>
#include <maxscale/cdefs.h>
#include <maxscale/dcb.h>
MXS_BEGIN_DECLS
/**
* Column types
@ -85,4 +87,4 @@ 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
MXS_END_DECLS

View File

@ -1,5 +1,4 @@
#ifndef _ROUTER_H
#define _ROUTER_H
#pragma once
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
@ -25,13 +24,19 @@
* 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
* 08/11/2016 Massimiliano Pinto Add destroyInstance() entry point
*
*/
#include <service.h>
#include <session.h>
#include <buffer.h>
#include <maxscale/cdefs.h>
#include <maxscale/routing.h>
#include <maxscale/service.h>
#include <maxscale/session.h>
#include <maxscale/buffer.h>
#include <stdint.h>
MXS_BEGIN_DECLS
/**
* The ROUTER handle points to module specific data, so the best we can do
* is to make it a void * externally.
@ -77,7 +82,8 @@ typedef struct router_object
DCB* backend_dcb,
error_action_t action,
bool* succp);
int (*getCapabilities)();
uint64_t (*getCapabilities)(void);
void (*destroyInstance)(ROUTER *instance);
} ROUTER_OBJECT;
/**
@ -85,21 +91,22 @@ typedef struct router_object
* must update these versions numbers in accordance with the rules in
* modinfo.h.
*/
#define ROUTER_VERSION { 1, 0, 0 }
#define ROUTER_VERSION { 2, 0, 0 }
/**
* Router capability type. Indicates what kind of input router accepts.
* Specifies capabilities specific for routers. Common capabilities
* are defined by @c routing_capability_t.
*
* @see routing_capability_t
*
* @note The values of the capabilities here *must* be between 0x00010000
* and 0x80000000, that is, bits 16 to 31.
*/
typedef enum router_capability_t
typedef enum router_capability
{
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
RCAP_TYPE_NO_RSESSION = 0x00010000, /**< Router does not use router sessions */
RCAP_TYPE_NO_USERS_INIT = 0x00020000, /**< Prevent the loading of authenticator
users when the service is started */
} router_capability_t;
#endif
MXS_END_DECLS

View File

@ -0,0 +1,57 @@
#pragma once
/*
* 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 routing.h - Common definitions and declarations for routers and filters.
*/
#include <maxscale/cdefs.h>
MXS_BEGIN_DECLS
/**
* Routing capability type. Indicates what kind of input a router or
* a filter accepts.
*
* @note The values of the capabilities here *must* be between 0x0000
* and 0x8000, that is, bits 0 to 15.
*/
typedef enum routing_capability
{
/**< Statements are delivered one per buffer. */
RCAP_TYPE_STMT_INPUT = 0x0001, /* 0b0000000000000001 */
/**< Each delivered buffer is contiguous; implies RCAP_TYPE_STMT_INPUT. */
RCAP_TYPE_CONTIGUOUS_INPUT = 0x0003, /* 0b0000000000000011 */
/**< The transaction state and autocommit mode of the session are tracked;
implies RCAP_TYPE_CONTIGUOUS_INPUT and RCAP_TYPE_STMT_INPUT. */
RCAP_TYPE_TRANSACTION_TRACKING = 0x0007, /* 0b0000000000000111 */
} routing_capability_t;
#define RCAP_TYPE_NONE 0
/**
* Determines whether a particular capability type is required.
*
* @param capabilites The capability bits to be tested.
* @param type A particular capability type or a bitmask of types.
*
* @return True, if @c type is present in @c capabilities.
*/
static inline bool rcap_type_required(uint64_t capabilities, uint64_t type)
{
return (capabilities & type) == type;
}
MXS_END_DECLS

View File

@ -1,5 +1,4 @@
#ifndef _SECRETS_H
#define _SECRETS_H
#pragma once
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
@ -25,6 +24,7 @@
* @endverbatim
*/
#include <maxscale/cdefs.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
@ -32,9 +32,10 @@
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <openssl/aes.h>
MXS_BEGIN_DECLS
#define MAXSCALE_KEYLEN 32
#define MAXSCALE_IV_LEN 16
@ -56,4 +57,4 @@ extern int secrets_writeKeys(const char *directory);
extern char *decryptPassword(const char *);
extern char *encryptPassword(const char*, const char *);
#endif
MXS_END_DECLS

View File

@ -1,5 +1,4 @@
#ifndef _MAXSCALE_LIMITS_H
#define _MAXSCALE_LIMITS_H
#pragma once
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
@ -13,12 +12,11 @@
* Public License.
*/
// This file defines hard limits of MaxScale.
/**
* @file semaphore.h Semaphores used by 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
// As a minimal preparation for other environments than Linux, components
// include <maxscale/semaphore.h>, instead of including <semaphore.h>
// directly.
#include <semaphore.h>

View File

@ -1,5 +1,4 @@
#ifndef _SERVER_H
#define _SERVER_H
#pragma once
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
@ -12,8 +11,6 @@
* of this software will be governed by version 2 or later of the General
* Public License.
*/
#include <dcb.h>
#include <resultset.h>
/**
* @file service.h
@ -44,7 +41,15 @@
* @endverbatim
*/
#include <maxscale/cdefs.h>
#include <maxscale/dcb.h>
#include <maxscale/resultset.h>
MXS_BEGIN_DECLS
#define MAX_SERVER_NAME_LEN 1024
#define MAX_SERVER_MONUSER_LEN 512
#define MAX_SERVER_MONPW_LEN 512
#define MAX_NUM_SLAVES 128 /**< Maximum number of slaves under a single server*/
/**
@ -83,13 +88,16 @@ typedef struct server
#endif
SPINLOCK lock; /**< Common access lock */
char *unique_name; /**< Unique name for the server */
char *name; /**< Server name/IP address*/
char name[MAX_SERVER_NAME_LEN]; /**< 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 */
char *auth_options; /**< Authenticator options */
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 */
char monuser[MAX_SERVER_MONUSER_LEN]; /**< User name to use to monitor the db */
char monpw[MAX_SERVER_MONPW_LEN]; /**< 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 */
@ -107,6 +115,7 @@ typedef struct server
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 */
bool is_active; /**< Server is active and has not been "destroyed" */
#if defined(SS_DEBUG)
skygw_chk_t server_chk_tail;
#endif
@ -131,6 +140,11 @@ typedef struct server
#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 valid and active
*/
#define SERVER_IS_ACTIVE(server) (server->is_active)
/**
* 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
@ -192,9 +206,57 @@ typedef struct 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);
/**
* @brief Allocate a new server
*
* This will create a new server that represents a backend server that services
* can use. This function will add the server to the running configuration but
* will not persist the changes.
*
* @param name Unique server name
* @param address The server address
* @param port The port to connect to
* @param protocol The protocol to use to connect to the server
* @param authenticator The server authenticator module
* @param auth_options Options for the authenticator module
* @return The newly created server or NULL if an error occurred
*/
extern SERVER* server_alloc(const char *name, const char *address, unsigned short port,
const char *protocol, const char *authenticator,
const char *auth_options);
/**
* @brief Create a new server
*
* This function creates a new, persistent server by first allocating a new
* server and then storing the resulting configuration file on disk. This
* function should be used only from administrative interface modules and internal
* modules should use server_alloc() instead.
*
* @param name Server name
* @param address Network address
* @param port Network port
* @param protocol Protocol module name
* @param authenticator Authenticator module name
* @param options Options for the authenticator module
* @return True on success, false if an error occurred
*/
extern bool server_create(const char *name, const char *address, const char *port,
const char *protocol, const char *authenticator,
const char *options);
/**
* @brief Destroy a server
*
* This removes any created server configuration files and marks the server removed
* If the server is not in use.
* @param server Server to destroy
* @return True if server was destroyed
*/
bool server_destroy(SERVER *server);
extern int server_free(SERVER *);
extern SERVER *server_find_by_unique_name(char *);
extern SERVER *server_find_by_unique_name(const char *name);
extern SERVER *server_find(char *, unsigned short);
extern void printServer(SERVER *);
extern void printAllServers();
@ -211,13 +273,14 @@ 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 void server_update_credentials(SERVER *, char *, 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);
extern bool server_is_ssl_parameter(const char *key);
extern void server_update_ssl(SERVER *server, const char *key, const char *value);
#endif
MXS_END_DECLS

View File

@ -1,5 +1,4 @@
#ifndef _SERVICE_H
#define _SERVICE_H
#pragma once
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
@ -13,21 +12,6 @@
* Public License.
*/
#include <time.h>
#include <gw_protocol.h>
#include <spinlock.h>
#include <dcb.h>
#include <server.h>
#include <listener.h>
#include <filter.h>
#include <hashtable.h>
#include <resultset.h>
#include <maxconfig.h>
#include <queuemanager.h>
#include <openssl/crypto.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/dh.h>
/**
* @file service.h
*
@ -53,6 +37,26 @@
*
* @endverbatim
*/
#include <maxscale/cdefs.h>
#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/config.h>
#include <maxscale/queuemanager.h>
#include <openssl/crypto.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/dh.h>
MXS_BEGIN_DECLS
struct server;
struct router;
struct router_object;
@ -93,10 +97,16 @@ typedef struct
typedef struct server_ref_t
{
struct server_ref_t *next;
SERVER* server;
struct server_ref_t *next; /**< Next server reference */
SERVER* server; /**< The actual server */
int weight; /**< Weight of this server */
int connections; /**< Number of connections created through this reference */
bool active; /**< Whether this reference is valid and in use*/
} SERVER_REF;
/** Macro to check whether a SERVER_REF is active */
#define SERVER_REF_IS_ACTIVE(ref) (ref->active && SERVER_IS_ACTIVE(ref->server))
#define SERVICE_MAX_RETRY_INTERVAL 3600 /*< The maximum interval between service start retries */
/** Value of service timeout if timeout checks are disabled */
@ -108,6 +118,15 @@ typedef struct server_ref_t
*/
#define SERVICE_PARAM_UNINIT -1
/* 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
/**
* Defines a service within the gateway.
*
@ -131,6 +150,7 @@ typedef struct service
void *router_instance; /**< The router instance for this service */
char *version_string; /** version string for this service listeners */
SERVER_REF *dbref; /** server references */
int n_dbref; /** Number of server references */
SERVICE_USER credentials; /**< The cedentials of the service user */
SPINLOCK spin; /**< The service spinlock */
SERVICE_STATS stats; /**< The service statistics */
@ -152,6 +172,7 @@ typedef struct service
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 */
uint64_t capabilities; /*< The capabilities of the service. */
} SERVICE;
typedef enum count_spec_t
@ -173,10 +194,12 @@ 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, SSL_LISTENER *ssl);
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 void serviceRemoveBackend(SERVICE *, const SERVER *);
extern int serviceHasBackend(SERVICE *, SERVER *);
extern void serviceAddRouterOption(SERVICE *, char *);
extern void serviceClearRouterOptions(SERVICE *);
@ -221,4 +244,24 @@ extern RESULTSET *serviceGetList();
extern RESULTSET *serviceGetListenerList();
extern bool service_all_services_have_listeners();
#endif
/**
* Get the capabilities of the servive.
*
* The capabilities of a service are the union of the capabilities of
* its router and all filters.
*
* @return The service capabilities.
*/
static inline uint64_t service_get_capabilities(const SERVICE *service)
{
return service->capabilities;
}
/**
* Check if a service uses @c servers
* @param server Server that is queried
* @return True if server is used by at least one service
*/
bool service_server_in_use(const SERVER *server);
MXS_END_DECLS

View File

@ -1,5 +1,4 @@
#ifndef _SESSION_H
#define _SESSION_H
#pragma once
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
@ -33,14 +32,17 @@
*
* @endverbatim
*/
#include <maxscale/cdefs.h>
#include <time.h>
#include <atomic.h>
#include <buffer.h>
#include <listmanager.h>
#include <spinlock.h>
#include <resultset.h>
#include <skygw_utils.h>
#include <log_manager.h>
#include <maxscale/atomic.h>
#include <maxscale/buffer.h>
#include <maxscale/listmanager.h>
#include <maxscale/spinlock.h>
#include <maxscale/resultset.h>
#include <maxscale/log_manager.h>
MXS_BEGIN_DECLS
struct dcb;
struct service;
@ -69,6 +71,34 @@ typedef enum
SESSION_STATE_DUMMY /*< dummy session for consistency */
} session_state_t;
typedef enum
{
SESSION_TRX_INACTIVE_BIT = 1, /* 0b0001 */
SESSION_TRX_ACTIVE_BIT = 2, /* 0b0010 */
SESSION_TRX_READ_ONLY_BIT = 4, /* 0b0100 */
SESSION_TRX_READ_WRITE_BIT = 8, /* 0b1000 */
} session_trx_state_bit_t;
typedef enum
{
/*< There is no on-going transaction. */
SESSION_TRX_INACTIVE = SESSION_TRX_INACTIVE_BIT,
/*< A transaction is active. */
SESSION_TRX_ACTIVE = SESSION_TRX_ACTIVE_BIT,
/*< An explicit READ ONLY transaction is active. */
SESSION_TRX_READ_ONLY = (SESSION_TRX_ACTIVE_BIT | SESSION_TRX_READ_ONLY_BIT),
/*< An explicit READ WRITE transaction is active. */
SESSION_TRX_READ_WRITE = (SESSION_TRX_ACTIVE_BIT | SESSION_TRX_READ_WRITE_BIT)
} session_trx_state_t;
/**
* Convert transaction state to string representation.
*
* @param state A transaction state.
* @return String representation of the state.
*/
const char* session_trx_state_to_string(session_trx_state_t state);
/**
* The downstream element in the filter chain. This may refer to
* another filter or to a router.
@ -146,6 +176,8 @@ typedef struct session
UPSTREAM tail; /*< The tail of the filter chain */
int refcount; /*< Reference count on the session */
bool ses_is_child; /*< this is a child session */
session_trx_state_t trx_state; /*< The current transaction state. */
bool autocommit; /*< Whether autocommit is on. */
skygw_chk_t ses_chk_tail;
} SESSION;
@ -201,4 +233,123 @@ void session_disable_log_priority(SESSION* ses, int priority);
RESULTSET *sessionGetList(SESSIONLISTFILTER);
void process_idle_sessions();
void enable_session_timeouts();
#endif
/**
* Get the transaction state of the session.
*
* Note that this tells only the state of @e explicitly started transactions.
* That is, if @e autocommit is OFF, which means that there is always an
* active transaction that is ended with an explicit COMMIT or ROLLBACK,
* at which point a new transaction is started, this function will still
* return SESSION_TRX_INACTIVE, unless a transaction has explicitly been
* started with START TRANSACTION.
*
* Likewise, if @e autocommit is ON, which means that every statement is
* executed in a transaction of its own, this will return false, unless a
* transaction has explicitly been started with START TRANSACTION.
*
* @note The return value is valid only if either a router or a filter
* has declared that it needs RCAP_TYPE_TRANSACTION_TRACKING.
*
* @param ses The SESSION object.
* @return The transaction state.
*/
session_trx_state_t session_get_trx_state(const SESSION* ses);
/**
* Set the transaction state of the session.
*
* NOTE: Only the protocol object may call this.
*
* @param ses The SESSION object.
* @param new_state The new transaction state.
*
* @return The previous transaction state.
*/
session_trx_state_t session_set_trx_state(SESSION* ses, session_trx_state_t new_state);
/**
* Tells whether an explicit transaction is active.
*
* @see session_get_trx_state
*
* @note The return value is valid only if either a router or a filter
* has declared that it needs RCAP_TYPE_TRANSACTION_TRACKING.
*
* @return True if a transaction is active, false otherwise.
*/
static inline bool session_trx_is_active(const SESSION* ses)
{
return ses->trx_state & SESSION_TRX_ACTIVE_BIT;
}
/**
* Tells whether an explicit READ ONLY transaction is active.
*
* @see session_get_trx_state
*
* @note The return value is valid only if either a router or a filter
* has declared that it needs RCAP_TYPE_TRANSACTION_TRACKING.
*
* @return True if an explicit READ ONLY transaction is active,
* false otherwise.
*/
static inline bool session_trx_is_read_only(const SESSION* ses)
{
return ses->trx_state == SESSION_TRX_READ_ONLY;
}
/**
* Tells whether an explicit READ WRITE transaction is active.
*
* @see session_get_trx_state
*
* @note The return value is valid only if either a router or a filter
* has declared that it needs RCAP_TYPE_TRANSACTION_TRACKING.
*
* @return True if an explicit READ WRITE transaction is active,
* false otherwise.
*/
static inline bool session_trx_is_read_write(const SESSION* ses)
{
return ses->trx_state == SESSION_TRX_READ_WRITE;
}
/**
* Tells whether autocommit is ON or not.
*
* Note that the returned value effectively only tells the last value
* of the statement "set autocommit=...".
*
* That is, if the statement "set autocommit=1" has been executed, then
* even if a transaction has been started, which implicitly will cause
* autocommit to be set to 0 for the duration of the transaction, this
* function will still return true.
*
* Note also that by default autocommit is ON.
*
* @see session_get_trx_state
*
* @return True if autocommit has been set ON, false otherwise.
*/
static inline bool session_is_autocommit(const SESSION* ses)
{
return ses->autocommit;
}
/**
* Sets the autocommit state of the session.
*
* NOTE: Only the protocol object may call this.
*
* @param enable True if autocommit is enabled, false otherwise.
* @return The previous state.
*/
static inline bool session_set_autocommit(SESSION* ses, bool autocommit)
{
bool prev_autocommit = ses->autocommit;
ses->autocommit = autocommit;
return prev_autocommit;
}
MXS_END_DECLS

View File

@ -1,5 +1,4 @@
#ifndef _SPINLOCK_H
#define _SPINLOCK_H
#pragma once
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
@ -23,9 +22,11 @@
* 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 <skygw_debug.h>
EXTERN_C_BLOCK_BEGIN
#include <maxscale/cdefs.h>
#include <maxscale/debug.h>
MXS_BEGIN_DECLS
#define SPINLOCK_PROFILE 0
@ -74,6 +75,4 @@ 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
MXS_END_DECLS

View File

@ -1,5 +1,4 @@
#ifndef _STATISTICS_HG
#define _STATISTICS_HG
#pragma once
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
@ -25,8 +24,11 @@
* @endverbatim
*/
#include <maxscale/cdefs.h>
#include <stdint.h>
MXS_BEGIN_DECLS
typedef void* ts_stats_t;
/** stats_init should be called only once */
@ -68,4 +70,4 @@ ts_stats_set(ts_stats_t stats, int value, int thread_id)
((int64_t*)stats)[thread_id] = value;
}
#endif
MXS_END_DECLS

View File

@ -1,5 +1,4 @@
#ifndef _THREAD_H
#define _THREAD_H
#pragma once
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
@ -22,6 +21,10 @@
* of changes.
*/
#include <maxscale/cdefs.h>
MXS_BEGIN_DECLS
/**
* Thread type and thread identifier function macros
*/
@ -33,4 +36,4 @@ extern THREAD *thread_start(THREAD *thd, void (*entry)(void *), void *arg);
extern void thread_wait(THREAD thd);
extern void thread_millisleep(int ms);
#endif
MXS_END_DECLS

View File

@ -1,5 +1,4 @@
#ifndef _USERS_H
#define _USERS_H
#pragma once
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
@ -12,10 +11,6 @@
* of this software will be governed by version 2 or later of the General
* Public License.
*/
#include <hashtable.h>
#include <dcb.h>
#include <listener.h>
#include <openssl/sha.h>
/**
* @file users.h The functions to manipulate the table of users maintained
@ -33,6 +28,14 @@
* @endverbatim
*/
#include <maxscale/cdefs.h>
#include <maxscale/hashtable.h>
#include <maxscale/dcb.h>
#include <maxscale/listener.h>
#include <openssl/sha.h>
MXS_BEGIN_DECLS
#define USERS_HASHTABLE_DEFAULT_SIZE 52
/**
@ -60,14 +63,14 @@ typedef struct 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
extern int users_add(USERS *, const char *, const char *); /**< Add a user to the users table */
extern int users_delete(USERS *, const char *); /**< Delete a user from the users table */
extern const char *users_fetch(USERS *, const char *); /**< Fetch the authentication data for a user*/
extern int users_update(USERS *, const char *, const 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 */
extern int users_default_loadusers(SERV_LISTENER *port); /**< A generic implementation of the
authenticator loadusers entry point */
extern void usersPrint(const USERS *); /**< Print data about the users loaded */
extern void dcb_usersPrint(DCB *, const USERS *); /**< Print data about the users loaded */
#endif
MXS_END_DECLS

79
include/maxscale/utils.h Normal file
View File

@ -0,0 +1,79 @@
#pragma once
/*
* 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
*/
#include <maxscale/cdefs.h>
#include <ctype.h>
#include <math.h>
#include <stdlib.h>
#include <netinet/in.h>
MXS_BEGIN_DECLS
#define CALCLEN(i) ((size_t)(floor(log10(abs(i))) + 1))
#define UINTLEN(i) (i<10 ? 1 : (i<100 ? 2 : (i<1000 ? 3 : CALCLEN(i))))
#define MXS_ARRAY_NELEMS(array) ((size_t)(sizeof(array)/sizeof(array[0])))
bool utils_init(); /*< Call this first before using any other function */
void utils_end();
int setnonblocking(int fd);
int parse_bindconfig(const char *, struct sockaddr_in *);
int setipaddress(struct in_addr *, char *);
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);
char* trim(char *str);
char* squeeze_whitespace(char* str);
bool strip_escape_chars(char*);
bool is_valid_posix_path(char* path);
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 clean_up_pathname(char *path);
bool mxs_mkdir_all(const char *path, int mask);
long get_processor_count();
MXS_END_DECLS

View File

@ -11,8 +11,8 @@
* Public License.
*/
#include <modules.h>
#include <query_classifier.h>
#include <maxscale/modules.h>
#include <maxscale/query_classifier.h>
qc_parse_result_t qc_parse(GWBUF* querybuf)
{
@ -45,11 +45,6 @@ bool qc_is_drop_table_query(GWBUF* querybuf)
return false;
}
char* qc_get_affected_fields(GWBUF* buf)
{
return NULL;
}
bool qc_query_has_clause(GWBUF* buf)
{
return false;
@ -66,6 +61,22 @@ qc_query_op_t qc_get_operation(GWBUF* querybuf)
return QUERY_OP_UNDEFINED;
}
char* qc_sqlite_get_prepare_name(GWBUF* query)
{
return NULL;
}
qc_query_op_t qc_sqlite_get_prepare_operation(GWBUF* query)
{
return QUERY_OP_UNDEFINED;
}
void qc_sqlite_get_field_info(GWBUF* query, const QC_FIELD_INFO** infos, size_t* n_infos)
{
*infos = NULL;
*n_infos = 0;
}
bool qc_init(const char* args)
{
return true;
@ -125,8 +136,10 @@ extern "C"
qc_get_table_names,
NULL,
qc_query_has_clause,
qc_get_affected_fields,
qc_get_database_names,
qc_get_prepare_name,
qc_get_prepare_operation,
qc_get_field_info,
};
QUERY_CLASSIFIER* GetModuleObject()

File diff suppressed because it is too large Load Diff

View File

@ -5,7 +5,7 @@
#include "builtin_functions.h"
#include <stdlib.h>
#include <string.h>
#include <skygw_debug.h>
#include <maxscale/debug.h>
static struct
{

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More