diff --git a/advLayer/advLayer.go b/advLayer/advLayer.go index 318c5ff..8abca73 100644 --- a/advLayer/advLayer.go +++ b/advLayer/advLayer.go @@ -6,6 +6,7 @@ import ( "crypto/tls" "errors" "fmt" + "io" "net" "github.com/e1732a364fed/v2ray_simple/netLayer" @@ -16,6 +17,8 @@ var ErrPreviousFull = errors.New("previous conn full") var ProtocolsMap = make(map[string]Creator) +var MaxEarlyDataLen = 2048 //for ws early data + func PrintAllProtocolNames() { fmt.Printf("===============================\nSupported Advanced Layer protocols:\n") for _, v := range utils.GetMapSortedKeySlice(ProtocolsMap) { @@ -42,6 +45,7 @@ type Conf struct { } type Client interface { + GetPath() string IsMux() bool //quic and grpc. if IsMux, then Client is a MuxClient, or it's a SingleClient IsEarly() bool //is 0-rtt or not. @@ -61,7 +65,10 @@ type SingleClient interface { type MuxClient interface { Client - GetCommonConn(underlay net.Conn) (conn any, err error) //if IsSuper, underlay should be nil + // If IsSuper, underlay should be nil; + // + // If not IsSuper and underlay == nil, it will return error if it can't find any extablished connection. + GetCommonConn(underlay net.Conn) (conn any, err error) DialSubConn(underlay any) (net.Conn, error) @@ -76,10 +83,21 @@ type Server interface { IsSuper() bool //quic } +//ws type SingleServer interface { Handshake(optionalFirstBuffer *bytes.Buffer, underlay net.Conn) (net.Conn, error) } +//grpc type MuxServer interface { + //non-blocking StartHandle(underlay net.Conn, newSubConnChan chan net.Conn) } + +//quic +type SuperMuxServer interface { + MuxServer + + //non-blocking. Super会直接掌控 原始链接的 监听过程, 并直接向 newSubConnChan 传递 子连接。 + StartListen() (newSubConnChan chan net.Conn, closer io.Closer) +} diff --git a/advLayer/grpc/client.go b/advLayer/grpc/client.go index 7a83802..7b053b8 100644 --- a/advLayer/grpc/client.go +++ b/advLayer/grpc/client.go @@ -113,6 +113,7 @@ func DialNewSubConn(path string, clientconn ClientConn, addr *netLayer.Addr, isM return newMultiConn(stream_multiTunClient, cancelF), nil } else { stream_TunClient, err := streamClient.tun_withName(ctx, path) + if err != nil { clientconnMutex.Lock() delete(clientconnMap, addr.GetHashable()) @@ -174,6 +175,10 @@ func NewClient(addr netLayer.Addr, path string) (*Client, error) { }, nil } +func (c *Client) GetPath() string { + return c.Path +} + func (c *Client) IsSuper() bool { return false } @@ -188,12 +193,16 @@ func (c *Client) IsEarly() bool { func (c *Client) GetCommonConn(underlay net.Conn) (any, error) { - cc := GetEstablishedConnFor(&c.ServerAddr) - if cc != nil { - return cc, nil + if underlay == nil { + cc := GetEstablishedConnFor(&c.ServerAddr) + if cc != nil { + return cc, nil + } else { + return nil, utils.ErrFailed + + } } else { return ClientHandshake(underlay, &c.ServerAddr) - } } diff --git a/advLayer/grpc/server.go b/advLayer/grpc/server.go index c53f819..9a9c4b4 100644 --- a/advLayer/grpc/server.go +++ b/advLayer/grpc/server.go @@ -70,9 +70,9 @@ func (s *Server) Tun(stream_TunServer Stream_TunServer) error { // 这里需要一个 <-tunCtx.Done() 进行阻塞;只有当 子连接被Close的时候, Done 才能通过, 才意味着本次子连接结束. - //正常的grpc的业务逻辑是,客户端传一大段数据上来,然后我们服务端同步传回一大段数据, 然后达到某个时间点后 就自动关闭 此次 rpc 过程调用。 + //正常的grpc的业务逻辑是,客户端传一大段数据上来,然后我们服务端同步传回一大段数据, 然后达到某个时间点后 或者 交换信息完成后, 就 马上关闭 此次 rpc 过程调用。 // 但是我们现在是作为代理用途, 所以到底发什么数据,和发送的时机都是在其它位置确定的, - // 我们只能 发送一个 新连接信号,然后等待外界Close子连接. + // 所以我们只能 发送一个 新连接信号,然后等待外界Close子连接. return nil } diff --git a/advLayer/quic/client.go b/advLayer/quic/client.go index 4a9aec5..ab03b67 100644 --- a/advLayer/quic/client.go +++ b/advLayer/quic/client.go @@ -44,13 +44,13 @@ func NewClient(addr *netLayer.Addr, alpnList []string, host string, insecure boo } //trimBadConns removes non-Active sessions, 并试图返回一个 最佳的可用于新stream的session -func (c *Client) trimBadConns(ss map[[16]byte]*connState) (s *connState) { +func (c *Client) trimBadConns() (bestConn *connState) { minSessionNum := 10000 - for id, thisState := range ss { + for id, thisState := range c.clientconns { if isActive(thisState) { if c.knownServerMaxStreamCount == 0 { - s = thisState + bestConn = thisState return } else { osc := int(thisState.openedStreamCount) @@ -58,7 +58,7 @@ func (c *Client) trimBadConns(ss map[[16]byte]*connState) (s *connState) { if osc < int(c.knownServerMaxStreamCount) { if osc < minSessionNum { - s = thisState + bestConn = thisState minSessionNum = osc } @@ -67,7 +67,7 @@ func (c *Client) trimBadConns(ss map[[16]byte]*connState) (s *connState) { } else { thisState.CloseWithError(0, "") - delete(ss, id) + delete(c.clientconns, id) } } @@ -95,7 +95,7 @@ func (c *Client) ProcessWhenFull(previous any) { } //获取已拨号的连接,或者重新从底层拨号。返回一个可作 c.DialSubConn 参数 的值. -func (c *Client) DialCommonConn(_ any) (any, error) { +func (c *Client) GetCommonConn(_ net.Conn) (any, error) { //返回一个 *sessionState. //我们采用预先openStream的策略, 来试出哪些session已经满了, 哪些没满 @@ -108,7 +108,7 @@ func (c *Client) DialCommonConn(_ any) (any, error) { c.connMapMutex.Lock() var theState *connState if len(c.clientconns) > 0 { - theState = c.trimBadConns(c.clientconns) + theState = c.trimBadConns() } if len(c.clientconns) > 0 { c.connMapMutex.Unlock() @@ -195,3 +195,6 @@ func (c *Client) IsMux() bool { func (c *Client) IsEarly() bool { return c.early } +func (c *Client) GetPath() string { + return "" +} diff --git a/advLayer/quic/quic.go b/advLayer/quic/quic.go index 8609747..8dbb207 100644 --- a/advLayer/quic/quic.go +++ b/advLayer/quic/quic.go @@ -10,7 +10,6 @@ import ( "time" "github.com/e1732a364fed/v2ray_simple/advLayer" - "github.com/e1732a364fed/v2ray_simple/utils" "github.com/lucas-clemente/quic-go" ) @@ -58,7 +57,7 @@ func CloseConn(baseC any) { } var ( - AlpnList = []string{"h3"} + DefaultAlpnList = []string{"h3"} common_ListenConfig = quic.Config{ ConnectionIDLength: common_ConnectionIDLength, @@ -80,9 +79,93 @@ var ( type Creator struct{} func (Creator) NewClientFromConf(conf *advLayer.Conf) (advLayer.Client, error) { - return NewClient(&conf.Addr, conf.TlsConf.NextProtos, conf.Host, conf.TlsConf.InsecureSkipVerify, false, 0, false, conf.IsEarly), nil + var alpn []string + if conf.TlsConf != nil { + alpn = conf.TlsConf.NextProtos + + } + + var useHysteria, hysteria_manual bool + var maxbyteCount int + + if len(alpn) == 0 { + alpn = DefaultAlpnList + } + + if conf.Extra != nil { + useHysteria, hysteria_manual, maxbyteCount, _ = getExtra(conf.Extra) + } + + return NewClient(&conf.Addr, alpn, conf.Host, conf.TlsConf.InsecureSkipVerify, useHysteria, maxbyteCount, hysteria_manual, conf.IsEarly), nil } func (Creator) NewServerFromConf(conf *advLayer.Conf) (advLayer.Server, error) { - return nil, utils.ErrNotImplemented + + var useHysteria, hysteria_manual bool + var maxbyteCount int + var maxStreamCountInOneSession int64 + + tlsConf := *conf.TlsConf + if len(tlsConf.NextProtos) == 0 { + tlsConf.NextProtos = DefaultAlpnList + } + + if conf.Extra != nil { + + useHysteria, hysteria_manual, maxbyteCount, maxStreamCountInOneSession = getExtra(conf.Extra) + + } + + return &Server{ + addr: conf.Addr.String(), + tlsConf: tlsConf, + useHysteria: useHysteria, + hysteria_manual: hysteria_manual, + hysteriaMaxByteCount: maxbyteCount, + customMaxStreamCountInOneConn: maxStreamCountInOneSession, + }, nil +} + +func getExtra(extra map[string]any) (useHysteria, hysteria_manual bool, + maxbyteCount int, + maxStreamCountInOneSession int64) { + + if thing := extra["maxStreamCountInOneSession"]; thing != nil { + if count, ok := thing.(int64); ok && count > 0 { + log.Println("maxStreamCountInOneSession,", count) + maxStreamCountInOneSession = count + + } + + } + + if thing := extra["congestion_control"]; thing != nil { + if use, ok := thing.(string); ok && use == "hy" { + useHysteria = true + + if thing := extra["mbps"]; thing != nil { + if mbps, ok := thing.(int64); ok && mbps > 1 { + maxbyteCount = int(mbps) * 1024 * 1024 / 8 + + log.Println("Using Hysteria Congestion Control, max upload mbps: ", mbps) + + } + } else { + + log.Println("Using Hysteria Congestion Control, max upload mbps:", Default_hysteriaMaxByteCount, "mbps") + + } + + if thing := extra["hy_manual"]; thing != nil { + if ismanual, ok := thing.(bool); ok { + hysteria_manual = ismanual + if ismanual { + log.Println("Using Hysteria Manual Control Mode") + } + } + } + } + } + + return } diff --git a/advLayer/quic/server.go b/advLayer/quic/server.go index 12bb301..44992df 100644 --- a/advLayer/quic/server.go +++ b/advLayer/quic/server.go @@ -3,6 +3,7 @@ package quic import ( "context" "crypto/tls" + "io" "net" "github.com/e1732a364fed/v2ray_simple/utils" @@ -11,7 +12,8 @@ import ( "go.uber.org/zap" ) -func ListenInitialLayers(addr string, tlsConf tls.Config, useHysteria bool, hysteriaMaxByteCount int, hysteria_manual, early bool, customMaxStreamCountInOneConn int64) (newConnChan chan net.Conn, baseConn any) { +//non-blocking +func ListenInitialLayers(addr string, tlsConf tls.Config, useHysteria bool, hysteriaMaxByteCount int, hysteria_manual, early bool, customMaxStreamCountInOneConn int64) (newConnChan chan net.Conn, baseConn io.Closer) { thisConfig := common_ListenConfig if customMaxStreamCountInOneConn > 0 { @@ -47,10 +49,11 @@ func ListenInitialLayers(addr string, tlsConf tls.Config, useHysteria bool, hyst if early { go loopAcceptEarly(elistener, newConnChan, useHysteria, hysteria_manual, hysteriaMaxByteCount) - + baseConn = elistener } else { go loopAccept(listener, newConnChan, useHysteria, hysteria_manual, hysteriaMaxByteCount) + baseConn = listener } return @@ -130,3 +133,32 @@ func dealNewConn(conn quic.Connection, theChan chan net.Conn) { theChan <- StreamConn{stream, conn.LocalAddr(), conn.RemoteAddr(), nil, false} } } + +type Server struct { + addr string + tlsConf tls.Config + useHysteria bool + hysteriaMaxByteCount int + hysteria_manual, early bool + customMaxStreamCountInOneConn int64 +} + +func (s *Server) GetPath() string { + return "" +} + +func (*Server) IsMux() bool { + return true +} + +func (*Server) IsSuper() bool { + return true +} + +func (s *Server) StartListen() (newSubConnChan chan net.Conn, baseConn io.Closer) { + return ListenInitialLayers(s.addr, s.tlsConf, s.useHysteria, s.hysteriaMaxByteCount, s.hysteria_manual, s.early, s.customMaxStreamCountInOneConn) +} + +func (s *Server) StartHandle(underlay net.Conn, newSubConnChan chan net.Conn) { + go dealNewConn(underlay.(quic.Connection), newSubConnChan) +} diff --git a/advLayer/ws/client.go b/advLayer/ws/client.go index dc1b28f..6236829 100644 --- a/advLayer/ws/client.go +++ b/advLayer/ws/client.go @@ -21,6 +21,7 @@ const MaxEarlyDataLen = 2048 //implements advLayer.Client type Client struct { requestURL *url.URL //因为调用gobwas/ws.Dialer.Upgrade 时要传入url,所以我们直接提供包装好的即可 + path string UseEarlyData bool headers map[string][]string @@ -34,11 +35,16 @@ func NewClient(hostAddr, path string, headers map[string][]string, isEarly bool) } return &Client{ requestURL: u, + path: path, headers: headers, UseEarlyData: isEarly, }, nil } +func (c *Client) GetPath() string { + return c.path +} + func (c *Client) IsSuper() bool { return false } diff --git a/advLayer/ws/ws_test.go b/advLayer/ws/ws_test.go index 7580561..7ec9dd9 100644 --- a/advLayer/ws/ws_test.go +++ b/advLayer/ws/ws_test.go @@ -75,7 +75,7 @@ func TestWs(t *testing.T) { } }() - cli, err := ws.NewClient(listenAddr, wsPath, nil) + cli, err := ws.NewClient(listenAddr, wsPath, nil, false) if err != nil { t.Log(err) t.FailNow() @@ -85,7 +85,7 @@ func TestWs(t *testing.T) { t.Log(err) t.FailNow() } - wsConn, err := cli.Handshake(tcpConn) + wsConn, err := cli.Handshake(tcpConn, nil) if err != nil { t.Log(err) t.FailNow() diff --git a/examples/quic.client.toml b/examples/quic.client.toml index cb8dc48..1ec4513 100644 --- a/examples/quic.client.toml +++ b/examples/quic.client.toml @@ -42,4 +42,4 @@ advancedLayer = "quic" # 实测似乎mac上quic最大的网速就只能够达到 1400mbps左右,配置再大的数也没用 -# extra = { quic_early = true } \ No newline at end of file +# early = true \ No newline at end of file diff --git a/examples/quic.server.toml b/examples/quic.server.toml index ff665d7..6aea659 100644 --- a/examples/quic.server.toml +++ b/examples/quic.server.toml @@ -16,7 +16,7 @@ advancedLayer = "quic" #extra = { congestion_control = "hy", mbps = 3000 } #extra = { maxStreamCountInOneSession = 6 } # maxStreamCountInOneSession默认为4. 该值越大, 对浏览网页的延迟降低越多,但是对下载、测速等情况的负优化越大. 鱼和熊掌不可兼得. 自行调节. 如果调为1, 就相当于 单路单用 -# extra = { quic_early = true } # 开启 quic 0-rtt功能。注意, 两端都要开启,且 v2ray/xray没有这个功能. +# early = true # 开启 quic 0-rtt功能。注意, 两端都要开启,且 v2ray/xray没有这个功能. [[dial]] protocol = "direct" diff --git a/examples/ws.client.toml b/examples/ws.client.toml index e2b8c6b..089bc9b 100644 --- a/examples/ws.client.toml +++ b/examples/ws.client.toml @@ -14,4 +14,4 @@ insecure = true #utls = true # 如果你要用v2ray或者xray做服务端,则要关闭utls,它们不够强大所以它们的websocket无法支持uTls;如果你用verysimple做服务端,则可以打开utls,享受chrome指纹伪装。 advancedLayer = "ws" path = "/ohmygod_verysimple_is_very_simple" #为了防探测这里越长越随机越好 -#extra = { ws_earlydata = true } # 是否开启early data, 注意本作这里要开启的话,就要服务端和客户端 两端都开启。 +# early = true # 是否开启early data, 注意本作这里要开启的话,就要服务端和客户端 两端都开启。 diff --git a/examples/ws.server.toml b/examples/ws.server.toml index 63cef01..f3dd4a1 100644 --- a/examples/ws.server.toml +++ b/examples/ws.server.toml @@ -10,7 +10,7 @@ cert = "cert.pem" key = "cert.key" advancedLayer = "ws" path = "/ohmygod_verysimple_is_very_simple" -#extra = { ws_earlydata = true } +# early = true [[dial]] protocol = "direct" diff --git a/main.go b/main.go index 68c3504..0616634 100644 --- a/main.go +++ b/main.go @@ -14,15 +14,17 @@ import ( "go.uber.org/zap" - "github.com/e1732a364fed/v2ray_simple/advLayer/grpc" - "github.com/e1732a364fed/v2ray_simple/advLayer/quic" - "github.com/e1732a364fed/v2ray_simple/advLayer/ws" + "github.com/e1732a364fed/v2ray_simple/advLayer" "github.com/e1732a364fed/v2ray_simple/httpLayer" "github.com/e1732a364fed/v2ray_simple/netLayer" "github.com/e1732a364fed/v2ray_simple/proxy" "github.com/e1732a364fed/v2ray_simple/tlsLayer" "github.com/e1732a364fed/v2ray_simple/utils" + _ "github.com/e1732a364fed/v2ray_simple/advLayer/grpc" + _ "github.com/e1732a364fed/v2ray_simple/advLayer/quic" + _ "github.com/e1732a364fed/v2ray_simple/advLayer/ws" + _ "github.com/e1732a364fed/v2ray_simple/proxy/dokodemo" _ "github.com/e1732a364fed/v2ray_simple/proxy/http" _ "github.com/e1732a364fed/v2ray_simple/proxy/simplesocks" @@ -46,9 +48,6 @@ var ( Tls_lazy_encrypt bool Tls_lazy_secure bool - - //有时需要测试到单一网站的流量,此时为了避免其它干扰,可声明 一下 该域名,然后程序里会进行过滤 - //uniqueTestDomain string ) func init() { @@ -56,8 +55,6 @@ func init() { flag.BoolVar(&Tls_lazy_encrypt, "lazy", false, "tls lazy encrypt (splice)") flag.BoolVar(&Tls_lazy_secure, "ls", false, "tls lazy secure, use special techs to ensure the tls lazy encrypt data can't be detected. Only valid at client end.") - //flag.StringVar(&uniqueTestDomain, "td", "", "test a single domain, like www.domain.com. Only valid when loglevel=0") - } // ListenSer 函数 是本包 最重要的函数。可以 直接使用 本函数 来手动开启新的 自定义的 转发流程。 @@ -68,20 +65,23 @@ func ListenSer(inServer proxy.Server, defaultOutClientForThis proxy.Client, env var err error + var handleHere bool + var advs advLayer.Server + + if advs = inServer.GetAdvServer(); advs != nil { + handleHere = advs.IsSuper() && advs.IsMux() + } + //quic - if inServer.IsHandleInitialLayers() { + if handleHere { //如果像quic一样自行处理传输层至tls层之间的部分,则我们跳过 handleNewIncomeConnection 函数 // 拿到连接后直接调用 handshakeInserver_and_passToOutClient - handleFunc := inServer.HandleInitialLayersFunc() - if handleFunc == nil { - panic("inServer.IsHandleInitialLayers but inServer.HandleInitialLayersFunc() returns nil") - } + superSer := advs.(advLayer.SuperMuxServer) - //baseConn可以为nil,quic就是如此 - newConnChan, baseConn := handleFunc() + newConnChan, closer := superSer.StartListen() if newConnChan == nil { - utils.Error("StarthandleInitialLayers can't extablish baseConn") + utils.Error("superSer.StartListen can't extablish baseConn") return } @@ -89,17 +89,18 @@ func ListenSer(inServer proxy.Server, defaultOutClientForThis proxy.Client, env for { newConn, ok := <-newConnChan if !ok { - utils.Error("read from SuperProxy not ok") + utils.Error("read from Super AdvLayer not ok") - quic.CloseConn(baseConn) + if closer != nil { + closer.Close() + } return } + //utils.Debug("quic Got New Conn") iics := incomingInserverConnState{ - wrappedConn: newConn, - //baseLocalConn: baseConn, //quic是没有baseLocalConn的,因为基于udp - // 或者说虽然有baseConn,但是并不与子连接一一对应.那个conn更类似于一个listener + wrappedConn: newConn, inServer: inServer, defaultClient: defaultOutClientForThis, } @@ -172,6 +173,43 @@ type incomingInserverConnState struct { RoutingEnv *proxy.RoutingEnv //used in passToOutClient } +// 在调用 passToOutClient前遇到err时调用, 若找出了buf,设置iics,并返回true +func (iics *incomingInserverConnState) extractFirstBufFromErr(err error) bool { + if ce := utils.CanLogWarn("failed in inServer proxy handshake"); ce != nil { + ce.Write( + zap.String("handler", iics.inServer.AddrStr()), + zap.Error(err), + ) + } + + if !iics.inServer.CanFallback() { + iics.wrappedConn.Close() + return false + } + + //通过err找出 并赋值给 iics.theFallbackFirstBuffer + { + + fe, ok := err.(*utils.ErrFirstBuffer) + if !ok { + // 能fallback 但是返回的 err却不是fallback err,证明遇到了更大问题,可能是底层read问题,所以也不用继续fallback了 + iics.wrappedConn.Close() + return false + } + + if firstbuffer := fe.First; firstbuffer == nil { + //不应该,至少能读到1字节的。 + + panic("No FirstBuffer") + + } else { + iics.theFallbackFirstBuffer = firstbuffer + + } + } + return true +} + // handleNewIncomeConnection 会处理 网络层至高级层的数据, // 然后将代理层的处理发往 handshakeInserver_and_passToOutClient 函数。 // @@ -275,11 +313,9 @@ func handleNewIncomeConnection(inServer proxy.Server, defaultClientForThis proxy // 我们直接循环监听然后分别用 新goroutine发向 handshakeInserver_and_passToOutClient - if ce := utils.CanLogDebug("start upgrade grpc"); ce != nil { - ce.Write() - } + utils.Debug("start upgrade grpc") - grpcs := inServer.GetGRPC_Server() //这个grpc server是在配置阶段初始化好的. + grpcs := inServer.GetAdvServer().(advLayer.MuxServer) newConnChan := make(chan net.Conn, 10) grpcs.StartHandle(wrappedConn, newConnChan) @@ -288,7 +324,11 @@ func handleNewIncomeConnection(inServer proxy.Server, defaultClientForThis proxy // 新的子请求被 grpc包 抽象成了 抽象的 conn //遇到chan被关闭的情况后,就会自动关闭底层连接并退出整个函数。 for { + + //utils.Debug("grpc for chan") newGConn, ok := <-newConnChan + //utils.Debug("grpc for chan got") + if !ok { if ce := utils.CanLogWarn("grpc getNewSubConn not ok"); ce != nil { ce.Write() @@ -332,9 +372,9 @@ func handleNewIncomeConnection(inServer proxy.Server, defaultClientForThis proxy return } - wss := inServer.GetWS_Server() + wss := inServer.GetAdvServer() - if rp.Method != "GET" || wss.Thepath != rp.Path { + if rp.Method != "GET" || wss.GetPath() != rp.Path { iics.theRequestPath = rp.Path iics.theFallbackFirstBuffer = rp.WholeRequestBuf @@ -343,7 +383,7 @@ func handleNewIncomeConnection(inServer proxy.Server, defaultClientForThis proxy ce.Write( zap.String("handler", inServer.AddrStr()), zap.String("reason", "path/method not match"), - zap.String("validPath", wss.Thepath), + zap.String("validPath", wss.GetPath()), zap.String("gotMethod", rp.Method), zap.String("gotPath", rp.Path), ) @@ -354,8 +394,12 @@ func handleNewIncomeConnection(inServer proxy.Server, defaultClientForThis proxy } + wsss := wss.(advLayer.SingleServer) + //此时path和method都已经匹配了, 如果还不能通过那就说明后面的header等数据不满足ws的upgrade请求格式, 肯定是非法数据了,也不用再回落 - wsConn, err := wss.Handshake(rp.WholeRequestBuf, wrappedConn) + + wsConn, err := wsss.Handshake(rp.WholeRequestBuf, wrappedConn) + if err != nil { if ce := utils.CanLogErr("InServer ws handshake failed"); ce != nil { @@ -382,6 +426,10 @@ func handleNewIncomeConnection(inServer proxy.Server, defaultClientForThis proxy //被 handshakeInserver_and_passToOutClient 调用 func handshakeInserver(iics *incomingInserverConnState) (wlc net.Conn, udp_wlc netLayer.MsgConn, targetAddr netLayer.Addr, err error) { inServer := iics.inServer + if inServer == nil { + err = utils.ErrInErr{ErrDesc: "handshakeInserver failed, nil inServer", ErrDetail: utils.ErrNilParameter} + return + } wlc, udp_wlc, targetAddr, err = inServer.Handshake(iics.wrappedConn) @@ -464,7 +512,7 @@ func handshakeInserver(iics *incomingInserverConnState) (wlc net.Conn, udp_wlc n } newiics := *iics - if !findoutFirstBuf(err1, &newiics) { + if !newiics.extractFirstBufFromErr(err1) { return } passToOutClient(newiics, true, wlc1, udp_wlc1, targetAddr1) @@ -494,43 +542,6 @@ func handshakeInserver(iics *incomingInserverConnState) (wlc net.Conn, udp_wlc n return } -// 在调用 passToOutClient前遇到err时调用, 若找出了buf,设置iics,并返回true -func findoutFirstBuf(err error, iics *incomingInserverConnState) bool { - if ce := utils.CanLogWarn("failed in inServer proxy handshake"); ce != nil { - ce.Write( - zap.String("handler", iics.inServer.AddrStr()), - zap.Error(err), - ) - } - - if !iics.inServer.CanFallback() { - iics.wrappedConn.Close() - return false - } - - //通过err找出 并赋值给 iics.theFallbackFirstBuffer - { - - fe, ok := err.(*utils.ErrFirstBuffer) - if !ok { - // 能fallback 但是返回的 err却不是fallback err,证明遇到了更大问题,可能是底层read问题,所以也不用继续fallback了 - iics.wrappedConn.Close() - return false - } - - if firstbuffer := fe.First; firstbuffer == nil { - //不应该,至少能读到1字节的。 - - panic("No FirstBuffer") - - } else { - iics.theFallbackFirstBuffer = firstbuffer - - } - } - return true -} - // 本函数 处理inServer的代理层数据,并在试图处理 分流和回落后,将流量导向目标,并开始Copy。 // iics 不使用指针, 因为iics不能公用,因为 在多路复用时 iics.wrappedConn 是会变化的。 // @@ -547,7 +558,7 @@ func handshakeInserver_and_passToOutClient(iics incomingInserverConnState) { return default: - if !findoutFirstBuf(err, &iics) { + if !iics.extractFirstBufFromErr(err) { return } @@ -807,7 +818,7 @@ func passToOutClient(iics incomingInserverConnState, isfallback bool, wlc net.Co //实测 grpc.Conn 被调用了Close 也不会实际关闭连接,而是会卡住,阻塞,直到底层tcp连接被关闭后才会返回 // 但是我们还是 直接避免这种情况 - if inServer != nil && !inServer.IsMux() { + if inServer != nil && !(inServer.GetAdvServer() != nil && inServer.GetAdvServer().IsMux()) { iics.shouldCloseInSerBaseConnWhenFinish = true } @@ -877,23 +888,6 @@ func dialClient(targetAddr netLayer.Addr, // 而其它代理的话, realTargetAddr会被设成实际配置的代理的地址 realTargetAddr = targetAddr - /* - if ce := utils.CanLogDebug("request isn't the appointed domain"); ce != nil { - - - if uniqueTestDomain != "" && uniqueTestDomain != targetAddr.Name { - - ce.Write( - zap.String("request", targetAddr.String()), - zap.String("uniqueTestDomain", uniqueTestDomain), - ) - result = -1 - return - - } - } - */ - if ce := utils.CanLogInfo("Request"); ce != nil { ce.Write( @@ -918,7 +912,7 @@ func dialClient(targetAddr netLayer.Addr, } var clientConn net.Conn - var grpcClientConn grpc.ClientConn + //var grpcClientConn any//grpc.ClientConn var dialedCommonConn any dialHere := !(client.Name() == "direct" && isudp) @@ -930,25 +924,26 @@ func dialClient(targetAddr netLayer.Addr, // Instead, 我们要试图从grpc中取出已经拨号好了的 grpc链接 adv := client.AdvancedLayer() + var notsuper bool if dialHere { - switch adv { - case "grpc": + if adv != "" && client.GetAdvClient().IsMux() { + if client.GetAdvClient().IsSuper() { - grpcClientConn = grpc.GetEstablishedConnFor(&realTargetAddr) + dialedCommonConn, err = client.GetAdvClient().(advLayer.MuxClient).GetCommonConn(nil) + if dialedCommonConn != nil && err == nil { + goto advLayerHandshakeStep + } else { - if grpcClientConn != nil { - //如果有已经建立好的连接,则跳过传输层拨号和tls阶段 - goto advLayerHandshakeStep - } - case "quic": - dialedCommonConn, _ = client.GetQuic_Client().DialCommonConn(nil) - if dialedCommonConn != nil { - goto advLayerHandshakeStep + result = -1 + return + } } else { - - result = -1 - return + notsuper = true + dialedCommonConn, err = client.GetAdvClient().(advLayer.MuxClient).GetCommonConn(nil) + if dialedCommonConn != nil && err == nil { + goto advLayerHandshakeStep + } } } @@ -1038,7 +1033,7 @@ advLayerHandshakeStep: if adv != "" { switch adv { case "quic": - qclient := client.GetQuic_Client() + qclient := client.GetAdvClient().(advLayer.MuxClient) clientConn, err = qclient.DialSubConn(dialedCommonConn) if err != nil { eStr := err.Error() @@ -1052,7 +1047,7 @@ advLayerHandshakeStep: qclient.ProcessWhenFull(dialedCommonConn) //第一条连接已满,再开一条session - dialedCommonConn, _ = qclient.DialCommonConn(nil) + dialedCommonConn, _ = qclient.GetCommonConn(nil) if dialedCommonConn == nil { //再dial还是nil,也许是暂时性的网络错误, 先退出 result = -1 @@ -1081,24 +1076,21 @@ advLayerHandshakeStep: } case "grpc": - if grpcClientConn == nil { - grpcClientConn, err = grpc.ClientHandshake(clientConn, &realTargetAddr) - if err != nil { - if ce := utils.CanLogErr("grpc.ClientHandshake failed"); ce != nil { - ce.Write(zap.Error(err)) - - } - if baseLocalConn != nil { - baseLocalConn.Close() + if notsuper && dialedCommonConn == nil { + dialedCommonConn, _ = client.GetAdvClient().(advLayer.MuxClient).GetCommonConn(clientConn) + if dialedCommonConn == nil { + if ce := utils.CanLogErr("GetCommonConn failed"); ce != nil { + ce.Write( + zap.Error(err), + ) } result = -1 return } - } - clientConn, err = grpc.DialNewSubConn(client.Path(), grpcClientConn, &realTargetAddr, client.IsGrpcClientMultiMode()) + clientConn, err = client.GetAdvClient().(advLayer.MuxClient).DialSubConn(dialedCommonConn) if err != nil { if ce := utils.CanLogErr("grpc.DialNewSubConn failed"); ce != nil { @@ -1116,14 +1108,14 @@ advLayerHandshakeStep: } case "ws": - wsClient := client.GetWS_Client() + wsClient := client.GetAdvClient() var ed []byte - if wsClient.UseEarlyData && wlc != nil { + if wsClient.IsEarly() && wlc != nil { //若配置了 MaxEarlyDataLen,则我们先读一段; edBuf := utils.GetPacket() - edBuf = edBuf[:ws.MaxEarlyDataLen] + edBuf = edBuf[:advLayer.MaxEarlyDataLen] n, e := wlc.Read(edBuf) if e != nil { if ce := utils.CanLogErr("failed to read ws early data"); ce != nil { @@ -1148,7 +1140,9 @@ advLayerHandshakeStep: var wc net.Conn - wc, err = wsClient.Handshake(clientConn, ed) + wcs := wsClient.(advLayer.SingleClient) + + wc, err = wcs.Handshake(clientConn, ed) if err != nil { if ce := utils.CanLogErr("failed in handshake ws"); ce != nil { diff --git a/netLayer/dial.go b/netLayer/dial.go index 6e4020e..6250cb2 100644 --- a/netLayer/dial.go +++ b/netLayer/dial.go @@ -71,7 +71,7 @@ tcp: } defaultPart: - resultConn, err = net.Dial(addr.Network, addr.String()) + resultConn, err = net.DialTimeout(addr.Network, addr.String(), time.Second*15) dialedPart: if istls && err == nil { diff --git a/proxy/config.go b/proxy/config.go index 7472abe..06bea7f 100644 --- a/proxy/config.go +++ b/proxy/config.go @@ -30,6 +30,8 @@ type CommonConf struct { AdvancedLayer string `toml:"advancedLayer"` //高级层; 可不填,或者为ws,或者为grpc + IsEarly bool `toml:"early"` //是否启用 0-rtt + Path string `toml:"path"` //ws 的path 或 grpc的 serviceName。为了简便我们在同一位置给出. Extra map[string]any `toml:"extra"` //用于包含任意其它数据.虽然本包自己定义的协议肯定都是已知的,但是如果其他人使用了本包的话,那就有可能添加一些 新协议 特定的数据. diff --git a/proxy/creator.go b/proxy/creator.go index 49bbbc1..7a620da 100644 --- a/proxy/creator.go +++ b/proxy/creator.go @@ -295,11 +295,11 @@ func configCommonByURL(ser ProxyCommon, u *url.URL) { } } -//setAdvancedLayer -func configCommon(ser ProxyCommon, cc *CommonConf) { - ser.getCommon().setAdvancedLayer(cc.AdvancedLayer) +//setAdvancedLayer, setPath +func configCommon(this ProxyCommon, cc *CommonConf) { + this.getCommon().setAdvancedLayer(cc.AdvancedLayer) if cc.Path != "" { - ser.getCommon().setPath(cc.Path) + this.getCommon().setPath(cc.Path) } } @@ -326,18 +326,7 @@ func configCommonForClient(cli ProxyCommon, dc *DialConf) error { configCommon(cli, &dc.CommonConf) - switch dc.AdvancedLayer { - case "ws": - return cli.initWS_client() - case "grpc": - if dc.Extra != nil { - if thing := dc.Extra["grpc_multi"]; thing != nil { - if use, ok := thing.(bool); ok && use == true { - clic.grpc_multi = true - } - } - } - } + clic.InitAdvLayer() return nil } @@ -361,25 +350,7 @@ func configCommonForServer(ser ProxyCommon, lc *ListenConf) error { serc.setHeader(lc.HttpHeader) } - switch lc.AdvancedLayer { - case "ws": - err := ser.initWS_server() - if err != nil { - return err - } - - case "grpc": - err := ser.initGRPC_server() - if err != nil { - return err - } - - //case "quic": - - //因为quic接管了tls层, 而我们的configCommonForServer是在tls配置之前被调用的 - // 所以不能在这里配置quic。本作直接在 prepareTLS_forServer 函数里配置 quic的所有配置 - - } + serc.InitAdvLayer() fallbackThing := lc.Fallback diff --git a/proxy/proxy.go b/proxy/proxy.go index f9b4066..6881b25 100644 --- a/proxy/proxy.go +++ b/proxy/proxy.go @@ -1,15 +1,13 @@ package proxy import ( - "errors" + "crypto/tls" "io" "net" "strings" "time" - "github.com/e1732a364fed/v2ray_simple/advLayer/grpc" - "github.com/e1732a364fed/v2ray_simple/advLayer/quic" - "github.com/e1732a364fed/v2ray_simple/advLayer/ws" + "github.com/e1732a364fed/v2ray_simple/advLayer" "github.com/e1732a364fed/v2ray_simple/httpLayer" "github.com/e1732a364fed/v2ray_simple/netLayer" "github.com/e1732a364fed/v2ray_simple/tlsLayer" @@ -151,14 +149,6 @@ type ProxyCommon interface { CantRoute() bool //for inServer GetTag() string - //如果 IsHandleInitialLayers 方法返回true, 则监听/拨号从传输层一直到高级层的过程直接由inServer/outClient自己处理, 而我们主过程直接处理它 处理完毕的剩下的 代理层。 - // - // quic就属于这种接管底层协议的“超级协议”, 可称之为 SuperProxy。 - IsHandleInitialLayers() bool - - // 在IsHandleInitialLayers时可用, 用于 inServer - HandleInitialLayersFunc() func() (newConnChan chan net.Conn, baseConn any) - /////////////////// TLS层 /////////////////// SetUseTLS() @@ -182,21 +172,10 @@ type ProxyCommon interface { AdvancedLayer() string //如果使用了ws或者grpc,这个要返回 ws 或 grpc - GetWS_Client() *ws.Client //for outClient - GetWS_Server() *ws.Server //for inServer + GetAdvClient() advLayer.Client + GetAdvServer() advLayer.Server - initWS_client() error //for outClient - initWS_server() error //for inServer - - GetGRPC_Server() *grpc.Server - - IsGrpcClientMultiMode() bool - - initGRPC_server() error - - IsMux() bool //如果用了grpc或者quic, 则此方法返回true。这个是用于判断外层mux的。 - - GetQuic_Client() *quic.Client //for outClient + //IsGrpcClientMultiMode() bool /////////////////// 内层mux层 /////////////////// @@ -234,17 +213,13 @@ type ProxyCommonStruct struct { AdvancedL string - ws_c *ws.Client - ws_s *ws.Server + advC advLayer.Client + advS advLayer.Server + + //grpc_multi bool - grpc_s *grpc.Server - grpc_multi bool FallbackAddr *netLayer.Addr - quic_c *quic.Client - - listenCommonConnFunc func() (newConnChan chan net.Conn, baseConn any) - innermux *smux.Session //用于存储 client的已拨号的mux连接 } @@ -253,10 +228,6 @@ func (pcs *ProxyCommonStruct) getCommon() *ProxyCommonStruct { return pcs } -func (pcs *ProxyCommonStruct) setListenCommonConnFunc(f func() (newConnChan chan net.Conn, baseConn any)) { - pcs.listenCommonConnFunc = f -} - func (pcs *ProxyCommonStruct) Network() string { return pcs.network } @@ -403,10 +374,6 @@ func (s *ProxyCommonStruct) CanFallback() bool { return false } -func (s *ProxyCommonStruct) IsHandleInitialLayers() bool { - return s.AdvancedL == "quic" -} - func (pcs *ProxyCommonStruct) setTLS_Server(s *tlsLayer.Server) { pcs.tls_s = s } @@ -431,9 +398,10 @@ func (s *ProxyCommonStruct) SetAddrStr(a string) { func (s *ProxyCommonStruct) IsUseTLS() bool { return s.TLS } -func (s *ProxyCommonStruct) IsGrpcClientMultiMode() bool { - return s.grpc_multi -} + +//func (s *ProxyCommonStruct) IsGrpcClientMultiMode() bool { +// return s.grpc_multi +//} func (s *ProxyCommonStruct) IsMux() bool { switch s.AdvancedL { @@ -443,10 +411,6 @@ func (s *ProxyCommonStruct) IsMux() bool { return false } -func (s *ProxyCommonStruct) HandleInitialLayersFunc() func() (newConnChan chan net.Conn, baseConn any) { - return s.listenCommonConnFunc -} - func (s *ProxyCommonStruct) SetUseTLS() { s.TLS = true } @@ -457,112 +421,106 @@ func (s *ProxyCommonStruct) setListenConf(lc *ListenConf) { func (s *ProxyCommonStruct) setDialConf(dc *DialConf) { s.dialConf = dc } - -func (s *ProxyCommonStruct) GetQuic_Client() *quic.Client { - return s.quic_c +func (s *ProxyCommonStruct) GetAdvClient() advLayer.Client { + return s.advC +} +func (s *ProxyCommonStruct) GetAdvServer() advLayer.Server { + return s.advS } -func (s *ProxyCommonStruct) setQuic_Client(c *quic.Client) { - s.quic_c = c -} - -func (s *ProxyCommonStruct) GetWS_Client() *ws.Client { - return s.ws_c -} -func (s *ProxyCommonStruct) GetWS_Server() *ws.Server { - return s.ws_s -} - -func (s *ProxyCommonStruct) GetGRPC_Server() *grpc.Server { - return s.grpc_s -} - -func (s *ProxyCommonStruct) initWS_client() error { - if s.dialConf == nil { - return errors.New("initWS_client failed when no dialConf assigned") - } - path := s.dialConf.Path - if path == "" { // 至少Path需要为 "/" - path = "/" +func (s *ProxyCommonStruct) InitAdvLayer() { + if s.AdvancedL == "" { + return } - var useEarlyData bool - if s.dialConf.Extra != nil { - if thing := s.dialConf.Extra["ws_earlydata"]; thing != nil { - if use, ok := thing.(bool); ok && use { - useEarlyData = true + creator := advLayer.ProtocolsMap[s.AdvancedL] + if creator == nil { + utils.Error("InitAdvLayer failed, 2, " + s.AdvancedL) + + return + } + + ad, err := netLayer.NewAddr(s.Addr) + if err != nil { + utils.Error("InitAdvLayer failed, 3") + + return + } + + if dc := s.dialConf; dc != nil { + + var Headers map[string][]string + if dc.HttpHeader != nil { + if dc.HttpHeader.Request != nil { + Headers = dc.HttpHeader.Request.Headers } } - } - var c *ws.Client - var e error + advClient, err := creator.NewClientFromConf(&advLayer.Conf{ + Path: dc.Path, + Host: dc.Host, + IsEarly: dc.IsEarly, + Addr: ad, + Headers: Headers, + TlsConf: &tls.Config{ + InsecureSkipVerify: dc.Insecure, + NextProtos: dc.Alpn, + ServerName: dc.Host, + }, + Extra: dc.Extra, + }) + if err != nil { + utils.Error("InitAdvLayer failed, 4") - if s.header != nil { - c, e = ws.NewClient(s.dialConf.GetAddrStr(), path, s.header.Request.Headers) - - } else { - c, e = ws.NewClient(s.dialConf.GetAddrStr(), path, nil) + return + } + s.advC = advClient } - if e != nil { - return utils.ErrInErr{ErrDesc: "initWS_client failed", ErrDetail: e} - } - c.UseEarlyData = useEarlyData - s.ws_c = c + if lc := s.listenConf; lc != nil { - return nil -} - -func (s *ProxyCommonStruct) initWS_server() error { - if s.listenConf == nil { - - return errors.New("initWS_server failed when no listenConf assigned") - - } - path := s.listenConf.Path - if path == "" { // 至少Path需要为 "/" - path = "/" - } - - var useEarlyData bool - if s.listenConf.Extra != nil { - if thing := s.listenConf.Extra["ws_earlydata"]; thing != nil { - if use, ok := thing.(bool); ok && use { - useEarlyData = true + var Headers map[string][]string + if lc.HttpHeader != nil { + if lc.HttpHeader.Request != nil { + Headers = lc.HttpHeader.Response.Headers } } + + var certArray []tls.Certificate + + if lc.TLSCert != "" && lc.TLSKey != "" { + certArray, err = tlsLayer.GetCertArrayFromFile(lc.TLSCert, lc.TLSKey) + + if err != nil { + + if ce := utils.CanLogErr("can't create tls cert"); ce != nil { + ce.Write(zap.String("cert", lc.TLSCert), zap.String("key", lc.TLSKey), zap.Error(err)) + } + + return + } + + } + + advSer, err := creator.NewServerFromConf(&advLayer.Conf{ + Path: lc.Path, + Host: lc.Host, + IsEarly: lc.IsEarly, + Addr: ad, + Headers: Headers, + TlsConf: &tls.Config{ + InsecureSkipVerify: lc.Insecure, + NextProtos: lc.Alpn, + ServerName: lc.Host, + Certificates: certArray, + }, + Extra: lc.Extra, + }) + if err != nil { + return + } + + s.advS = advSer } - var wss *ws.Server - if s.header != nil { - wss = ws.NewServer(path, s.header.Response.Headers) - - } else { - wss = ws.NewServer(path, nil) - - } - wss.UseEarlyData = useEarlyData - - s.ws_s = wss - - return nil -} - -func (s *ProxyCommonStruct) initGRPC_server() error { - if s.listenConf == nil { - - return errors.New("initGRPC_server failed when no listenConf assigned") - - } - - serviceName := s.listenConf.Path - if serviceName == "" { //不能为空 - - return errors.New("initGRPC_server failed, path must be specified") - - } - - s.grpc_s = grpc.NewServer(serviceName) - return nil } diff --git a/proxy/tlsConfig.go b/proxy/tlsConfig.go index b0f1977..bd8aa26 100644 --- a/proxy/tlsConfig.go +++ b/proxy/tlsConfig.go @@ -1,21 +1,14 @@ package proxy import ( - "crypto/tls" - "log" "net" "net/url" - "github.com/e1732a364fed/v2ray_simple/advLayer/quic" "github.com/e1732a364fed/v2ray_simple/httpLayer" - "github.com/e1732a364fed/v2ray_simple/netLayer" "github.com/e1732a364fed/v2ray_simple/tlsLayer" - "github.com/e1732a364fed/v2ray_simple/utils" - "go.uber.org/zap" ) //use dc.Host, dc.Insecure, dc.Utls, dc.Alpn. -// 如果用到了quic,还会直接配置quic的client的所有设置. func prepareTLS_forClient(com ProxyCommon, dc *DialConf) error { alpnList := dc.Alpn @@ -26,59 +19,8 @@ func prepareTLS_forClient(com ProxyCommon, dc *DialConf) error { switch com.AdvancedLayer() { case "quic": - na, e := netLayer.NewAddr(com.AddrStr()) - if e != nil { - if ce := utils.CanLogErr("prepareTLS_forClient,quic,netLayer.NewAddr failed"); ce != nil { - ce.Write(zap.Error(e)) - } - return e - } - clic.setNetwork("udp") - var useHysteria, hysteria_manual, early bool - var maxbyteCount int - - if dc.Extra != nil { - if thing := dc.Extra["congestion_control"]; thing != nil { - if use, ok := thing.(string); ok && use == "hy" { - useHysteria = true - - if thing := dc.Extra["mbps"]; thing != nil { - if mbps, ok := thing.(int64); ok && mbps > 1 { - maxbyteCount = int(mbps) * 1024 * 1024 / 8 - - log.Println("Using Hysteria Congestion Control, max upload mbps: ", mbps) - } - } else { - log.Println("Using Hysteria Congestion Control, max upload mbps: ", quic.Default_hysteriaMaxByteCount, "mbps") - } - - if thing := dc.Extra["hy_manual"]; thing != nil { - if ismanual, ok := thing.(bool); ok { - hysteria_manual = ismanual - if ismanual { - log.Println("Using Hysteria Manual Control Mode") - } - } - } - } - } - - if thing := dc.Extra["quic_early"]; thing != nil { - if use, ok := thing.(bool); ok && use { - early = true - } - } - - } - - if len(alpnList) == 0 { - alpnList = quic.AlpnList - } - - clic.setQuic_Client(quic.NewClient(&na, alpnList, dc.Host, dc.Insecure, useHysteria, maxbyteCount, hysteria_manual, early)) - return nil //quic直接接管了tls,所以不执行下面步骤 - + return nil case "grpc": has_h2 := false for _, a := range alpnList { @@ -96,7 +38,6 @@ func prepareTLS_forClient(com ProxyCommon, dc *DialConf) error { } //use lc.Host, lc.TLSCert, lc.TLSKey, lc.Insecure, lc.Alpn. -// 如果用到了quic,还会直接配置quic的server的所有设置. func prepareTLS_forServer(com ProxyCommon, lc *ListenConf) error { // 这里直接不检查 字符串就直接传给 tlsLayer.NewServer // 所以要求 cert和 key 不在程序本身目录 的话,就要给出完整路径 @@ -111,85 +52,8 @@ func prepareTLS_forServer(com ProxyCommon, lc *ListenConf) error { case "quic": serc.setNetwork("udp") + return nil - if len(alpnList) == 0 { - alpnList = quic.AlpnList - } - - var useHysteria, hysteria_manual, early bool - var maxbyteCount int - var maxStreamCountInOneSession int64 - - if lc.Extra != nil { - - if thing := lc.Extra["quic_early"]; thing != nil { - if use, ok := thing.(bool); ok && use { - early = true - } - } - - if thing := lc.Extra["maxStreamCountInOneSession"]; thing != nil { - if count, ok := thing.(int64); ok && count > 0 { - log.Println("maxStreamCountInOneSession,", count) - maxStreamCountInOneSession = count - - } - - } - - if thing := lc.Extra["congestion_control"]; thing != nil { - if use, ok := thing.(string); ok && use == "hy" { - useHysteria = true - - if thing := lc.Extra["mbps"]; thing != nil { - if mbps, ok := thing.(int64); ok && mbps > 1 { - maxbyteCount = int(mbps) * 1024 * 1024 / 8 - - log.Println("Using Hysteria Congestion Control, max upload mbps: ", mbps) - - } - } else { - - log.Println("Using Hysteria Congestion Control, max upload mbps:", quic.Default_hysteriaMaxByteCount, "mbps") - - } - - if thing := lc.Extra["hy_manual"]; thing != nil { - if ismanual, ok := thing.(bool); ok { - hysteria_manual = ismanual - if ismanual { - log.Println("Using Hysteria Manual Control Mode") - } - } - } - } - } - - } - - serc.setListenCommonConnFunc(func() (newConnChan chan net.Conn, baseConn any) { - - certArray, err := tlsLayer.GetCertArrayFromFile(lc.TLSCert, lc.TLSKey) - - if err != nil { - - if ce := utils.CanLogErr("can't create tls cert"); ce != nil { - ce.Write(zap.String("cert", lc.TLSCert), zap.String("key", lc.TLSKey), zap.Error(err)) - } - - return nil, nil - } - - return quic.ListenInitialLayers(com.AddrStr(), tls.Config{ - InsecureSkipVerify: lc.Insecure, - ServerName: lc.Host, - Certificates: certArray, - NextProtos: alpnList, - }, useHysteria, maxbyteCount, hysteria_manual, early, maxStreamCountInOneSession) - - }) - - return nil //quic直接接管了tls,所以不执行下面步骤 case "grpc": has_h2 := false for _, a := range alpnList {