If an error is generated while a COM_CHANGE_USER is being done, it would
always use the sequence number 1. To properly handle this case and send
the correct sequence number, the COM_CHANGE_USER progress needs to be
tracked at the session level.
The information needs to be shared between the backend and client
protocols as the final OK to the COM_CHANGE_USER, with the sequence number
3, is the one that the backend server returns. Only after this response
has been received and routed to the client can the COM_CHANGE_USER
processing stop.
As is explained in MDEV-19893:
Client reads from socket, gets the packet from 1. with seqno=0, which
it does not expect, since seqno is supposed to be incremented. Client
complains, throws tantrums and exceptions.
To cater for clients that do not expect out-of-bound messages
(i.e. server-initiated packets with seqno 0), all messages generated by
MaxScale should use at least sequence number 1.
If a packet with a KILL query was followed with another packet in the same
network buffer, the code wouldn't work as it expected to receive only one
packet at a time.
By iterating over the servers and sending the master's charset we are
guaranteed a "known good" charset. This also solves the problem where a
deactivated server reference would be used as the charset and server
version source.
If the authentication process fails due to an inability to start a
session, it should not be counted towards the number of failed
authentication attempts.
If a connection attempt is not accepted due to the host being blocked, the
protocol can now return an error message that is sent to the client. Only
mariadb_client implements this as it is the only one who calls the auth
failure methods in the first place.
The RateLimit class stores authentication failure data mapped by the
client IP addresses. The authentication failures are limited
per thread. The limits are still hard-coded and at least the number of
failures should be made configurable.
The simplest, most maintainable and acceptably efficient implementation
for DDoS protection is a thread-local unordered_map. The unwanted
side-effect of "scaling" of the number of allowed authentication failures
is unlikely to be problematic in most use-cases.
As the blocking of a host is only temporary, the behavior differs from the
one in the MariaDB server. This allows the number of failures to be set to
a much lower value negating some of the problems caused by the relatively
simple implementation.
Given the assumption that queries are rarely 16MB long and that
realistically the only time that happens is during a large dump of data,
we can limit the size of a single read to at most one MariaDB/MySQL packet
at a time. This change allows the network throttling to engage a lot
sooner and reduces the maximum overshoot of throtting to 16MB.
Some SQL clients may default to a different authentication plugin than
"mysql_native_password". Since this is the only one supported by MySQL-
authenticator, the client is instructed to swap its plugin.
There is a race condition between the addition of the DCB into epoll and
the execution of the event that initiates the protocol pointer for the DCB
and sends the handshake to the client. If a hangup event would occur
before the handshake would be sent, it would be possible that the DCB
would get freed before the code that sends the handshake is executed.
By picking the worker who owns the DCB before the DCB is placed into the
owner's epoll instance, we make sure no events arrive on the DCB while the
control is transferred from the accepting worker to the owning
worker.
The prefix was always added even when the original version would've been
acceptable. For example, a version string of 5.5.40 would get converted to
5.5.5-5.5.40 which is quite confusing for older client applications.
Minor renaming of the session state enum values. Also exposed the session
state stringification function in the public header and removed the
stringification macro.