[MDEV-15935] Connection Redirection Mechanism in MariaDB Client/Server Protocol Created: 2018-04-20 Updated: 2024-02-06 Resolved: 2023-10-26 |
|
| Status: | Closed |
| Project: | MariaDB Server |
| Component/s: | Protocol |
| Fix Version/s: | 11.3.1 |
| Type: | Task | Priority: | Critical |
| Reporter: | Alex Lee | Assignee: | Yuchen Pei |
| Resolution: | Fixed | Votes: | 0 |
| Labels: | Preview_11.3, client, protocol, proxy | ||
| Attachments: |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Issue Links: |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Description |
WhyRedirection mechanism is widely used in proxy-based scenario. What to doWe'll add a new global/session variable, say, redirect_url. The value should be an empty string or a connection string in the conventional format (in the style of a connection url of C/J or C/NodeJS or C/C or FederatedX). Internally the server might have a check to ensure that the value of this variable is a valid url. This variable is appended to the default value of session_track_system_variables variable. When this variable is changed, the existing SESSION_TRACK_SYSTEM_VARIABLES implementation will send its new value to the client as a part of the OK packet. It's up to the client or to the connector to use this value or to ignore it. Note that the server should not disallow changing of this variable in an active transaction. This is up to connectors, perhaps a connector would want to reconnect and replay the transaction. Thoughts
Possible use cases:
and so on. An ability to redirect any time using SQL to calculate a new location opens limitless possibilities. Original specs for comparison: What to DoClient/Server Protocol change needs both client and server support. Either connector support redirection mechanism and will close current connection and redirect to indicated value, or if not supporting redirection (or redirection is disable) then driver will continue using current connection. info field format is then:
HostDescription:
specific redirection option:
|
| Comments |
| Comment by Otto Kekäläinen [ 2018-04-26 ] | |||||||||||||||||
|
Thanks for the detailed feature specification. Do you have any patches / prototype code or something related to this? | |||||||||||||||||
| Comment by markus makela [ 2018-04-26 ] | |||||||||||||||||
|
A simple approach to this would be to have a dedicated proxy return an error packet telling the user that they should reconnect to another server. To clients that do not support it, it would look like an error. For unauthorized users, the normal authentication error message would be received. This would not require any protocol changes nor any changes on the server side. For example, the error that tells where to reconnect could be something like this:
A specific error number would need to be allocated for this purpose. This approach does have a vulnerability to man-in-the-middle attacks so usage of TLS is required with server certificate verification. A less invasive version of this would be to return the redirection target in a custom value with session_track_system_variables. This would allow older clients to connect via the proxy but newer clients could close the connection and create a direct connection to the redirection target. Using the OK packet to relay the information should also be easier for the connectors to process as no string parsing is required. | |||||||||||||||||
| Comment by Georg Richter [ 2018-05-07 ] | |||||||||||||||||
|
The capability flag should be defined in extended capabilities, 1UL << 31 is already used by CLIENT_REMEMBER_OPTIONS #define MARIADB_CLIENT_SERVER_REDIRECTION (1ULL << 35) I would suggest the following:
| |||||||||||||||||
| Comment by xiangyhu [ 2018-05-09 ] | |||||||||||||||||
|
otto, markus makela, georg, Hi, thanks for your feedback. Please see the pcap attached. We prototyped the client code and server code based on mysql. The first logon (1,2) was non-ssl, which was supposed to uncover the unencrypted flow. The logon failed because it disobeyed the ssl enforcement (packet#2118) (markus makela, you are totally correct, we enforce TLS here). The second logon (3,4) was a successful logon. Please open the pcap for detailed fields. We used 1UL << 28 now to avoid conflict. Use "tcp.port==16003||tcp.port==3306" to filter the mysql traffic we want (16003 was the redirected tcp port). Thanks, | |||||||||||||||||
| Comment by Vladislav Vaintroub [ 2018-05-09 ] | |||||||||||||||||
| |||||||||||||||||
| Comment by xiangyhu [ 2018-05-10 ] | |||||||||||||||||
|
wlad Hi, regarding your questions,
Thanks, | |||||||||||||||||
| Comment by Vladislav Vaintroub [ 2018-05-10 ] | |||||||||||||||||
|
I see.
| |||||||||||||||||
| Comment by Georg Richter [ 2018-05-10 ] | |||||||||||||||||
|
xiangyhu: As I mentioned before, please use extended capabilities (see include/mariadb_com.h of MariaDB Connector/C). Since 10.2 we don't use the 32-bit flags anymore and also obsoleted the CLIENT_PROGRESS flag and moved it to extended capabilities. vlad:
| |||||||||||||||||
| Comment by Vladislav Vaintroub [ 2018-05-10 ] | |||||||||||||||||
|
georg "redirection should be allowed only for secure (TLS) connections" , is not that an arbitrary restriction? Is this also like this in HTTP? | |||||||||||||||||
| Comment by xiangyhu [ 2018-05-10 ] | |||||||||||||||||
|
Thank you for your suggestions.
Please let me know your thoughts. Thanks! + cvicentiu for awareness. Thanks, | |||||||||||||||||
| Comment by xiangyhu [ 2018-05-10 ] | |||||||||||||||||
|
georg Are you talking about this one? if (server_capabilities & CLIENT_MYSQL) Which bit do you recommend we use? Thanks you! | |||||||||||||||||
| Comment by Georg Richter [ 2018-05-10 ] | |||||||||||||||||
|
The next free bit, which should be (1ULL << 35) | |||||||||||||||||
| Comment by Vladislav Vaintroub [ 2018-05-10 ] | |||||||||||||||||
|
Maybe someone has a better idea on that, but I believe you can grab some error code you like from the higher range , and hardcode it ( progress reporting hijacked 0xFFFF already) I.e you can define ERR_SERVER_REDIRECT as 0xF301 (to commemorate HTTP code 301) and send (intentionally) non-localizable error message as "Location: <host>:<port>" . | |||||||||||||||||
| Comment by xiangyhu [ 2018-05-10 ] | |||||||||||||||||
|
Thank you georg. Sorry I missed your previous comment: Quote I would suggest the following: Server always sends an error (with a new error number), e.g. ER_CONNECTION_REDIRECT
Thanks, | |||||||||||||||||
| Comment by Vladislav Vaintroub [ 2018-05-10 ] | |||||||||||||||||
|
there are 64K error codes, and there is already an area reserved for MariaDB. There won't be errors allocated in the highest range. It is very unexpected. Network analyzers are aware of error packets, 3rd party drivers are, documentation is there, so extending protocol to new type of packet, better not. Less is better here. Parsing overhead is minimal, as compared to all the exchanges already done. | |||||||||||||||||
| Comment by markus makela [ 2018-05-10 ] | |||||||||||||||||
|
The one extra benefit that the OK packet has is the ability to fall back to normal proxy behavior if the client does not support it (meaning that the client would have to be smart enough to pick up the extra variables). This would still allow abstraction of the cluster that the proxy is in front of without any reduction to supported connectors. | |||||||||||||||||
| Comment by Vladislav Vaintroub [ 2018-05-10 ] | |||||||||||||||||
|
And yes, you should not send error if client is not aware of redirection, I think, and proxy transparently. | |||||||||||||||||
| Comment by markus makela [ 2018-05-10 ] | |||||||||||||||||
|
Another use for the error would be to redirect new connections to a fallback server if a server is going down for maintenance. | |||||||||||||||||
| Comment by Vladislav Vaintroub [ 2018-05-10 ] | |||||||||||||||||
|
Yes, markus makela, I like OK better, too. One could assume that MARIADB_CLIENT_SUPPORT_REDIRECT can parse the extra stuff in OK packet from authentication even if client does not specify the capability when connecting. | |||||||||||||||||
| Comment by Vladislav Vaintroub [ 2018-05-10 ] | |||||||||||||||||
|
So, to summarize what I think of it , is that
So, using session_track_system_variables is actually ideal, with special variable, and added stuff in OK packet. This does not extend the protocol, allows aware clients to disconnect, unaware clients to transparent proxy.markus makela, nice ideas, from start on. And xiangyhu, if you do not want actual backend server to support session tracking , backend does not have to send CLIENT_SESSION_TRACK in server welcome packet, but proxy should | |||||||||||||||||
| Comment by Georg Richter [ 2018-05-10 ] | |||||||||||||||||
|
Why not use a CR error code (CR_CONNECTION_REDIRECT) ? The server never will return this error, it is only used by client and proxy. If the redirection information is part of the error message, the proxy should always send this error:
| |||||||||||||||||
| Comment by Diego Dupin [ 2018-05-10 ] | |||||||||||||||||
|
I agree with markus makela: this CLIENT_SESSION_TRACK has been created because of all bits of OK_Packet status flag where nearly set. Using CLIENT_SESSION_TRACK permit to indicate extra information in a dedicated format when needed. And this format is extensible then : like redirect to x.x.x.x for master, y.y.y.y for reads. >We currently disable CLIENT_SESSION_TRACK in our service. We do not want to introduce extra networking overheads for now. | |||||||||||||||||
| Comment by Vladislav Vaintroub [ 2018-05-10 ] | |||||||||||||||||
|
Ok, I think here is probably the best thing I can think of, that does not involve session tracking. string<lenenc> info human readable status information in the post-authentication OK packet That looks like a hack, and does mean that aware clients would actually need to read at least 1 byte of this "human readable information" and compare this to 'L', but this seems like a small price for compatibility it offers. | |||||||||||||||||
| Comment by xiangyhu [ 2018-05-10 ] | |||||||||||||||||
|
wlad diego dupin markus makela, what would happen if client is expecting authentication switch packet from the real server after proxy sends the login packet to the backend but it gets ok packet? | |||||||||||||||||
| Comment by Diego Dupin [ 2018-05-10 ] | |||||||||||||||||
|
authentication always finish by an OK or Error packet, even when using authentication switch packet. wlad why need a hack. driver does alredy support session tracking. Better to have a proper format. REDIRECTION | |||||||||||||||||
| Comment by Vladislav Vaintroub [ 2018-05-10 ] | |||||||||||||||||
|
xiangyhu - nothing bad I guess. Client never really expects authentication switch in MariaDB. If server sends it, client handles it . If server sends OK, authentication is considered successful. diego - I refered to other part of OK, and quoted the MySQL docs, not to tracking , but to "human readable" in this string is always sent disregarding session tracking, and after update contains something like "n rows affected". Also , there is no the driver . there is are multiple drivers, and some support session tracking, and some do not. some would sent client flag, and some would not. I would not need it by default | |||||||||||||||||
| Comment by xiangyhu [ 2018-05-10 ] | |||||||||||||||||
|
diego dupin, wlad I mean capability flag is needed. Think about a client who does not support redirection gets an okay packet with redirection info, it will treat it as login success. But actually, there are other packet types could be sent at this stage that does not mean a successful login, authentication switch packet is one of them. So server must be able to distinguish the client capability to redirect and shutdown connection or proceed the normal login. | |||||||||||||||||
| Comment by markus makela [ 2018-05-10 ] | |||||||||||||||||
|
wlad oh, that would probably be the least invasive way to implement this (I completely forgot that OK packets can have arbitrary strings). This would give the best of both worlds in regards to the human-readability of an ERR packet with the transparency of the OK packet. | |||||||||||||||||
| Comment by Vladislav Vaintroub [ 2018-05-10 ] | |||||||||||||||||
|
xiangyhu, then send an error, instead of OK, if your proxy does not perform authentication . There is no need in capability flag still Authentication ends up with an OK packet, this is how it is defined. Or with error packet. | |||||||||||||||||
| Comment by xiangyhu [ 2018-05-10 ] | |||||||||||||||||
|
wlad, if there is no capability flag, proxy will shutdown all connections with redirection info wrapped in error packet, not falling back to proxied connections. | |||||||||||||||||
| Comment by Vladislav Vaintroub [ 2018-05-10 ] | |||||||||||||||||
|
if you can fall back to transparent proxy, then you can do authentication, including pluggable one. | |||||||||||||||||
| Comment by xiangyhu [ 2018-05-10 ] | |||||||||||||||||
|
wlad I understand your point now. So you are having client doing two full authentication, either of which ends with an ok/err message, while within the first one there could be a redirection info which is up to the client to choose to perform another direct connection. | |||||||||||||||||
| Comment by xiangyhu [ 2018-05-14 ] | |||||||||||||||||
|
wlad markus makela could you kindly let know what's our next step to push redirection feature to the next step? Shall we come to a documented proposal or publish a pull request directly? Thank you! xiangyhu | |||||||||||||||||
| Comment by xiangyhu [ 2018-06-22 ] | |||||||||||||||||
|
wlad markus makela I am preparing the pull request for this. I need your input on the format of redirection information returned as part of the human readable message within the OK packet. I am thinking of a comma delimited string separating host, port, user, etc.. Do you have any suggestions? | |||||||||||||||||
| Comment by Vladislav Vaintroub [ 2018-06-22 ] | |||||||||||||||||
|
Why not "Location: mysql://<host>:<port>/key=value&key2=value2" we're already using HTTP-like redirection, thus URL syntax seems logical to me IPv6 addresses are given in square brackets using this notation mysql://[2001:db8:85a3:8d3:1319:8a2e:370:7348]:3307/ | |||||||||||||||||
| Comment by markus makela [ 2018-06-22 ] | |||||||||||||||||
|
An URL does seem like a nice way to pass the information in one "payload". I'd recommend going this route if the redirection is to be given in the OK packet info message. Instead of using a URL string, I would prefer to use the session state tracking information as described in the OK Packet documentation. Having the information readily split into a list of variables would make it significantly easier to convert to native types. For example, reserving the _redirect_host and _redirect_port system variables would make it very easy to use this information in environments that do not directly consume JDBC URL formats. This should not be a problem for connectors that would understand redirection as it is quite likely that they already support session state tracking. | |||||||||||||||||
| Comment by Diego Dupin [ 2018-07-02 ] | |||||||||||||||||
|
The 2 solutions are ok, using human readable or session state tracking, but i tend to agree with markus makela : It's better to have structured format using ok_packet than hacking the "human readable" string value. | |||||||||||||||||
| Comment by libin [ 2018-07-02 ] | |||||||||||||||||
|
@markus makela and @diego dupin do you means you prefer to use the info property as shown below? if yes, I suspect the string<lenenc> info format would be like: | |||||||||||||||||
| Comment by markus makela [ 2018-07-02 ] | |||||||||||||||||
|
I'm referring to the list of values that follow that info value. It is a list of items that support key-values. | |||||||||||||||||
| Comment by libin [ 2018-07-02 ] | |||||||||||||||||
|
do you means the format as: the total length encoded bytes, followed by list of the key-values? total size of key-values
| |||||||||||||||||
| Comment by libin [ 2018-07-02 ] | |||||||||||||||||
|
as you mentioned, "I'm referring to the list of values that follow that info value. It is a list of items that support key-values." I am not sure whether this format would confused the current driver, since this format is intended to pass the "SERVER_SESSION_STATE_CHANGE" info, NOT the redirection info | |||||||||||||||||
| Comment by Vladislav Vaintroub [ 2018-07-02 ] | |||||||||||||||||
|
One can argue that redirection is state change. Basically state change is an opaque thing, not further specified. It is a way for the server to send keys and values. | |||||||||||||||||
| Comment by libin [ 2018-07-02 ] | |||||||||||||||||
|
@Vladislav Vaintroub from the spec of https://mariadb.com/kb/en/library/ok_packet/#server-status-flag I am not sure whether it support list of key-values In login packet, it spec to allow loop for key-values, but in ok packet, I don't see the loop | |||||||||||||||||
| Comment by libin [ 2018-07-03 ] | |||||||||||||||||
|
Hi, sorry for my misunderstanding for the OK packet format, I check the source code, and I think it can append list of changed system variables via the session_tracker So I think the key-values list is available for the redirection scenario But one thing is, only the MySQL/maria db 5.7 or above version support the CLIENT_SESSION_TRACK feature, and I think there are still many customers are using MySQL/Maria db 5.6 version so I think a readable connection string in the OK packet may be suitable | |||||||||||||||||
| Comment by markus makela [ 2018-07-03 ] | |||||||||||||||||
|
Since those versions don't support redirection it doesn't matter. In those cases the extra information will not be sent and the client will connect normally with both old client and old server. | |||||||||||||||||
| Comment by libin [ 2018-07-03 ] | |||||||||||||||||
|
@markus makela I think redirection does not depends on CLIENT_SESSION_TRACK feature, if ok packet can return redirection info to client driver, and client driver can recognize this info, the feature can work we do want to support border range of version both for MariaDB and MySQL, I am thinking that, if session_tracking_supported IS NOT enable, we just return a readable redirection connection string in the OK packet, if session_tracking_supported is enable, we add the redirection info into the list of key-value of session state info | |||||||||||||||||
| Comment by markus makela [ 2018-07-03 ] | |||||||||||||||||
|
Yes, that is a valid option but implementing it means doubling the amount of functionality which inevitably leads to double the work. I'd suggest compiling an initial list of connectors that would be willing to implement the reconnection functionality and then see which of those support session tracking. Given that all MariaDB connectors support session tracking, I don't think it would be a very big restriction to require the connector to implement session tracking in order for it to support connection redirection. | |||||||||||||||||
| Comment by Vladislav Vaintroub [ 2018-07-03 ] | |||||||||||||||||
|
I suggest to do either URL in a readable format (no length encoding here, please). Or list in OK packet, with CLIENT_SESSION_TRACK. markus makela, parsing the URL is not a big deal, really. Not much more complicated than handle the length encoded list. | |||||||||||||||||
| Comment by markus makela [ 2018-07-03 ] | |||||||||||||||||
|
wlad That's true, I think using it would be OK. | |||||||||||||||||
| Comment by libin [ 2018-07-04 ] | |||||||||||||||||
|
@Vladislav Vaintroub and @markus makela would you please help to have a check for the code review: https://github.com/MariaDB/server/compare/10.3...libliang17:10.3 many thanks | |||||||||||||||||
| Comment by xiangyhu [ 2018-07-10 ] | |||||||||||||||||
|
markus makela, wlad Thanks for your feedbacks. The above pull request implements the JDBC formatted string returned within the OK packet in string format. Could you kindly help to review? thanks, | |||||||||||||||||
| Comment by Bradley Grainger [ 2020-04-03 ] | |||||||||||||||||
|
Can we ensure that the redirection data put into the "human readable status information" field has a terminator, e.g., \n? If we use just "Location: mysql://%s:%s/user=%s" (e.g., from https://github.com/MariaDB/server/compare/10.3...libliang17:10.3#diff-dca2f11b2511ceff9960dc3bcd972d04R13526) then we have no good way to extend this field for future needs. Clients will assume the user ID extends to the end of the packet, which will not allow other information to be added to the OK packet in the future. Instead, we should say that the redirection header must be terminated by LF (or CR LF if you want to be just like HTTP) and not by the end of the packet. Servers have to emit the terminator and clients have to stop processing the Location "header" when the terminator is found. | |||||||||||||||||
| Comment by Sergei Golubchik [ 2022-05-30 ] | |||||||||||||||||
|
What about a somewhat different approach: use not the info field of the OK packet, but the session state info of the OK packet, in particular the with the type being SESSION_TRACK_SYSTEM_VARIABLES, variable name being "redirect_url" (or any other better string) and the value being the url in the mysql://username@host:port/database?options syntax, as in FederatedX. Benefits:
of course, it doesn't mean the client has to follow redirects in the middle of the session or at all, it only means that the server has a possibility of asking for it | |||||||||||||||||
| Comment by markus makela [ 2022-06-10 ] | |||||||||||||||||
|
We'll need at least the design part of this to be resolved in order for MXS-4153 to be doable. | |||||||||||||||||
| Comment by markus makela [ 2023-04-17 ] | |||||||||||||||||
|
From the MaxScale perspective, parsing the session state information is very simple to implement. This should allow MaxScale to gracefully move the traffic away from the server without having to do it in multiple places. The same design should be relatively simple to implement for anything that MaxScale wants to generate internally and send to the clients. Since the APIs exist for the connector-c, testing this is also very straightforward. All in all, I think the use of session state change notifications would be a more flexible and well-defined approach compared to injecting text messages into the OK packet. | |||||||||||||||||
| Comment by Daniel Lenski [ 2023-04-20 ] | |||||||||||||||||
|
Few questions about the intended result(s) of redirection…
| |||||||||||||||||
| Comment by markus makela [ 2023-04-20 ] | |||||||||||||||||
|
If the approach taken is to embed the redirection request into the variable length data (i.e. SESSION_TRACK_SYSTEM_VARIABLES) of an OK packet, the feature would be an opt-in one and as such it would not have any effect on clients that do not understand it. This also means that any response, be it a resultset or an OK response, could be used to start a redirection. This includes even the very first OK packet that's sent as the final step of the authentication process. I would imagine that if the driver is aware of the transaction state, it could safely do the redirection at a point right after a transaction has committed. If the driver does not support the redirection, it would behave as if the feature never existed and would happily continue using it even if a server requested to redirect on every request. I don't see a need to limit redirection in the server. It seems like something that could be controlled at the driver level with a maximum redirection count to prevent infinite loops. | |||||||||||||||||
| Comment by Daniel Lenski [ 2023-04-20 ] | |||||||||||||||||
|
markus makela wrote:
Ack, makes sense. That seems like a good approach given the greater flexibility it affords, in terms of the timing of the redirect.
Agreed. I was thinking more about the case where the redirect occurs at another point; not after a commit (or rollback), but in the middle of another one.
Agreed. It would be better to have this managed in the driver/client layer. Should that line be removed from the description then? ("There is no recursion, meaning that connector that have been redirect will not take another redirection in account.").
I am thinking more about how much state the server would have to manage here, particularly for supporting old/misconfigured clients. Should the server have to care that it has attempted to redirect a client, and the client has ignored that redirect (perhaps because it's an old client that doesn't know about the redirect)? If the server could embed a mid-transaction redirect in an ERR_packet indicating a rollback, this would induce old clients not to continue as if nothing had happened. Basically, consider this^ a sub-case of a more general problem: "how much effort should the server have to put into maintaining an ongoing connection for a client which has received a redirect, but continued to ignore it?" And my argument here is that this should be made as simple as possible for the server:
| |||||||||||||||||
| Comment by markus makela [ 2023-04-21 ] | |||||||||||||||||
serg could you update the description to match the current design? Not having to go through the comment history hopefully makes this easier for driver implementors to read.
The minimal amount of effort for the server is to only send the notification once when the global variable is changed by an administrator. From what I understand of serg's comments, this is very straightforward and a new global variable takes care of the server-side implementation. However I think that if the server is capable of retransmitting the notification for every request, the client side implementation gets easier as it can be written in a stateless manner, in other words, redirections in the middle of transactions are just ignored and the redirection in the COMMIT response is what trigger the redirection. For the client-side implementation, most of the drivers comprehend the extra data and some (e.g. the C connector) already expose the contents at the API level. This means that once the feature is added, it's possible to use even very old versions of the drivers to emulate support for redirection. From a practical point of view, I think this'll have to be something for the drivers to implement before it gets used. My experience with custom error messages is that if the driver or the application doesn't expect it, in the best case, it gracefully retries the transaction. More often than not it seems like drivers just pass it onto the application and the application itself just aborts everything and closes the connection. This would make the redirection faster but it wouldn't make it very graceful. A transaction rollback error would probably be something that applications can at least comprehend, for example MaxScale supports retrying of transactions that run into a deadlock error. However, there are cases where transactions cannot be replayed and as such the approach of returning errors where non-error responses would normally be generated is inherently disruptive. In my mind the process of gracefully taking down a server with this feature would be:
| |||||||||||||||||
| Comment by Daniel Lenski [ 2023-04-21 ] | |||||||||||||||||
The server-side implementation (no state) also gets easier if the server retransmits it in this way.
Okay.
It still seems to me that this process would work better for old clients if the redirect gets embedded in…
Am I understanding that your objection to this, markus makela, is that some clients will just ignore-and-retry after any error? That doesn't seem like too much of a downside; at least some clients will recognize the error and realize they need to immediately stop connecting to this server. | |||||||||||||||||
| Comment by Daniel Lenski [ 2023-04-21 ] | |||||||||||||||||
|
Way back, georg also proposed implementing the redirect with a custom error. | |||||||||||||||||
| Comment by markus makela [ 2023-04-22 ] | |||||||||||||||||
|
I think that if the response type (Err instead of OK) changes, this is not a graceful redirection and it turns into a forceful redirection. This is probably something that is not always wanted and if the idea is to make it opt-in, modifying the behavior breaks that goal. In addition, since old clients won't have any idea what to do with the error, they'll just report it back to the application. This sort of stop connecting to this server kind of behavior can be implemented on top of the redirection but I don't think it's a core part of it. For a prompt shutdown, this would be a good feature similar to read_only) but a more forceful one that prevents all actions from being done. In the list of steps I listed previously, it would be after the first graceful redirection step and after max_connections is lowered to prevent new connections. | |||||||||||||||||
| Comment by Daniel Lenski [ 2023-04-24 ] | |||||||||||||||||
Agreed. I wasn't totally clear on whether there were less-than-forceful redirection scenarios envisioned here.
Agree. | |||||||||||||||||
| Comment by markus makela [ 2023-06-26 ] | |||||||||||||||||
|
Is the name of the variable going to be redirect_url? Getting that locked in early would allow MaxScale to use the same name for it. | |||||||||||||||||
| Comment by Yuchen Pei [ 2023-06-27 ] | |||||||||||||||||
|
markus makela I will know after I start working on it next development cycle. Maybe serg can comment on this? | |||||||||||||||||
| Comment by markus makela [ 2023-06-28 ] | |||||||||||||||||
|
I ended up making the initial version of this in MaxScale very generic in the form of a customizable metadata string of the form connection_metadata=key=value,key2=value2 that's added to the OK packet that's sent once authentication is complete. The values are encoded as system variable changes as was suggested by serg. This should make it possible to use it to implement basic connection redirection that's intended for graceful shutdowns. | |||||||||||||||||
| Comment by Daniel Lenski [ 2023-06-29 ] | |||||||||||||||||
|
I've recently submitted a working implementation:
The very short summary of how it works is:
| |||||||||||||||||
| Comment by markus makela [ 2023-06-29 ] | |||||||||||||||||
|
I took a look at the client-side pull request (
For the server-side pull request, I don't have much comments apart from the implementation approach. In its current incarnation it's a forceful redirection and doesn't allow any of the other use-cases described in this issue (e.g. zero-overhead proxying) from being implemented on top of it. However, I also think that the feature which uses the system variable tracker can be built on top of the suggested error packet implementation. It would cover use-cases other than forceful redirection and also make it possible to have a longer redirection period. As such, I'd name the value for server_redirect_mode as FORCE rather than ON: this way the door is left open for a less intrusive method of redirection which would also solve the problem you've described in CONC-648. | |||||||||||||||||
| Comment by Sergei Golubchik [ 2023-06-30 ] | |||||||||||||||||
|
More thoughts about the session_track_system_variables approach:
Let's get compare with the "error message" approach:
But (drawbacks):
It seems to me that session tracking is still preferable, despite its deficiencies. | |||||||||||||||||
| Comment by Daniel Lenski [ 2023-06-30 ] | |||||||||||||||||
|
markus makela wrote:
Absolutely. My very minimal client-side implementation at mariadb-connector-c #226 could/should be extended to offer --no-follow-redirects as an option.
Indeed. Since I'm trying to follow the battle-tested semantics of HTTP(S) clients here, I think it would make sense to implement this in terms of a client-side "max redirection" limit, like most web browsers have. And cURL has:
Good idea!
CONC-648 is a vulnerability caused by a TLS-using client to improperly trust information that is sent in plaintext prior to the TLS handshake. In CONC-654/MDEV-31585, it's even worse: the server actually requires certain client configuration information to be sent in plaintext, and ignores it when it's subsequently sent over the TLS channel. CONC-648 makes an Error-packet-based redirection mechanism extremely exploitable by a MITM attacker; but not having such a mechanism doesn't solve CONC-648 in any way. | |||||||||||||||||
| Comment by markus makela [ 2023-07-01 ] | |||||||||||||||||
|
Oh yes, I didn't express myself correctly: if the implementation of redirection is done post-authentication, a problem similar to CONC-648 would be avoided. It doesn't solve CONC-648 by itself. | |||||||||||||||||
| Comment by Daniel Lenski [ 2023-07-13 ] | |||||||||||||||||
|
serg wrote:
This is a great summary of the technical pros and cons but… It seems like "no forceful redirect" is a major deficiency of session tracking. (And for old clients or clients with session tracking disabled, there will be no way at all to force them to notice the redirection, unless with the ERR-packet approach.) As you noted yourself on the mailing list, you don't know of any actual use cases for advisory-only redirection. By contrast, we are aware of one major use case for "forceful" redirection, graceful server shutdown, as discussed here and on the mailing list. And I don't see any comments here, in the last 5 years, from someone who isn't a MariaDB core developer. So I'm quite confused about the idea that the "preferable" approach here is to implement a version of this feature which has no known actual use cases… particularly given that I have already implemented a version that does have practical use cases. | |||||||||||||||||
| Comment by Otto Kekäläinen [ 2023-07-19 ] | |||||||||||||||||
|
Hi! The proposal in https://lists.mariadb.org/hyperkitty/list/developers@lists.mariadb.org/thread/7UGBTX2B2KPH7UAXCCWFMUNIRQEA3WLS/ to have a new error code ERR_REDIRECT and a IP/hostname payload so clients can connect to a new server perfectly suits the use case of one server being shut down and new connections being asked to go to a new server. This is a simple and solid approach, modeled after the time--tested HTTP 301 redirect, with TLS considerations and all. Could we please get green light from Georg and Sergei for https://github.com/mariadb-corporation/mariadb-connector-c/pull/226 and https://github.com/MariaDB/server/pull/2681? If you later want to have a more complex version that fulfills other use cases, you can have that too. This implementation does not block voluntary suggest redirect to logged in users approach via session_track_system_variables as suggested in this Jira. You can have both if you want. | |||||||||||||||||
| Comment by Sergei Golubchik [ 2023-07-19 ] | |||||||||||||||||
|
dlenski, the original use case was load balancing. And that didn't need any code in the server it was supposed to be done in the proxy. Anyway, the user who wanted it stopped answering years ago. And again, as far as graceful shutdown is concerned, any approach works, because any redirect will be forceful when the server shuts down. So this is not an argument. All the drawbacks from the above still apply, though. otto, no, it would be strange to have two completely different approaches to the same functionality, if we'll do error message approach we'll likely stick with it. | |||||||||||||||||
| Comment by Georg Richter [ 2023-07-19 ] | |||||||||||||||||
|
Since the redirect affects not only C/C, but all MariaDB connectors, Serg and I are not the only decision makers, but other connector maintainers as well. Speaking of Connector/C and other Connectors based on C/C the session tracking approach would be easy to implement, even if an older Connector/C (without redirection support) would be used. Example in MariaDB Connector/Python:
From my perspective using error packet has several disadvantages:
| |||||||||||||||||
| Comment by markus makela [ 2023-07-19 ] | |||||||||||||||||
|
From the MaxScale point of view, adding support for server redirection via session state tracking should be trivial now that | |||||||||||||||||
| Comment by Yuchen Pei [ 2023-08-08 ] | |||||||||||||||||
|
I've more or less caught up with the comments and mailing list Some relevant info about the implementation I have gathered from the 1. The baseline scope of this ticket is to add the session variable | |||||||||||||||||
| Comment by Yuchen Pei [ 2023-08-15 ] | |||||||||||||||||
|
Hi serg, ptal thanks
The commit has been updated (see the comment below). | |||||||||||||||||
| Comment by markus makela [ 2023-08-15 ] | |||||||||||||||||
|
One thing that would be nice is to accept both mysql:// and mariadb://. After all, it's a feature that's currently only in MariaDB so not accepting it seems odd. | |||||||||||||||||
| Comment by Yuchen Pei [ 2023-08-16 ] | |||||||||||||||||
|
> One thing that would be nice is to accept both mysql:// and Done[1]. serg, sorry ptal this one instead: | |||||||||||||||||
| Comment by Yuchen Pei [ 2023-09-08 ] | |||||||||||||||||
|
Hi serg, thanks for the comments, ptal at the updated commits, thank you | |||||||||||||||||
| Comment by Yuchen Pei [ 2023-09-08 ] | |||||||||||||||||
|
The review has been taking place on the mailing list https://lists.mariadb.org/hyperkitty/list/developers@lists.mariadb.org/thread/2D5LPOFKWXZ35GPIZRAHIJJO3HSPUQCN/ | |||||||||||||||||
| Comment by Yuchen Pei [ 2023-09-12 ] | |||||||||||||||||
|
Thanks for the comments serg, ptal at the updated commits 6128bc9b599 BTW I only included commit hash this time without the github link, but let me know if I should include the github commit urls instead. | |||||||||||||||||
| Comment by Yuchen Pei [ 2023-09-13 ] | |||||||||||||||||
|
Thanks for the third round review on the clean-up commit serg, ptal at the updated commits
| |||||||||||||||||
| Comment by Sergei Golubchik [ 2023-09-13 ] | |||||||||||||||||
|
9db04b3dc73 and 14a12f98eb8 are ok to push into preview-11.3-preview branch with one change:
| |||||||||||||||||
| Comment by Yuchen Pei [ 2023-09-14 ] | |||||||||||||||||
|
Thanks for the review serg. Done and pushed the following to
| |||||||||||||||||
| Comment by Ramesh Sivaraman [ 2023-10-18 ] | |||||||||||||||||
|
ok to push | |||||||||||||||||
| Comment by Yuchen Pei [ 2023-10-19 ] | |||||||||||||||||
|
Thanks for the testing ramesh, can you clarify which commits are ok
| |||||||||||||||||
| Comment by Ramesh Sivaraman [ 2023-10-19 ] | |||||||||||||||||
|
ycp Test performed on latest preview-11.3-preview commit
| |||||||||||||||||
| Comment by Yuchen Pei [ 2023-10-20 ] | |||||||||||||||||
|
OK, I squashed 76e20f00772 into dd2608fa92d, and cherry picked the
sergramesh let me know if this needs testing by ramesh too | |||||||||||||||||
| Comment by Ramesh Sivaraman [ 2023-10-20 ] | |||||||||||||||||
|
ycp I will initiate new pquery test run on bb-11.3-mdev-15935 and let you know if there is any issue asap | |||||||||||||||||
| Comment by Ramesh Sivaraman [ 2023-10-23 ] | |||||||||||||||||
|
ycp pquery test run looks good. | |||||||||||||||||
| Comment by Yuchen Pei [ 2023-10-25 ] | |||||||||||||||||
|
Thanks ramesh. Now that | |||||||||||||||||
| Comment by Ramesh Sivaraman [ 2023-10-26 ] | |||||||||||||||||
|
ycp bug fix branch looks good. | |||||||||||||||||
| Comment by Yuchen Pei [ 2023-10-26 ] | |||||||||||||||||
|
Thanks ramesh, pushing now... | |||||||||||||||||
| Comment by Yuchen Pei [ 2023-10-26 ] | |||||||||||||||||
|
pushed the following to 11.3 c4a506f0bf3 upstream/bb-11.3-mdev-15935 |