mirror of
https://github.com/e1732a364fed/v2ray_simple.git
synced 2025-10-25 17:50:29 +08:00
上一个commit修改了函数签名,不好,太笨,还是不改好
proxy.Server返回的 *bytes.Buffer只被用于Fallback,所以直接放到Fallback里就行
This commit is contained in:
@@ -1,6 +1,10 @@
|
||||
package httpLayer
|
||||
|
||||
import "github.com/hahahrfool/v2ray_simple/proxy"
|
||||
import (
|
||||
"bytes"
|
||||
|
||||
"github.com/hahahrfool/v2ray_simple/proxy"
|
||||
)
|
||||
|
||||
const (
|
||||
Fallback_none = 0
|
||||
@@ -21,10 +25,12 @@ func HasFallbackType(ftype, b byte) bool {
|
||||
type Fallback interface {
|
||||
GetFallback(ftype byte, param string) *proxy.Addr
|
||||
SupportType() byte //参考Fallback_开头的常量。如果支持多个,则返回它们 按位与 的结果
|
||||
FirstBuffer() *bytes.Buffer
|
||||
}
|
||||
|
||||
type SingleFallback struct {
|
||||
Addr *proxy.Addr
|
||||
Addr *proxy.Addr
|
||||
First *bytes.Buffer
|
||||
}
|
||||
|
||||
func (ef *SingleFallback) GetFallback(ftype byte, param string) *proxy.Addr {
|
||||
@@ -35,6 +41,10 @@ func (ef *SingleFallback) SupportType() byte {
|
||||
return FallBack_default
|
||||
}
|
||||
|
||||
func (ef *SingleFallback) FirstBuffer() *bytes.Buffer {
|
||||
return ef.First
|
||||
}
|
||||
|
||||
//实现 Fallback
|
||||
type ClassicFallback struct {
|
||||
Default *proxy.Addr
|
||||
@@ -97,6 +107,7 @@ type ErrSingleFallback struct {
|
||||
FallbackAddr *proxy.Addr
|
||||
Err error
|
||||
eStr string
|
||||
First *bytes.Buffer
|
||||
}
|
||||
|
||||
func (ef *ErrSingleFallback) Error() string {
|
||||
@@ -109,6 +120,7 @@ func (ef *ErrSingleFallback) Error() string {
|
||||
//返回 SingleFallback
|
||||
func (ef *ErrSingleFallback) Fallback() Fallback {
|
||||
return &SingleFallback{
|
||||
Addr: ef.FallbackAddr,
|
||||
Addr: ef.FallbackAddr,
|
||||
First: ef.First,
|
||||
}
|
||||
}
|
||||
|
||||
10
main.go
10
main.go
@@ -188,8 +188,9 @@ func handleNewIncomeConnection(localServer proxy.Server, remoteClient proxy.Clie
|
||||
|
||||
}
|
||||
//isfallback := false
|
||||
var theFallback httpLayer.Fallback
|
||||
|
||||
wlc, localServerFirstReadBuf, targetAddr, err := localServer.Handshake(thisLocalConnectionInstance)
|
||||
wlc, targetAddr, err := localServer.Handshake(thisLocalConnectionInstance)
|
||||
if err != nil {
|
||||
log.Println("failed in handshake from", localServer.AddrStr(), err)
|
||||
|
||||
@@ -197,6 +198,7 @@ func handleNewIncomeConnection(localServer proxy.Server, remoteClient proxy.Clie
|
||||
fe, ok := err.(httpLayer.FallbackErr)
|
||||
if ok {
|
||||
f := fe.Fallback()
|
||||
theFallback = f
|
||||
if httpLayer.HasFallbackType(f.SupportType(), httpLayer.FallBack_default) {
|
||||
targetAddr = f.GetFallback(httpLayer.FallBack_default, "")
|
||||
|
||||
@@ -424,10 +426,10 @@ afterLocalServerHandshake:
|
||||
|
||||
}
|
||||
|
||||
if localServerFirstReadBuf != nil {
|
||||
if theFallback != nil {
|
||||
//这里注意,因为是吧tls解密了之后的数据发送到目标地址,所以这种方式只支持转发到本机纯http服务器
|
||||
wrc.Write(localServerFirstReadBuf.Bytes())
|
||||
common.PutBytes(localServerFirstReadBuf.Bytes()) //这个Buf不是从common.GetBuf创建的,而是从一个 GetBytes的[]byte 包装 的
|
||||
wrc.Write(theFallback.FirstBuffer().Bytes())
|
||||
common.PutBytes(theFallback.FirstBuffer().Bytes()) //这个Buf不是从common.GetBuf创建的,而是从一个 GetBytes的[]byte 包装 的
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -91,7 +91,6 @@ ws和grpc文件夹(第七层)
|
||||
package proxy
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
@@ -256,7 +255,7 @@ type Server interface {
|
||||
|
||||
Name() string
|
||||
|
||||
Handshake(underlay net.Conn) (io.ReadWriter, *bytes.Buffer, *Addr, error)
|
||||
Handshake(underlay net.Conn) (io.ReadWriter, *Addr, error)
|
||||
Stop()
|
||||
|
||||
CanFallback() bool //如果能fallback,则handshake失败后,会专门返回 ErrFallback
|
||||
|
||||
@@ -54,10 +54,10 @@ func (s *Server) CanFallback() bool {
|
||||
//中文: https://aber.sh/articles/Socks5/
|
||||
// 参考 https://studygolang.com/articles/31404
|
||||
|
||||
func (s *Server) Handshake(underlay net.Conn) (io.ReadWriter, *bytes.Buffer, *proxy.Addr, error) {
|
||||
func (s *Server) Handshake(underlay net.Conn) (io.ReadWriter, *proxy.Addr, error) {
|
||||
// Set handshake timeout 4 seconds
|
||||
if err := underlay.SetReadDeadline(time.Now().Add(time.Second * 4)); err != nil {
|
||||
return nil, nil, nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
defer underlay.SetReadDeadline(time.Time{})
|
||||
|
||||
@@ -68,24 +68,24 @@ func (s *Server) Handshake(underlay net.Conn) (io.ReadWriter, *bytes.Buffer, *pr
|
||||
// 一般握手包发来的是 [5 1 0]
|
||||
n, err := underlay.Read(buf)
|
||||
if err != nil || n == 0 {
|
||||
return nil, nil, nil, fmt.Errorf("failed to read hello: %w", err)
|
||||
return nil, nil, fmt.Errorf("failed to read hello: %w", err)
|
||||
}
|
||||
version := buf[0]
|
||||
if version != Version5 {
|
||||
return nil, nil, nil, fmt.Errorf("unsupported socks version %v", version)
|
||||
return nil, nil, fmt.Errorf("unsupported socks version %v", version)
|
||||
}
|
||||
|
||||
// Write hello response, [5 0]
|
||||
// TODO: Support Auth
|
||||
_, err = underlay.Write([]byte{Version5, AuthNone})
|
||||
if err != nil {
|
||||
return nil, nil, nil, fmt.Errorf("failed to write hello response: %w", err)
|
||||
return nil, nil, fmt.Errorf("failed to write hello response: %w", err)
|
||||
}
|
||||
|
||||
// Read command message,
|
||||
n, err = underlay.Read(buf)
|
||||
if err != nil || n < 7 { // Shortest length is 7
|
||||
return nil, nil, nil, fmt.Errorf("read socks5 failed, msgTooShort: %w", err)
|
||||
return nil, nil, fmt.Errorf("read socks5 failed, msgTooShort: %w", err)
|
||||
}
|
||||
|
||||
// 一般可以为 5 1 0 3 n,3表示域名,n是域名长度,然后域名很可能是 119 119 119 46 开头,表示 www.
|
||||
@@ -94,7 +94,7 @@ func (s *Server) Handshake(underlay net.Conn) (io.ReadWriter, *bytes.Buffer, *pr
|
||||
cmd := buf[1]
|
||||
switch cmd {
|
||||
case CmdBind:
|
||||
return nil, nil, nil, fmt.Errorf("unsuppoted command %v", cmd)
|
||||
return nil, nil, fmt.Errorf("unsuppoted command %v", cmd)
|
||||
case CmdUDPAssociate:
|
||||
|
||||
}
|
||||
@@ -114,11 +114,11 @@ func (s *Server) Handshake(underlay net.Conn) (io.ReadWriter, *bytes.Buffer, *pr
|
||||
l += int(buf[4])
|
||||
off = 5
|
||||
default:
|
||||
return nil, nil, nil, fmt.Errorf("unknown address type %v", buf[3])
|
||||
return nil, nil, fmt.Errorf("unknown address type %v", buf[3])
|
||||
}
|
||||
|
||||
if len(buf[off:]) < l {
|
||||
return nil, nil, nil, errors.New("short command request")
|
||||
return nil, nil, errors.New("short command request")
|
||||
}
|
||||
|
||||
var theName string
|
||||
@@ -146,7 +146,7 @@ func (s *Server) Handshake(underlay net.Conn) (io.ReadWriter, *bytes.Buffer, *pr
|
||||
serverAtyp, serverAddr, _, err := proxy.ParseStrToAddr(s.Addr)
|
||||
if serverAtyp != proxy.AtypIP4 { //暂时先只支持ipv4,为了简单起见
|
||||
if err != nil {
|
||||
return nil, nil, nil, errors.New("UDPAssociate: can't listen an domain, must be ip")
|
||||
return nil, nil, errors.New("UDPAssociate: can't listen an domain, must be ip")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,7 +161,7 @@ func (s *Server) Handshake(underlay net.Conn) (io.ReadWriter, *bytes.Buffer, *pr
|
||||
|
||||
udpRC, err := net.ListenUDP("udp", udpPreparedAddr)
|
||||
if err != nil {
|
||||
return nil, nil, nil, errors.New("UDPAssociate: unable to listen udp")
|
||||
return nil, nil, errors.New("UDPAssociate: unable to listen udp")
|
||||
}
|
||||
|
||||
//ver(5), rep(0,表示成功), rsv(0), atyp(1, 即ipv4), BND.ADDR(4字节的ipv4) , BND.PORT(2字节)
|
||||
@@ -170,14 +170,14 @@ func (s *Server) Handshake(underlay net.Conn) (io.ReadWriter, *bytes.Buffer, *pr
|
||||
// Write command response
|
||||
_, err = underlay.Write(reply)
|
||||
if err != nil {
|
||||
return nil, nil, nil, fmt.Errorf("failed to write command response: %w", err)
|
||||
return nil, nil, fmt.Errorf("failed to write command response: %w", err)
|
||||
}
|
||||
|
||||
uc := &UDPConn{
|
||||
clientSupposedAddr: clientFutureAddr,
|
||||
UDPConn: udpRC,
|
||||
}
|
||||
return uc, nil, clientFutureAddr, nil
|
||||
return uc, clientFutureAddr, nil
|
||||
|
||||
} else {
|
||||
addr := &proxy.Addr{
|
||||
@@ -194,10 +194,10 @@ func (s *Server) Handshake(underlay net.Conn) (io.ReadWriter, *bytes.Buffer, *pr
|
||||
|
||||
_, err = underlay.Write(reply)
|
||||
if err != nil {
|
||||
return nil, nil, nil, fmt.Errorf("failed to write command response: %w", err)
|
||||
return nil, nil, fmt.Errorf("failed to write command response: %w", err)
|
||||
}
|
||||
|
||||
return underlay, nil, addr, nil
|
||||
return underlay, addr, nil
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -130,12 +130,11 @@ func (s *Server) GetUserByStr(str string) proxy.User {
|
||||
|
||||
func (s *Server) Name() string { return Name }
|
||||
|
||||
//原本我们直接
|
||||
//see https://github.com/v2fly/v2ray-core/blob/master/proxy/vless/inbound/inbound.go
|
||||
func (s *Server) Handshake(underlay net.Conn) (io.ReadWriter, *bytes.Buffer, *proxy.Addr, error) {
|
||||
// 返回的bytes.Buffer 是用于 回落使用的,内含了整个读取的数据;不回落时不要使用该Buffer
|
||||
func (s *Server) Handshake(underlay net.Conn) (io.ReadWriter, *proxy.Addr, error) {
|
||||
|
||||
if err := underlay.SetReadDeadline(time.Now().Add(time.Second * 4)); err != nil {
|
||||
return nil, nil, nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
defer underlay.SetReadDeadline(time.Time{})
|
||||
|
||||
@@ -148,14 +147,14 @@ func (s *Server) Handshake(underlay net.Conn) (io.ReadWriter, *bytes.Buffer, *pr
|
||||
//var auth [17]byte
|
||||
wholeReadLen, err := underlay.Read(readbs)
|
||||
if err != nil {
|
||||
return nil, nil, nil, common.NewDataErr("read err", err, wholeReadLen)
|
||||
return nil, nil, common.NewDataErr("read err", err, wholeReadLen)
|
||||
}
|
||||
|
||||
if wholeReadLen < 17 {
|
||||
//根据下面回答,HTTP的最小长度恰好是16字节,但是是0.9版本。1.0是18字节,1.1还要更长。总之我们可以直接不返回fallback地址
|
||||
//https://stackoverflow.com/questions/25047905/http-request-minimum-size-in-bytes/25065089
|
||||
|
||||
return nil, nil, nil, common.NewDataErr("fallback, msg too short", nil, wholeReadLen)
|
||||
return nil, nil, common.NewDataErr("fallback, msg too short", nil, wholeReadLen)
|
||||
|
||||
}
|
||||
|
||||
@@ -168,13 +167,15 @@ func (s *Server) Handshake(underlay net.Conn) (io.ReadWriter, *bytes.Buffer, *pr
|
||||
errorPart:
|
||||
|
||||
//fallback 所返回的buffer必须包含所有数据,而Buffer不支持会退,所以只能重新New
|
||||
return nil, bytes.NewBuffer(readbs[:wholeReadLen]), nil, &httpLayer.ErrSingleFallback{
|
||||
return nil, nil, &httpLayer.ErrSingleFallback{
|
||||
FallbackAddr: s.defaultfallbackAddr,
|
||||
Err: returnErr,
|
||||
First: bytes.NewBuffer(readbs[:wholeReadLen]),
|
||||
}
|
||||
|
||||
realPart:
|
||||
//这部分过程可以参照 v2ray的 proxy/vless/encoding/encoding.go DecodeRequestHeader 方法
|
||||
//see https://github.com/v2fly/v2ray-core/blob/master/proxy/vless/inbound/inbound.go
|
||||
|
||||
auth := readbuf.Next(17)
|
||||
|
||||
@@ -204,7 +205,7 @@ realPart:
|
||||
|
||||
addonLenByte, err := readbuf.ReadByte()
|
||||
if err != nil {
|
||||
return nil, nil, nil, err //凡是和的层Read相关的错误,一律不再返回Fallback信息,因为连接已然不可用
|
||||
return nil, nil, err //凡是和的层Read相关的错误,一律不再返回Fallback信息,因为连接已然不可用
|
||||
}
|
||||
if addonLenByte != 0 {
|
||||
//v2ray的vless中没有对应的任何处理。
|
||||
@@ -218,7 +219,7 @@ realPart:
|
||||
common.PutBytes(tmpBuf)
|
||||
*/
|
||||
if tmpbs := readbuf.Next(int(addonLenByte)); len(tmpbs) != int(addonLenByte) {
|
||||
return nil, readbuf, nil, errors.New("vless short read in addon")
|
||||
return nil, nil, errors.New("vless short read in addon")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -266,7 +267,7 @@ realPart:
|
||||
|
||||
s.mux4Hashes.Unlock()
|
||||
|
||||
return nil, readbuf, addr, nil
|
||||
return nil, addr, nil
|
||||
|
||||
case proxy.CmdTCP, proxy.CmdUDP:
|
||||
|
||||
@@ -327,7 +328,7 @@ realPart:
|
||||
_, err = readbuf.Read(ip_or_domain)
|
||||
|
||||
if err != nil {
|
||||
return nil, nil, nil, errors.New("fallback, reason 6")
|
||||
return nil, nil, errors.New("fallback, reason 6")
|
||||
}
|
||||
|
||||
if addr.IP != nil {
|
||||
@@ -351,7 +352,7 @@ realPart:
|
||||
version: int(version),
|
||||
isUDP: addr.IsUDP,
|
||||
isServerEnd: true,
|
||||
}, readbuf, addr, nil
|
||||
}, addr, nil
|
||||
|
||||
}
|
||||
func (s *Server) Stop() {
|
||||
|
||||
@@ -54,7 +54,7 @@ func testVLess(version int, port string, t *testing.T) {
|
||||
t.Log("vless sever got new conn")
|
||||
go func() {
|
||||
defer lc.Close()
|
||||
wlc, _, targetAddr, err := server.Handshake(lc)
|
||||
wlc, targetAddr, err := server.Handshake(lc)
|
||||
if err != nil {
|
||||
t.Logf("failed in handshake form %v: %v", server.AddrStr(), err)
|
||||
t.Fail()
|
||||
@@ -222,7 +222,7 @@ func testVLessUDP(version int, port string, t *testing.T) {
|
||||
}
|
||||
go func() {
|
||||
defer lc.Close()
|
||||
wlc, _, targetAddr, err := fakeServerEndLocalServer.Handshake(lc)
|
||||
wlc, targetAddr, err := fakeServerEndLocalServer.Handshake(lc)
|
||||
if err != nil {
|
||||
t.Logf("failed in handshake form %v: %v", fakeServerEndLocalServer.AddrStr(), err)
|
||||
t.Fail()
|
||||
|
||||
@@ -75,7 +75,7 @@ func testTls(protocol string, port string, t *testing.T) {
|
||||
|
||||
t.Log("server pass tls handshake")
|
||||
|
||||
wlc, _, targetAddr, err := server.Handshake(lc)
|
||||
wlc, targetAddr, err := server.Handshake(lc)
|
||||
if err != nil {
|
||||
t.Log("failed in handshake from ", server.AddrStr(), err)
|
||||
t.Fail()
|
||||
|
||||
Reference in New Issue
Block a user