-
Notifications
You must be signed in to change notification settings - Fork 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
WebSocket 0-RTT #375
WebSocket 0-RTT #375
Conversation
conn, resp, err := dialer.Dial(uri, wsSettings.GetRequestHeader()) | ||
header := wsSettings.GetRequestHeader() | ||
if ed != nil { | ||
header.Set("Sec-WebSocket-Protocol", base64.StdEncoding.EncodeToString(ed)) |
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.
这里的header需不需要clone一次,防止并发dialWebsocket的时候出错?
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.
Xray-core/transport/internet/websocket/config.go
Lines 23 to 29 in 9dec65e
func (c *Config) GetRequestHeader() http.Header { | |
header := http.Header{} | |
for _, h := range c.Header { | |
header.Add(h.Key, h.Value) | |
} | |
return header | |
} |
(be careful with golang's textproto.CanonicalMIMEHeaderKey)
Updates in #421 |
Background
v2fly/v2ray-core#378 本来想的是不等握手完成就连着发 payload,但某些 WebSocket 服务端实现可能会拒绝此行为
v2fly 的计划是将首个 payload 放 path,我不喜欢那个做法,因为要改很多配置,而且 path 往往会被 log
这里感谢 @darhwa 提出可以把首个 payload 放 WS header v2fly/v2ray-core#378 (comment)
Header
最初的想法是需要自定义 header 名,但有一些麻烦,我希望尽量减少对现有配置的改动,以便此功能可以迅速普及
所以最终决定使用
Sec-WebSocket-Protocol
这个 header 承载 early data(一般带着内层 TLS Client Hello):ws = new WebSocket(url [, protocols])
设置它,方便日后的浏览器中转具体方式是客户端将 early data 进行标准 Base64 编码后放入这个 header,服务端若成功解析即当作 early data 处理
Configuration
为了此功能可以迅速普及,经过反复思考后,我的设计是不需 GUI 新增配置项,只需在现有 path 后加上
?ed=2048
?ed=2048
即可减少 1-RTT,2048 代表 early data 的长度上限,目前建议写 2048与此同时,现在就可以下发带
?ed=2048
的订阅,因为旧的客户端虽然不支持 early data,但仍然可以正常使用节点?ed=2048
在本地就会被解析,不会被发到服务端,到服务端的是Sec-WebSocket-Protocol
?ed=2048
在本地不会被解析,且会被发到服务端,但只是多了个参数,不会影响正常使用就像 XUDP 一样,这也是一个非常简单且优雅的解决方案。至此,绝大多数场景下,WSS 的延迟已等同于 TCP+TLS 🎉