diff --git a/go.mod b/go.mod index b38b017..e7acc8f 100644 --- a/go.mod +++ b/go.mod @@ -2,6 +2,4 @@ module github.com/hahahrfool/v2ray_simple go 1.14 -require ( - -) +require github.com/yl2chen/cidranger v1.0.2 diff --git a/go.sum b/go.sum index a0b30ae..39d3edc 100644 --- a/go.sum +++ b/go.sum @@ -5,10 +5,13 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.1 h1:52QO5WkIUcHGIR7EnGagH88x1bUzqGXTC5/1bDTUQ7U= github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/yl2chen/cidranger v1.0.0 h1:9tdo0orHQJvXsX6mf+1Goou/R4kq21AfpbYeTcpXs2Q= github.com/yl2chen/cidranger v1.0.0/go.mod h1:L7Msw4X7EQK7zMVjOtv7o8xMyjv1rJcNlYlMgGwP7ko= +github.com/yl2chen/cidranger v1.0.2 h1:lbOWZVCG1tCRX4u24kuM1Tb4nHqWkDxwLdoS+SevawU= +github.com/yl2chen/cidranger v1.0.2/go.mod h1:9U1yz7WPYDwf0vpNWFaeRh0bjwz5RVgRy/9UEQfHl0g= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899 h1:DZhuSZLsGlFL4CmhA8BcRA0mnthyA/nZ00AqCUo7vHg= golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -19,5 +22,6 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5 golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/httpLayer/fallback.go b/httpLayer/fallback.go index c61df1f..e0f0f2d 100644 --- a/httpLayer/fallback.go +++ b/httpLayer/fallback.go @@ -3,7 +3,7 @@ package httpLayer import ( "bytes" - "github.com/hahahrfool/v2ray_simple/proxy" + "github.com/hahahrfool/v2ray_simple/netLayer" ) const ( @@ -23,17 +23,17 @@ func HasFallbackType(ftype, b byte) bool { //实现 Fallback. 这里的fallback只与http协议有关,所以只能按path,alpn 和 sni 进行分类 type Fallback interface { - GetFallback(ftype byte, param string) *proxy.Addr + GetFallback(ftype byte, param string) *netLayer.Addr SupportType() byte //参考Fallback_开头的常量。如果支持多个,则返回它们 按位与 的结果 FirstBuffer() *bytes.Buffer } type SingleFallback struct { - Addr *proxy.Addr + Addr *netLayer.Addr First *bytes.Buffer } -func (ef *SingleFallback) GetFallback(ftype byte, param string) *proxy.Addr { +func (ef *SingleFallback) GetFallback(ftype byte, param string) *netLayer.Addr { return ef.Addr } @@ -47,20 +47,24 @@ func (ef *SingleFallback) FirstBuffer() *bytes.Buffer { //实现 Fallback type ClassicFallback struct { - Default *proxy.Addr - MapByPath map[string]*proxy.Addr //因为只一次性设置,之后仅用于读,所以不会有多线程问题 - MapByAlpn map[string]*proxy.Addr - MapBySni map[string]*proxy.Addr + First *bytes.Buffer + Default *netLayer.Addr + MapByPath map[string]*netLayer.Addr //因为只一次性设置,之后仅用于读,所以不会有多线程问题 + MapByAlpn map[string]*netLayer.Addr + MapBySni map[string]*netLayer.Addr } func NewClassicFallback() *ClassicFallback { return &ClassicFallback{ - MapByPath: make(map[string]*proxy.Addr), - MapByAlpn: make(map[string]*proxy.Addr), - MapBySni: make(map[string]*proxy.Addr), + MapByPath: make(map[string]*netLayer.Addr), + MapByAlpn: make(map[string]*netLayer.Addr), + MapBySni: make(map[string]*netLayer.Addr), } } +func (ef *ClassicFallback) FirstBuffer() *bytes.Buffer { + return ef.First +} func (ef *ClassicFallback) SupportType() byte { var r byte = 0 @@ -83,7 +87,7 @@ func (ef *ClassicFallback) SupportType() byte { return FallBack_default } -func (ef *ClassicFallback) GetFallback(ftype byte, s string) *proxy.Addr { +func (ef *ClassicFallback) GetFallback(ftype byte, s string) *netLayer.Addr { switch ftype { default: return ef.Default @@ -104,7 +108,7 @@ type FallbackErr interface { //实现 FallbackErr type ErrSingleFallback struct { - FallbackAddr *proxy.Addr + FallbackAddr *netLayer.Addr Err error eStr string First *bytes.Buffer diff --git a/main.go b/main.go index e753aa1..6078fb0 100644 --- a/main.go +++ b/main.go @@ -16,6 +16,7 @@ import ( "github.com/hahahrfool/v2ray_simple/common" "github.com/hahahrfool/v2ray_simple/httpLayer" + "github.com/hahahrfool/v2ray_simple/netLayer" "github.com/hahahrfool/v2ray_simple/proxy/direct" "github.com/hahahrfool/v2ray_simple/proxy/socks5" "github.com/hahahrfool/v2ray_simple/proxy/vless" @@ -338,7 +339,7 @@ afterLocalServerHandshake: return } - var realTargetAddr *proxy.Addr = targetAddr //direct的话自己是没有目的地址的,直接使用 请求的地址 + var realTargetAddr *netLayer.Addr = targetAddr //direct的话自己是没有目的地址的,直接使用 请求的地址 if uniqueTestDomain != "" && uniqueTestDomain != targetAddr.Name { log.Println("request isn't the appointed domain", targetAddr, uniqueTestDomain) @@ -350,7 +351,7 @@ afterLocalServerHandshake: if client.AddrStr() != "" { //log.Println("will dial", client.AddrStr()) - realTargetAddr, _ = proxy.NewAddr(client.AddrStr()) + realTargetAddr, _ = netLayer.NewAddr(client.AddrStr()) } clientConn, err := realTargetAddr.Dial() @@ -449,10 +450,10 @@ afterLocalServerHandshake: } // tryRawCopy 尝试能否直接对拷,对拷 直接使用 原始 TCPConn,也就是裸奔转发 -//和 xtls的splice 含义相同 +// 和 xtls的splice 含义相同. // 我们内部先 使用 DetectConn进行过滤分析,然后再判断进化为splice 或者退化为普通拷贝 -// 前两个参数仅用于 tls_lazy_secure -func tryRawCopy(useSecureMethod bool, proxy_client proxy.UserClient, proxy_server proxy.UserServer, clientAddr *proxy.Addr, wrc, wlc io.ReadWriter, localConn net.Conn, isclient bool, theRecorder *tlsLayer.Recorder) { +// 第一个参数仅用于 tls_lazy_secure +func tryRawCopy(useSecureMethod bool, proxy_client proxy.UserClient, proxy_server proxy.UserServer, clientAddr *netLayer.Addr, wrc, wlc io.ReadWriter, localConn net.Conn, isclient bool, theRecorder *tlsLayer.Recorder) { //如果用了 lazy_encrypt, 则不直接利用Copy,因为有两个阶段:判断阶段和直连阶段 // 在判断阶段,因为还没确定是否是 tls,所以是要继续用tls加密的, diff --git a/proxy/addr.go b/netLayer/addr.go similarity index 93% rename from proxy/addr.go rename to netLayer/addr.go index a3b33fe..ed939d5 100644 --- a/proxy/addr.go +++ b/netLayer/addr.go @@ -1,10 +1,17 @@ -package proxy +package netLayer import ( "net" "strconv" ) +// Atyp, for vless and vmess; 注意与 trojan和socks5的区别,trojan和socks5的相同含义的值是1,3,4 +const ( + AtypIP4 byte = 1 + AtypDomain byte = 2 + AtypIP6 byte = 3 +) + // Addr represents a address that you want to access by proxy. Either Name or IP is used exclusively. type Addr struct { Name string // domain name diff --git a/netLayer/matcher.go b/netLayer/matcher.go new file mode 100644 index 0000000..c172ae7 --- /dev/null +++ b/netLayer/matcher.go @@ -0,0 +1,19 @@ +package netLayer + +import ( + "net" + + "github.com/yl2chen/cidranger" +) + +type TargetDescription struct { +} + +//任意一个参数匹配后,都将发往相同的方向,具体房向并不是 SameGroup 所关心的 +// SameGroup只负责把一些属性相同的 “网络层特征” 放到一起 +type SameGroup struct { + NetRanger cidranger.Ranger + IPMap map[string]net.IP + DomainMap map[string]string + TagMap map[string]bool +} diff --git a/netLayer/netlayer.go b/netLayer/netlayer.go new file mode 100644 index 0000000..e360ff3 --- /dev/null +++ b/netLayer/netlayer.go @@ -0,0 +1,4 @@ +/* + package netLayer contains definitions in network layer AND transport layer +*/ +package netLayer diff --git a/proxy/constant.go b/proxy/constant.go index 72a4aa7..15e0260 100644 --- a/proxy/constant.go +++ b/proxy/constant.go @@ -7,10 +7,3 @@ const ( CmdUDP CmdMux ) - -// Atyp, for vless and vmess; 注意与 trojan和socks5的区别,trojan和socks5的相同含义的值是1,3,4 -const ( - AtypIP4 byte = 1 - AtypDomain byte = 2 - AtypIP6 byte = 3 -) diff --git a/proxy/direct/client.go b/proxy/direct/client.go index 2052600..7343d63 100644 --- a/proxy/direct/client.go +++ b/proxy/direct/client.go @@ -6,6 +6,7 @@ import ( "net/url" "sync" + "github.com/hahahrfool/v2ray_simple/netLayer" "github.com/hahahrfool/v2ray_simple/proxy" ) @@ -19,7 +20,7 @@ type Direct struct { proxy.ProxyCommonStruct *proxy.UDP_Pipe - targetAddr *proxy.Addr + targetAddr *netLayer.Addr addrStr string } @@ -33,7 +34,7 @@ func NewDirectClient(url *url.URL) (proxy.Client, error) { func (d *Direct) Name() string { return name } -func (d *Direct) Handshake(underlay net.Conn, target *proxy.Addr) (io.ReadWriter, error) { +func (d *Direct) Handshake(underlay net.Conn, target *netLayer.Addr) (io.ReadWriter, error) { if underlay == nil { d.targetAddr = target diff --git a/proxy/proxy.go b/proxy/proxy.go index 3546951..d401029 100644 --- a/proxy/proxy.go +++ b/proxy/proxy.go @@ -98,6 +98,7 @@ import ( "strings" "github.com/hahahrfool/v2ray_simple/common" + "github.com/hahahrfool/v2ray_simple/netLayer" "github.com/hahahrfool/v2ray_simple/tlsLayer" ) @@ -196,7 +197,7 @@ type Client interface { Name() string // Handshake的 underlay有可能传入nil,所以要求 所有的 Client 都要能够自己dial - Handshake(underlay net.Conn, target *Addr) (io.ReadWriter, error) + Handshake(underlay net.Conn, target *netLayer.Addr) (io.ReadWriter, error) } // ClientCreator is a function to create client. @@ -255,7 +256,7 @@ type Server interface { Name() string - Handshake(underlay net.Conn) (io.ReadWriter, *Addr, error) + Handshake(underlay net.Conn) (io.ReadWriter, *netLayer.Addr, error) Stop() CanFallback() bool //如果能fallback,则handshake失败后,会专门返回 ErrFallback diff --git a/proxy/socks5/server.go b/proxy/socks5/server.go index bf49098..bb95209 100644 --- a/proxy/socks5/server.go +++ b/proxy/socks5/server.go @@ -12,6 +12,7 @@ import ( "time" "github.com/hahahrfool/v2ray_simple/common" + "github.com/hahahrfool/v2ray_simple/netLayer" "github.com/hahahrfool/v2ray_simple/proxy" ) @@ -54,7 +55,7 @@ func (s *Server) CanFallback() bool { //中文: https://aber.sh/articles/Socks5/ // 参考 https://studygolang.com/articles/31404 -func (s *Server) Handshake(underlay net.Conn) (io.ReadWriter, *proxy.Addr, error) { +func (s *Server) Handshake(underlay net.Conn) (io.ReadWriter, *netLayer.Addr, error) { // Set handshake timeout 4 seconds if err := underlay.SetReadDeadline(time.Now().Add(time.Second * 4)); err != nil { return nil, nil, err @@ -136,15 +137,15 @@ func (s *Server) Handshake(underlay net.Conn) (io.ReadWriter, *proxy.Addr, error //总之,UDP Associate方法并不是 UDP over TCP,完全不同,而且过程中握手用tcp,传输用udp,使用到了两个连接。 if cmd == CmdUDPAssociate { - clientFutureAddr := &proxy.Addr{ + clientFutureAddr := &netLayer.Addr{ IP: theIP, Name: theName, Port: thePort, IsUDP: true, } - serverAtyp, serverAddr, _, err := proxy.ParseStrToAddr(s.Addr) - if serverAtyp != proxy.AtypIP4 { //暂时先只支持ipv4,为了简单起见 + serverAtyp, serverAddr, _, err := netLayer.ParseStrToAddr(s.Addr) + if serverAtyp != netLayer.AtypIP4 { //暂时先只支持ipv4,为了简单起见 if err != nil { return nil, nil, errors.New("UDPAssociate: can't listen an domain, must be ip") } @@ -180,7 +181,7 @@ func (s *Server) Handshake(underlay net.Conn) (io.ReadWriter, *proxy.Addr, error return uc, clientFutureAddr, nil } else { - addr := &proxy.Addr{ + addr := &netLayer.Addr{ IP: theIP, Name: theName, Port: thePort, @@ -208,7 +209,7 @@ func (s *Server) Stop() { type UDPConn struct { *net.UDPConn - clientSupposedAddr *proxy.Addr //客户端指定的客户端自己未来将使用的公网UDP的Addr + clientSupposedAddr *netLayer.Addr //客户端指定的客户端自己未来将使用的公网UDP的Addr clientSupposedAddrIsNothing bool } @@ -313,7 +314,7 @@ func (u *UDPConn) StartReadRequest(udpPutter proxy.UDP_Putter) { newStart := off + l - thisaddr := &proxy.Addr{ + thisaddr := &netLayer.Addr{ IP: theIP, Name: theName, Port: thePort, diff --git a/proxy/vless/client.go b/proxy/vless/client.go index c60b8ed..ee1f1fc 100644 --- a/proxy/vless/client.go +++ b/proxy/vless/client.go @@ -12,6 +12,7 @@ import ( "sync" "github.com/hahahrfool/v2ray_simple/common" + "github.com/hahahrfool/v2ray_simple/netLayer" "github.com/hahahrfool/v2ray_simple/proxy" ) @@ -72,7 +73,7 @@ func (c *Client) GetUser() proxy.User { return c.user } -func (c *Client) Handshake(underlay net.Conn, target *proxy.Addr) (io.ReadWriter, error) { +func (c *Client) Handshake(underlay net.Conn, target *netLayer.Addr) (io.ReadWriter, error) { var err error if underlay == nil { @@ -155,7 +156,7 @@ func (c *Client) WriteUDPRequest(a *net.UDPAddr, b []byte) (err error) { if knownConn == nil { - knownConn, err = c.Handshake(nil, proxy.NewAddrFromUDPAddr(a)) + knownConn, err = c.Handshake(nil, netLayer.NewAddrFromUDPAddr(a)) if err != nil { return err } @@ -227,7 +228,7 @@ func (c *Client) handle_CRUMFURS(UMFURS_conn net.Conn) { atyp := msg[0] portIndex := net.IPv4len switch atyp { - case proxy.AtypIP6: + case netLayer.AtypIP6: portIndex = net.IPv6len default: //不合法,必须是ipv4或者ipv6 @@ -258,7 +259,7 @@ func (c *Client) handle_CRUMFURS(UMFURS_conn net.Conn) { ipLen := net.IPv4len switch atyp { - case proxy.AtypIP6: + case netLayer.AtypIP6: ipLen = net.IPv6len default: //不合法,必须是ipv4或者ipv6 diff --git a/proxy/vless/server.go b/proxy/vless/server.go index 4b3a93e..ce16402 100644 --- a/proxy/vless/server.go +++ b/proxy/vless/server.go @@ -15,6 +15,7 @@ import ( "github.com/hahahrfool/v2ray_simple/common" "github.com/hahahrfool/v2ray_simple/httpLayer" + "github.com/hahahrfool/v2ray_simple/netLayer" "github.com/hahahrfool/v2ray_simple/proxy" ) @@ -29,7 +30,7 @@ type Server struct { userCRUMFURS map[[16]byte]*CRUMFURS mux4Hashes sync.RWMutex - defaultfallbackAddr *proxy.Addr + defaultfallbackAddr *netLayer.Addr } func NewVlessServer(url *url.URL) (proxy.Server, error) { @@ -52,7 +53,7 @@ func NewVlessServer(url *url.URL) (proxy.Server, error) { fallbackStr := query.Get("fallback") if fallbackStr != "" { - fa, err := proxy.NewAddr(fallbackStr) + fa, err := netLayer.NewAddr(fallbackStr) if err != nil { return nil, fmt.Errorf("invalid fallback %v", fallbackStr) @@ -131,7 +132,7 @@ func (s *Server) GetUserByStr(str string) proxy.User { func (s *Server) Name() string { return Name } // 返回的bytes.Buffer 是用于 回落使用的,内含了整个读取的数据;不回落时不要使用该Buffer -func (s *Server) Handshake(underlay net.Conn) (io.ReadWriter, *proxy.Addr, error) { +func (s *Server) Handshake(underlay net.Conn) (io.ReadWriter, *netLayer.Addr, error) { if err := underlay.SetReadDeadline(time.Now().Add(time.Second * 4)); err != nil { return nil, nil, err @@ -232,7 +233,7 @@ realPart: goto errorPart } - addr := &proxy.Addr{} + addr := &netLayer.Addr{} switch commandByte { case proxy.CmdMux: //实际目前暂时verysimple还未实现mux,先这么写 @@ -296,12 +297,12 @@ realPart: } switch addrTypeByte { - case proxy.AtypIP4: + case netLayer.AtypIP4: ip_or_domain_bytesLength = net.IPv4len addr.IP = common.GetBytes(net.IPv4len) - case proxy.AtypDomain: + case netLayer.AtypDomain: // 解码域名的长度 domainNameLenByte, err := readbuf.ReadByte() @@ -313,7 +314,7 @@ realPart: } ip_or_domain_bytesLength = domainNameLenByte - case proxy.AtypIP6: + case netLayer.AtypIP6: ip_or_domain_bytesLength = net.IPv6len addr.IP = common.GetBytes(net.IPv6len) @@ -373,9 +374,9 @@ type CRUMFURS struct { } func (c *CRUMFURS) WriteUDPResponse(a *net.UDPAddr, b []byte) (err error) { - atype := proxy.AtypIP4 + atype := netLayer.AtypIP4 if len(a.IP) > 4 { - atype = proxy.AtypIP6 + atype = netLayer.AtypIP6 } buf := common.GetBuf() diff --git a/proxy/vless/vless_test.go b/proxy/vless/vless_test.go index f3a9ef4..dcd0ad7 100644 --- a/proxy/vless/vless_test.go +++ b/proxy/vless/vless_test.go @@ -10,6 +10,7 @@ import ( "strings" "testing" + "github.com/hahahrfool/v2ray_simple/netLayer" "github.com/hahahrfool/v2ray_simple/proxy" ) @@ -34,7 +35,7 @@ func testVLess(version int, port string, t *testing.T) { } targetStr := "dummy.com:80" - targetStruct := &proxy.Addr{ + targetStruct := &netLayer.Addr{ Name: "dummy.com", Port: 80, } @@ -200,7 +201,7 @@ func testVLessUDP(version int, port string, t *testing.T) { }() targetStr_forFakeUDPServer := "127.0.0.1:" + strconv.Itoa(thePort) - targetStruct_forFakeUDPServer := &proxy.Addr{ + targetStruct_forFakeUDPServer := &netLayer.Addr{ Name: "127.0.0.1", Port: thePort, IsUDP: true, diff --git a/tls_test.go b/tls_test.go index c3677c0..8118054 100644 --- a/tls_test.go +++ b/tls_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/hahahrfool/v2ray_simple/common" + "github.com/hahahrfool/v2ray_simple/netLayer" "github.com/hahahrfool/v2ray_simple/proxy" ) @@ -42,7 +43,7 @@ func testTls(protocol string, port string, t *testing.T) { } targetStr := "dummy.com:80" - targetStruct := &proxy.Addr{ + targetStruct := &netLayer.Addr{ Name: "dummy.com", Port: 80, }