-
Notifications
You must be signed in to change notification settings - Fork 25.6k
Add version to handshake requests #36171
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Pinging @elastic/es-distributed |
|
I'm not completely sure if this will work as I think that we validate the entire message is consumed. But I wanted to push it up here to see what happens on the backwards compatibility tests. |
I don't think this will fly. This handshake is only here to negotiate the version I am not sure what we are trying to achieve here? |
|
Alright I had been doubting whether this would work due to an initial test failure. But that was due to a mistake where I did not make master (7.0.0) able to read prior response versions.
I think that it works. I have tested these changes locally against 5.6 and 6.2, even with the additional data in the request, the nodes successfully handshake. The reason is that on handshake requests we do not require that the entire stream has been consumed (like we do for normal requests). Additionally, all of CI is passing now.
There two motivations:
Additionally, if the handshake was version-aware it would allow for work in the future to use this (if we ever wanted to negotiate anything else).
The request type currently is By making this change we bring the handshake into accordance with our other messages. The request stream will be consumed and treated more strictly (we can also validate the action name). As you see I added a field indicating how large the message is to allow future versions to add additional information if there is value in that. And prior versions would just blindly consume that data but send back their normal response (which includes the version so future version can handle it). One other supporting piece of data: This PR #31020 actually made 7.0 questionably backwards compatible for handshakes with versions prior to 6.3. It looks to me that we want these version to be able to handshake even if 7.0 will immediately close the connection after reading the response. My knowledge of what we want here is based on this comment: Based on that work it looks to me that 7.0 will send a handshake request with a stream version of 6.7. And 6.7 should be compatible with 6.2. Although once 7.0 receives the response (indicating 6.2) it would close the stream. The issue with #31020 is that 7.0 will have a minimal compatibility version of 6.7. That means in the handshake request it will include Maybe we should fix that in 7.0? Not send the features in the handshake request? However, I guess my point is that this is an example of how we currently allow sending extra data in handshake requests. And this PR would close this weird edge case, while introducing some support for future (unexpected) changes. |
|
I just kind of threw in the max of 2kb for future handshake requests. I'm not sure if there is actually any value in that. But we can decide on that validation, once you evaluate what you think of the reasoning for the other changes. |
uh sneaky. I think we should from now on?
fair enough. lets fix that!
++ I am all for having just one handshake request! I still think we should also validate that we consume everything in the handshake going forward? |
| static final class HandshakeResponse extends TransportResponse { | ||
|
|
||
| private final Version responseVersion; | ||
| private Version requestVersion; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm this is unused?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I removed it.
| try { | ||
| return buffer.readByte(); | ||
| } catch (IndexOutOfBoundsException ex) { | ||
| throw new EOFException(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you put the ex as a cause in there?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added it. The ctor does not take it. But I added it use the init method.
plugins/transport-nio/src/main/java/org/elasticsearch/http/nio/ByteBufUtils.java
Show resolved
Hide resolved
|
@s1monw - I updated this based on your comments. I removed the 2KB limit as I'm not sure that is something that actually makes sense. And verified that the stream is fully consumed. I did not validate the action name yet. I think that will be a follow-up. |
s1monw
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
left one comment LGTM. I assume we add stuff based on top of this in followups?
server/src/main/java/org/elasticsearch/transport/TransportHandshaker.java
Outdated
Show resolved
Hide resolved
Yeah. |
|
|
||
| static final class HandshakeResponse extends TransportResponse { | ||
|
|
||
| private final Version responseVersion; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the plan is to replace internal:transport/handshake with this message, does it also need the ClusterName? Today we rely on the fact that the transport handshake validates that the cluster names match during discovery - I think that we don't otherwise verify that we're talking to nodes from the right cluster.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is follow-up work. We need the version the the request to bootstrap the follow-up work. Once we have the version in the request, we can serialize arbitrary responses that are compatible with the remote node's version.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it, thanks.
Currently our handshake requests do not include a version. This is unfortunate as we cannot rely on the stream version since it is not the sending node's version. Instead it is the minimum compatibility version. The handshake request is currently empty and we do nothing with it. This should allow us to add data to the request without breaking backwards compatibility. This commit adds the version to the handshake request. Additionally, it allows "future data" to be added to the request. This allows nodes to craft a version compatible response. And will properly handle additional data in future handshake requests. The proper handling of "future data" is useful as this is the only request where we do not know the other node's version. Finally, it renames the TcpTransportHandshaker to TransportHandshaker.
Currently our handshake requests do not include a version. This is unfortunate as we cannot rely on the stream version since it is not the sending node's version. Instead it is the minimum compatibility version. The handshake request is currently empty and we do nothing with it. This should allow us to add data to the request without breaking backwards compatibility. This commit adds the version to the handshake request. Additionally, it allows "future data" to be added to the request. This allows nodes to craft a version compatible response. And will properly handle additional data in future handshake requests. The proper handling of "future data" is useful as this is the only request where we do not know the other node's version. Finally, it renames the TcpTransportHandshaker to TransportHandshaker.
Currently our handshake requests do not include a version. This is
unfortunate as we cannot rely on the stream version since it is not the
sending node's version. Instead it is the minimum compatibility version.
The handshake request is currently empty and we do nothing with it. This
should allow us to add data to the request without breaking backwards
compatibility.
This commit adds the version to the handshake request. Additionally, it
allows "future data" to be added to the request. This allows nodes to craft
a version compatible response. And will properly handle additional data in
future handshake requests. The proper handling of "future data" is useful
as this is the only request where we do not know the other node's version.
Finally, it renames the
TcpTransportHandshakertoTransportHandshaker.