diff --git a/advLayer/advLayer.go b/advLayer/advLayer.go index d1e67d1..923bfef 100644 --- a/advLayer/advLayer.go +++ b/advLayer/advLayer.go @@ -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) diff --git a/advLayer/ws/client.go b/advLayer/ws/client.go index 3a36e22..60a1317 100644 --- a/advLayer/ws/client.go +++ b/advLayer/ws/client.go @@ -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} diff --git a/advLayer/ws/server.go b/advLayer/ws/server.go index 9a3caab..c9a8942 100644 --- a/advLayer/ws/server.go +++ b/advLayer/ws/server.go @@ -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") diff --git a/advLayer/ws/ws.go b/advLayer/ws/ws.go index 0758027..cea959d 100644 --- a/advLayer/ws/ws.go +++ b/advLayer/ws/ws.go @@ -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{} } diff --git a/advLayer/ws/ws_test.go b/advLayer/ws/ws_test.go index fffadc7..d7f2337 100644 --- a/advLayer/ws/ws_test.go +++ b/advLayer/ws/ws_test.go @@ -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() diff --git a/main.go b/main.go index 6cb8937..5ed087b 100644 --- a/main.go +++ b/main.go @@ -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 { diff --git a/proxy/vmess/server.go b/proxy/vmess/server.go index 6cbb33d..b61d151 100644 --- a/proxy/vmess/server.go +++ b/proxy/vmess/server.go @@ -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 } diff --git a/proxy/vmess/vmess.go b/proxy/vmess/vmess.go index f275f1b..d2ebff7 100644 --- a/proxy/vmess/vmess.go +++ b/proxy/vmess/vmess.go @@ -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")