上一个commit修改了函数签名,不好,太笨,还是不改好

proxy.Server返回的 *bytes.Buffer只被用于Fallback,所以直接放到Fallback里就行
This commit is contained in:
hahahrfool
2022-03-16 08:19:09 +08:00
parent 861d5a74c5
commit fa1c5db1ef
7 changed files with 53 additions and 39 deletions

View File

@@ -1,6 +1,10 @@
package httpLayer package httpLayer
import "github.com/hahahrfool/v2ray_simple/proxy" import (
"bytes"
"github.com/hahahrfool/v2ray_simple/proxy"
)
const ( const (
Fallback_none = 0 Fallback_none = 0
@@ -21,10 +25,12 @@ func HasFallbackType(ftype, b byte) bool {
type Fallback interface { type Fallback interface {
GetFallback(ftype byte, param string) *proxy.Addr GetFallback(ftype byte, param string) *proxy.Addr
SupportType() byte //参考Fallback_开头的常量。如果支持多个则返回它们 按位与 的结果 SupportType() byte //参考Fallback_开头的常量。如果支持多个则返回它们 按位与 的结果
FirstBuffer() *bytes.Buffer
} }
type SingleFallback struct { type SingleFallback struct {
Addr *proxy.Addr Addr *proxy.Addr
First *bytes.Buffer
} }
func (ef *SingleFallback) GetFallback(ftype byte, param string) *proxy.Addr { func (ef *SingleFallback) GetFallback(ftype byte, param string) *proxy.Addr {
@@ -35,6 +41,10 @@ func (ef *SingleFallback) SupportType() byte {
return FallBack_default return FallBack_default
} }
func (ef *SingleFallback) FirstBuffer() *bytes.Buffer {
return ef.First
}
//实现 Fallback //实现 Fallback
type ClassicFallback struct { type ClassicFallback struct {
Default *proxy.Addr Default *proxy.Addr
@@ -97,6 +107,7 @@ type ErrSingleFallback struct {
FallbackAddr *proxy.Addr FallbackAddr *proxy.Addr
Err error Err error
eStr string eStr string
First *bytes.Buffer
} }
func (ef *ErrSingleFallback) Error() string { func (ef *ErrSingleFallback) Error() string {
@@ -109,6 +120,7 @@ func (ef *ErrSingleFallback) Error() string {
//返回 SingleFallback //返回 SingleFallback
func (ef *ErrSingleFallback) Fallback() Fallback { func (ef *ErrSingleFallback) Fallback() Fallback {
return &SingleFallback{ return &SingleFallback{
Addr: ef.FallbackAddr, Addr: ef.FallbackAddr,
First: ef.First,
} }
} }

10
main.go
View File

@@ -188,8 +188,9 @@ func handleNewIncomeConnection(localServer proxy.Server, remoteClient proxy.Clie
} }
//isfallback := false //isfallback := false
var theFallback httpLayer.Fallback
wlc, localServerFirstReadBuf, targetAddr, err := localServer.Handshake(thisLocalConnectionInstance) wlc, targetAddr, err := localServer.Handshake(thisLocalConnectionInstance)
if err != nil { if err != nil {
log.Println("failed in handshake from", localServer.AddrStr(), err) 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) fe, ok := err.(httpLayer.FallbackErr)
if ok { if ok {
f := fe.Fallback() f := fe.Fallback()
theFallback = f
if httpLayer.HasFallbackType(f.SupportType(), httpLayer.FallBack_default) { if httpLayer.HasFallbackType(f.SupportType(), httpLayer.FallBack_default) {
targetAddr = f.GetFallback(httpLayer.FallBack_default, "") targetAddr = f.GetFallback(httpLayer.FallBack_default, "")
@@ -424,10 +426,10 @@ afterLocalServerHandshake:
} }
if localServerFirstReadBuf != nil { if theFallback != nil {
//这里注意因为是吧tls解密了之后的数据发送到目标地址所以这种方式只支持转发到本机纯http服务器 //这里注意因为是吧tls解密了之后的数据发送到目标地址所以这种方式只支持转发到本机纯http服务器
wrc.Write(localServerFirstReadBuf.Bytes()) wrc.Write(theFallback.FirstBuffer().Bytes())
common.PutBytes(localServerFirstReadBuf.Bytes()) //这个Buf不是从common.GetBuf创建的而是从一个 GetBytes的[]byte 包装 的 common.PutBytes(theFallback.FirstBuffer().Bytes()) //这个Buf不是从common.GetBuf创建的而是从一个 GetBytes的[]byte 包装 的
} }
/* /*

View File

@@ -91,7 +91,6 @@ ws和grpc文件夹第七层
package proxy package proxy
import ( import (
"bytes"
"fmt" "fmt"
"io" "io"
"net" "net"
@@ -256,7 +255,7 @@ type Server interface {
Name() string Name() string
Handshake(underlay net.Conn) (io.ReadWriter, *bytes.Buffer, *Addr, error) Handshake(underlay net.Conn) (io.ReadWriter, *Addr, error)
Stop() Stop()
CanFallback() bool //如果能fallback则handshake失败后会专门返回 ErrFallback CanFallback() bool //如果能fallback则handshake失败后会专门返回 ErrFallback

View File

@@ -54,10 +54,10 @@ func (s *Server) CanFallback() bool {
//中文: https://aber.sh/articles/Socks5/ //中文: https://aber.sh/articles/Socks5/
// 参考 https://studygolang.com/articles/31404 // 参考 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 // Set handshake timeout 4 seconds
if err := underlay.SetReadDeadline(time.Now().Add(time.Second * 4)); err != nil { 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{}) defer underlay.SetReadDeadline(time.Time{})
@@ -68,24 +68,24 @@ func (s *Server) Handshake(underlay net.Conn) (io.ReadWriter, *bytes.Buffer, *pr
// 一般握手包发来的是 [5 1 0] // 一般握手包发来的是 [5 1 0]
n, err := underlay.Read(buf) n, err := underlay.Read(buf)
if err != nil || n == 0 { 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] version := buf[0]
if version != Version5 { 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] // Write hello response [5 0]
// TODO: Support Auth // TODO: Support Auth
_, err = underlay.Write([]byte{Version5, AuthNone}) _, err = underlay.Write([]byte{Version5, AuthNone})
if err != nil { 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 // Read command message
n, err = underlay.Read(buf) n, err = underlay.Read(buf)
if err != nil || n < 7 { // Shortest length is 7 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 n3表示域名n是域名长度然后域名很可能是 119 119 119 46 开头,表示 www. // 一般可以为 5 1 0 3 n3表示域名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] cmd := buf[1]
switch cmd { switch cmd {
case CmdBind: case CmdBind:
return nil, nil, nil, fmt.Errorf("unsuppoted command %v", cmd) return nil, nil, fmt.Errorf("unsuppoted command %v", cmd)
case CmdUDPAssociate: case CmdUDPAssociate:
} }
@@ -114,11 +114,11 @@ func (s *Server) Handshake(underlay net.Conn) (io.ReadWriter, *bytes.Buffer, *pr
l += int(buf[4]) l += int(buf[4])
off = 5 off = 5
default: 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 { 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 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) serverAtyp, serverAddr, _, err := proxy.ParseStrToAddr(s.Addr)
if serverAtyp != proxy.AtypIP4 { //暂时先只支持ipv4为了简单起见 if serverAtyp != proxy.AtypIP4 { //暂时先只支持ipv4为了简单起见
if err != nil { 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) udpRC, err := net.ListenUDP("udp", udpPreparedAddr)
if err != nil { if err != nil {
return nil, nil, nil, errors.New("UDPAssociate: unable to listen udp") return nil, nil, errors.New("UDPAssociate: unable to listen udp")
} }
//ver5, rep0表示成功, rsv0, atyp(1, 即ipv4), BND.ADDR(4字节的ipv4) , BND.PORT(2字节) //ver5, rep0表示成功, rsv0, 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 // Write command response
_, err = underlay.Write(reply) _, err = underlay.Write(reply)
if err != nil { 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{ uc := &UDPConn{
clientSupposedAddr: clientFutureAddr, clientSupposedAddr: clientFutureAddr,
UDPConn: udpRC, UDPConn: udpRC,
} }
return uc, nil, clientFutureAddr, nil return uc, clientFutureAddr, nil
} else { } else {
addr := &proxy.Addr{ addr := &proxy.Addr{
@@ -194,10 +194,10 @@ func (s *Server) Handshake(underlay net.Conn) (io.ReadWriter, *bytes.Buffer, *pr
_, err = underlay.Write(reply) _, err = underlay.Write(reply)
if err != nil { 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
} }
} }

View File

@@ -130,12 +130,11 @@ func (s *Server) GetUserByStr(str string) proxy.User {
func (s *Server) Name() string { return Name } func (s *Server) Name() string { return Name }
//原本我们直接 // 返回的bytes.Buffer 是用于 回落使用的,内含了整个读取的数据;不回落时不要使用该Buffer
//see https://github.com/v2fly/v2ray-core/blob/master/proxy/vless/inbound/inbound.go func (s *Server) Handshake(underlay net.Conn) (io.ReadWriter, *proxy.Addr, error) {
func (s *Server) Handshake(underlay net.Conn) (io.ReadWriter, *bytes.Buffer, *proxy.Addr, error) {
if err := underlay.SetReadDeadline(time.Now().Add(time.Second * 4)); err != nil { 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{}) 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 //var auth [17]byte
wholeReadLen, err := underlay.Read(readbs) wholeReadLen, err := underlay.Read(readbs)
if err != nil { 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 { if wholeReadLen < 17 {
//根据下面回答HTTP的最小长度恰好是16字节但是是0.9版本。1.0是18字节1.1还要更长。总之我们可以直接不返回fallback地址 //根据下面回答HTTP的最小长度恰好是16字节但是是0.9版本。1.0是18字节1.1还要更长。总之我们可以直接不返回fallback地址
//https://stackoverflow.com/questions/25047905/http-request-minimum-size-in-bytes/25065089 //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: errorPart:
//fallback 所返回的buffer必须包含所有数据而Buffer不支持会退所以只能重新New //fallback 所返回的buffer必须包含所有数据而Buffer不支持会退所以只能重新New
return nil, bytes.NewBuffer(readbs[:wholeReadLen]), nil, &httpLayer.ErrSingleFallback{ return nil, nil, &httpLayer.ErrSingleFallback{
FallbackAddr: s.defaultfallbackAddr, FallbackAddr: s.defaultfallbackAddr,
Err: returnErr, Err: returnErr,
First: bytes.NewBuffer(readbs[:wholeReadLen]),
} }
realPart: realPart:
//这部分过程可以参照 v2ray的 proxy/vless/encoding/encoding.go DecodeRequestHeader 方法 //这部分过程可以参照 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) auth := readbuf.Next(17)
@@ -204,7 +205,7 @@ realPart:
addonLenByte, err := readbuf.ReadByte() addonLenByte, err := readbuf.ReadByte()
if err != nil { if err != nil {
return nil, nil, nil, err //凡是和的层Read相关的错误一律不再返回Fallback信息因为连接已然不可用 return nil, nil, err //凡是和的层Read相关的错误一律不再返回Fallback信息因为连接已然不可用
} }
if addonLenByte != 0 { if addonLenByte != 0 {
//v2ray的vless中没有对应的任何处理。 //v2ray的vless中没有对应的任何处理。
@@ -218,7 +219,7 @@ realPart:
common.PutBytes(tmpBuf) common.PutBytes(tmpBuf)
*/ */
if tmpbs := readbuf.Next(int(addonLenByte)); len(tmpbs) != int(addonLenByte) { 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() s.mux4Hashes.Unlock()
return nil, readbuf, addr, nil return nil, addr, nil
case proxy.CmdTCP, proxy.CmdUDP: case proxy.CmdTCP, proxy.CmdUDP:
@@ -327,7 +328,7 @@ realPart:
_, err = readbuf.Read(ip_or_domain) _, err = readbuf.Read(ip_or_domain)
if err != nil { if err != nil {
return nil, nil, nil, errors.New("fallback, reason 6") return nil, nil, errors.New("fallback, reason 6")
} }
if addr.IP != nil { if addr.IP != nil {
@@ -351,7 +352,7 @@ realPart:
version: int(version), version: int(version),
isUDP: addr.IsUDP, isUDP: addr.IsUDP,
isServerEnd: true, isServerEnd: true,
}, readbuf, addr, nil }, addr, nil
} }
func (s *Server) Stop() { func (s *Server) Stop() {

View File

@@ -54,7 +54,7 @@ func testVLess(version int, port string, t *testing.T) {
t.Log("vless sever got new conn") t.Log("vless sever got new conn")
go func() { go func() {
defer lc.Close() defer lc.Close()
wlc, _, targetAddr, err := server.Handshake(lc) wlc, targetAddr, err := server.Handshake(lc)
if err != nil { if err != nil {
t.Logf("failed in handshake form %v: %v", server.AddrStr(), err) t.Logf("failed in handshake form %v: %v", server.AddrStr(), err)
t.Fail() t.Fail()
@@ -222,7 +222,7 @@ func testVLessUDP(version int, port string, t *testing.T) {
} }
go func() { go func() {
defer lc.Close() defer lc.Close()
wlc, _, targetAddr, err := fakeServerEndLocalServer.Handshake(lc) wlc, targetAddr, err := fakeServerEndLocalServer.Handshake(lc)
if err != nil { if err != nil {
t.Logf("failed in handshake form %v: %v", fakeServerEndLocalServer.AddrStr(), err) t.Logf("failed in handshake form %v: %v", fakeServerEndLocalServer.AddrStr(), err)
t.Fail() t.Fail()

View File

@@ -75,7 +75,7 @@ func testTls(protocol string, port string, t *testing.T) {
t.Log("server pass tls handshake") t.Log("server pass tls handshake")
wlc, _, targetAddr, err := server.Handshake(lc) wlc, targetAddr, err := server.Handshake(lc)
if err != nil { if err != nil {
t.Log("failed in handshake from ", server.AddrStr(), err) t.Log("failed in handshake from ", server.AddrStr(), err)
t.Fail() t.Fail()