|
| 1 | +# 0-RTT |
| 2 | + |
| 3 | +There seems to be some misconceptions around what 0-RTT means. Any given v2ray |
| 4 | +config does not just "have" 0-RTT or not have it. |
| 5 | + |
| 6 | +It's a property of a specific protocol layer, and your config is made of |
| 7 | +multiple layers. In this order, from outer to inner layer: |
| 8 | + |
| 9 | +* TCP, UDP |
| 10 | +* TLS layer, optional |
| 11 | +* Transport layer, optional |
| 12 | +* Mux, optional |
| 13 | +* "The protocol", e.g. VLESS or Vmess |
| 14 | + |
| 15 | +Each of these layers "is 0-RTT"... or doesn't. What that really means is: Does |
| 16 | +the given layer add a roundtrip when creating a full connection (and therefore |
| 17 | +increase latency), or does it not? |
| 18 | + |
| 19 | +## Simple example: WebSocket without ED |
| 20 | + |
| 21 | +```mermaid |
| 22 | +sequenceDiagram |
| 23 | + Client->>Server: TLS 1.3: ClientHello |
| 24 | + Server->>Client: TLS 1.3: ServerHello + Finished |
| 25 | + Client-->>Server: HTTP: GET /secretpath, Connection: upgrade |
| 26 | + Server-->>Client: HTTP: 101 Switching Protocols |
| 27 | + Client-->>Server: VLESS: open forbiddensite.com |
| 28 | + Server-->>Client: VLESS: return forbidden content |
| 29 | +``` |
| 30 | + |
| 31 | +Imagine your latency to send some data to the server is 100ms. This is what |
| 32 | +happens when a new connection is established (let's just ignore TCP for this |
| 33 | +article): |
| 34 | + |
| 35 | +1. Then, client sends ClientHello, and waits for the server to respond with |
| 36 | + ServerHello. **200ms added**, because you're waiting for the data to |
| 37 | + transmit in both directions. |
| 38 | +2. Then, client starts sending a HTTP request for WebSocket, and waits for the |
| 39 | + response. This is another **200ms added.** |
| 40 | +3. Finally, the client can start forwarding the actual traffic. |
| 41 | + |
| 42 | +This double-roundtrip is why URLTest may be slow (200ms + 200ms + ...), because |
| 43 | +it establishes a new connection, but later, the ping in speedtest is a bit |
| 44 | +nicer (100ms) |
| 45 | + |
| 46 | +In this example, it can be said that VLESS does not add latency, so VLESS "is |
| 47 | +0-RTT". The same holds true for Trojan. |
| 48 | + |
| 49 | +## Eliminating WebSocket RTT with Early Data |
| 50 | + |
| 51 | +WebSocket adds the roundtrip of a HTTP request, let's get rid of it. |
| 52 | + |
| 53 | +It was already briefly described in [Transports](./transports.md), but let's |
| 54 | +actually sketch it out: |
| 55 | + |
| 56 | +```mermaid |
| 57 | +sequenceDiagram |
| 58 | + Client->>Server: TLS 1.3: ClientHello |
| 59 | + Server->>Client: TLS 1.3: ServerHello + Finished |
| 60 | + Client-->>Server: HTTP: GET /secretpath, Connection: upgrade + Sec-WebSocket-Protocol: "VLESS: open forbiddensite.com" |
| 61 | + Server-->>Client: HTTP: 101 Switching Protocols + VLESS: return forbidden content |
| 62 | +``` |
| 63 | + |
| 64 | +The amount of data that is sent around hasn't actually changed. We just |
| 65 | +"batched" it efficiently into two roundtrips instead of three: |
| 66 | + |
| 67 | +1. TLS handshake as normal. |
| 68 | +2. Client sends the HTTP request together with the first half of VLESS traffic already. |
| 69 | + |
| 70 | + Server responds to the HTTP request and already sends the VLESS response |
| 71 | + (instead of waiting for a VLESS request to open forbiddensite) |
| 72 | + |
| 73 | +### What about protocols other than WebSocket? |
| 74 | + |
| 75 | +If you don't use WebSocket but for example TCP ("no transport"), gRPC or |
| 76 | +SplitHTTP, those protocols don't add a roundtrip to begin with. So there is no |
| 77 | +added latency that has to be "reverted". |
| 78 | + |
| 79 | +HTTPUpgrade has the same issues as WebSocket, see [Transports](./transports.md). |
| 80 | + |
| 81 | +## Eliminating TLS RTT |
| 82 | + |
| 83 | +As a user of v2ray, there isn't really much you can do to remove the overhead of TLS. |
| 84 | + |
| 85 | +* You can just turn off TLS. Just kidding, please don't. |
| 86 | +* TLS 1.3 Early Data is the same idea as WebSocket Early Data: Take the HTTP |
| 87 | + request, and send it alongside with ClientHello. Unfortunately [this |
| 88 | + compromises |
| 89 | + security](https://blog.trailofbits.com/2019/03/25/what-application-developers-need-to-know-about-tls-early-data-0rtt/) |
| 90 | + to a certain degree. And it is not supported by uTLS or Golang's TLS. |
| 91 | + |
| 92 | +### What about QUIC 0-RTT? |
| 93 | + |
| 94 | +It seems to be largely the same situation. The library support is unclear, and |
| 95 | +it compromises forward security in the same way. |
0 commit comments