-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
TCP fast open support #161
Comments
It seems TFO brings more problems than benefits. See https://squeeze.isobar.com/2019/04/11/the-sad-story-of-tcp-fast-open/
The tracking and privacy concern is also real, especially in SS use case. |
An alternative to TFO is to keep on the client a pool of established connections to the server (or even just one), so you have one already established when you need it. |
@fortuna True. Actually an even better idea is to slightly extend the Shadowsocks protocol so it can reuse connections. The popular proxy app Surge has a custom protocol called Snell, which adopted my idea, resulting in significant reduction in average connection establishing time (basically all benefits of TFO without any of its drawbacks). I should probably write a SIP draft :) |
Reusing connections sounds like a good idea. Besides performance it may add resistance against censorship. But I don't think we can do it in a backward-compatible way. How would you indicate EOF? Currently we rely on the TCP FIN. It probably requires a protocol change. |
It's actually a pretty easy fix but further testing must be done to see if it can be backward-compatible. Recall that using AEAD ciphers we split a stream of data into small chunks with a 2-byte chunk length prefix. We can define a zero-length chunk to signal EOF of an existing stream. Upon receiving zero-length chunk, implementations that understanding connection reuse can put the TCP connection into idle pool for later reuse. The connection pool should be a LIFO queue to prioritize reusing recently used connections, and close cold/aging connections to keep the pool under a certain size (say 10 idle connections at max). Currently zero-length chunk is undefined in the spec and actually we are vulnerable to truncation attack. Fortunately sensitive data should be protected by inner TLS with necessary mitigation so we can be a bit loose in the outer Shadowsocks layer. Could you please check if Outline client/server properly handles this edge case? I guess existing implementations should probably error out and close the TCP connection when it does not expect zero-length chunks. Of course at this point stream ciphers must be abandoned altogether. (I have some even crazier ideas to further enhance this…😄) |
My interpretation of the Shadowsocks spec is that a zero-length chunk is perfectly valid. It's just overhead. I believe outline-ss-server will simply ignore that chunk. It will read the payload size (0), validate the tag, then read 0 bytes of payload, and validate the tag for the empty payload. I actually considered about using empty chunks for padding in a backward-compatible way to deceive censors, but it's not very flexible. So I don't think we can use an empty chunk. But we could use a marker that fails AEAD validation with the My expectation is that older servers will close the connection on an invalid chunk, but new servers can keep the connection going. Though I think the behavior of closing the connection on invalid chunk is not really in the spec. |
Your interpretation is also perfectly valid and actually TLS has similar definition to allow zero-length data record. From RFC 8446 Section 5.1
But I hate to further complicate the key derivation part. We should not stuff protocol layer concerns into crypto layer… If you want to do it super cleanly, it's probably better to use the reserved two higher bits in the 2-byte chunk length. The spec currently strictly requires the two bits to be cleared. We could use one bit to signal that the following chunk is an enhanced chunk, such that it comes with a fixed-size header to signal various aspects (e.g. EOF, padding used, actual data size, etc). |
We won't plan to support TFO any more given the tracking and performance concerns. |
How about add TCP Fastopen like v2ray did(v2ray)?
The text was updated successfully, but these errors were encountered: