fix #166, vmess 在 ws + earlydata时 会导致连不上

这是一个陈旧的开发错误,直到现在才显现出来
This commit is contained in:
e1732a364fed
2000-01-01 00:00:00 +00:00
parent c05f8b8b53
commit 30b283b81b
8 changed files with 23 additions and 27 deletions

View File

@@ -78,8 +78,8 @@ type Client interface {
type SingleClient interface {
Client
//it's 0-rtt if payload is provided
Handshake(underlay net.Conn, payload []byte) (net.Conn, error)
//it may use 0-rtt if firstPayloadLen>0 && IsEarly() == true
Handshake(underlay net.Conn, firstPayloadLen int) (net.Conn, error)
}
//like grpc (h2) and quic (h3)

View File

@@ -54,14 +54,13 @@ func (c *Client) IsEarly() bool {
}
//与服务端进行 websocket握手并返回可直接用于读写 websocket 二进制数据的 net.Conn
func (c *Client) Handshake(underlay net.Conn, ed []byte) (net.Conn, error) {
func (c *Client) Handshake(underlay net.Conn, firstPayloadLen int) (net.Conn, error) {
if len(ed) > 0 {
if c.IsEarly() && firstPayloadLen > 0 && firstPayloadLen <= MaxEarlyDataLen {
// 我们要先返回一个 Conn, 然后读取到内层的 vless等协议的握手后再进行实际的 ws握手
return &EarlyDataConn{
Conn: underlay,
earlyData: ed,
requestURL: c.requestURL,
firstHandshakeOkChan: make(chan int, 1),
dialer: &ws.Dialer{
@@ -134,7 +133,6 @@ type EarlyDataConn struct {
realWsConn net.Conn
notFirst bool
earlyData []byte
requestURL *url.URL
firstHandshakeOkChan chan int
@@ -152,8 +150,7 @@ func (edc *EarlyDataConn) Write(p []byte) (int, error) {
outBuf := utils.GetBuf()
encoder := base64.NewEncoder(base64.RawURLEncoding, outBuf)
multiReader := io.MultiReader(bytes.NewReader(p), bytes.NewReader(edc.earlyData))
_, encerr := io.Copy(encoder, multiReader)
_, encerr := io.Copy(encoder, bytes.NewReader(p))
if encerr != nil {
close(edc.firstHandshakeOkChan)
return 0, utils.ErrInErr{ErrDesc: "Err when encode early data", ErrDetail: encerr}

View File

@@ -18,10 +18,6 @@ import (
"go.uber.org/zap"
)
// 2048 /3 = 682.6666... (682 又 三分之二),
// 683 * 4 = 2732, 你若不信,运行 we_test.go中的 TestBase64Len
const MaxEarlyDataLen_Base64 = 2732
var (
connectionBs = []byte("Connection")
upgradeBs = []byte("Upgrade")

View File

@@ -39,6 +39,11 @@ import (
"github.com/e1732a364fed/v2ray_simple/advLayer"
)
// 2048 /3 = 682.6666... (682 又 三分之二),
// 683 * 4 = 2732, 你若不信,运行 we_test.go中的 TestBase64Len
const MaxEarlyDataLen_Base64 = 2732
const MaxEarlyDataLen = 2048
func init() {
advLayer.ProtocolsMap["ws"] = Creator{}
}

View File

@@ -88,7 +88,7 @@ func TestWs(t *testing.T) {
t.Log(err)
t.FailNow()
}
wsConn, err := cli.Handshake(tcpConn, nil)
wsConn, err := cli.Handshake(tcpConn, 0)
if err != nil {
t.Log(err)
t.FailNow()

11
main.go
View File

@@ -1301,13 +1301,12 @@ advLayerHandshakeStep:
//ws
default:
var ed []byte
var edlen int
if !hasInnerMux && advClient.IsEarly() && wlc != nil {
//若配置了 MaxEarlyDataLen则我们先读一段;
ed = iics.firstPayload
iics.fallbackFirstBuffer = nil
iics.firstPayload = nil //防止vless 再写一遍firstpayload.
edlen = len(iics.firstPayload)
}
// 我们verysimple的架构是 ws握手之后再进行vless握手
@@ -1318,7 +1317,7 @@ advLayerHandshakeStep:
wcs := advClient.(advLayer.SingleClient)
wc, err = wcs.Handshake(clientConn, ed)
wc, err = wcs.Handshake(clientConn, edlen)
if err != nil {
if ce := iics.CanLogErr("Failed in handshake Single AdvLayer"); ce != nil {

View File

@@ -245,16 +245,14 @@ func (s *Server) Handshake(underlay net.Conn) (tcpConn net.Conn, msgConn netLaye
targetAddr = ad
//verysimple 不支持v2ray中的 vmess 的 mux.cool
case cmd_muxcool_unimplemented:
returnErr = utils.ErrInErr{ErrDesc: "Vmess mux.cool is not supported by verysimple ", ErrDetail: utils.ErrInvalidData}
default:
//mux.cool的command的定义 在 v2ray源代码的 common/protocol/headers.go 的 RequestCommandMux。
if sc.cmd == cmd_muxcool_unimplemented {
returnErr = utils.ErrInErr{ErrDesc: "Vmess mux.cool is not supported by verysimple ", ErrDetail: utils.ErrInvalidData}
returnErr = utils.ErrInErr{ErrDesc: "Vmess Invalid command ", ErrDetail: utils.ErrInvalidData, Data: sc.cmd}
} else {
returnErr = utils.ErrInErr{ErrDesc: "Vmess Invalid command ", ErrDetail: utils.ErrInvalidData, Data: sc.cmd}
}
return
}

View File

@@ -61,7 +61,8 @@ const (
const (
CmdTCP byte = 1
CmdUDP byte = 2
cmd_muxcool_unimplemented byte = 3
cmd_muxcool_unimplemented byte = 3 //mux.cool的command的定义 在 v2ray源代码的 common/protocol/headers.go 的 RequestCommandMux。
)
var getkeyBs = []byte("c48619fe-8f02-49e0-b9e9-edf763e17e21")