-
Notifications
You must be signed in to change notification settings - Fork 7
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
Enforce maximum payload size #279
base: 10-23-Encode_messages_before_storing_in_send_buffer
Are you sure you want to change the base?
Enforce maximum payload size #279
Conversation
Current dependencies on/for this PR: This comment was autogenerated by Freephite. |
7df315e
to
6a70fcc
Compare
// TODO: Is this the right error to send to the server? | ||
sessionScopedSend( | ||
cancelMessage( | ||
streamId, | ||
Err({ | ||
code: CANCEL_CODE, | ||
message: 'cancelled by client', | ||
}), | ||
), | ||
); |
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.
Not sure if this is the right message, to send, maybe it should send the payload size exceeded error to the server too? Currently the server only ever expects CANCEL_CODE
here
), | ||
); | ||
|
||
throw e; |
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.
Seems odd to have to throw here in addition to injecting the errors, but we do need a way for calls to write
to error out if we hit this.
@@ -141,6 +141,15 @@ export interface SessionOptions { | |||
* The codec to use for encoding/decoding messages over the wire | |||
*/ | |||
codec: Codec; | |||
/** | |||
* The maximum payload size that is allowed to be sent to the peer. | |||
* This does not enforce max payload side when receiving messages, |
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.
Thoughts on enforcing this on received messages too? I think we get the most value out of this by just enforcing it on the sender side as long as we do that everywhere (server, client, python client)
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.
makes sense to me! we can probs do that follow up though, in our case we control all the clients so enforcing sender side is probably fine
6a70fcc
to
1f90cb9
Compare
1f90cb9
to
0908b4d
Compare
|
||
##### Server handling | ||
|
||
If the server attempts to send a message after a procedure has been started which exceeds the maximum payload size, the server must reply with a `MAX_PAYLOAD_SIZE_EXCEEDED` error and close down the procedure. |
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.
is there a reason we need a new protocol error? could we just use CANCEL and have max payload size exceeded in the message? the semantics of MAX_PAYLOAD_SIZE_EXCEEDED and CANCEL are identical in how they should be handled i think
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.
Good point! My main goal was to make this error obvious when it happens, putting it in the message should be sufficient.
@@ -141,6 +141,15 @@ export interface SessionOptions { | |||
* The codec to use for encoding/decoding messages over the wire | |||
*/ | |||
codec: Codec; | |||
/** | |||
* The maximum payload size that is allowed to be sent to the peer. | |||
* This does not enforce max payload side when receiving messages, |
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.
makes sense to me! we can probs do that follow up though, in our case we control all the clients so enforcing sender side is probably fine
? ControlFlags.StreamOpenBit | ControlFlags.StreamClosedBit | ||
: ControlFlags.StreamOpenBit, | ||
}); | ||
try { |
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.
we can probably handle this uniformly across server/client in
Line 314 in 1007a55
getSessionBoundSendFn( |
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.
try catch the send and if it errors, send cancel instead
Why
Memory is not unbounded and underlying transports have limits on maximum payload size. When we accidentally exceed the max payload size for an underlying transport, the connection can get torn down entirely. This is bad because it means one bad RPC call can bring down the entire connection.
Additionally, when things do explode, its hard to find the right error message that tells you that this was due to exceeding some payload limit.
Let's enforce a configurable max payload limit in river itself. It's up to users to make sure that this max payload size is
<=
the max payload size allowed by their transport layer.Something to consider in the future is automatically chunking these messages in river; however, I think this is a bad idea because we want to avoid having large buffers in memory entirely. Having this restriction in river will force application developers to stream or chunk data and help avoid cases where loading large buffers into memory happens to work until we hit OOMs.
What changed
MAX_PAYLOAD_SIZE_EXCEEDED
write
returnsvoid
MAX_PAYLOAD_SIZE_EXCEEDED
whenever server attempts to send a payload that is too largeVersioning