mirror of
https://github.com/MetaCubeX/Clash.Meta.git
synced 2025-04-07 07:03:33 +03:00
fix: disallow dialFunc be called after grpc transport has be closed
This commit is contained in:
parent
efa224373f
commit
24a9ff6d03
3 changed files with 26 additions and 7 deletions
|
@ -46,7 +46,7 @@ type Conn struct {
|
|||
|
||||
reader io.ReadCloser
|
||||
once sync.Once
|
||||
close atomic.Bool
|
||||
closed atomic.Bool
|
||||
err error
|
||||
remain int
|
||||
br *bufio.Reader
|
||||
|
@ -71,7 +71,7 @@ func (g *Conn) initReader() {
|
|||
}
|
||||
g.netAddr = addr
|
||||
|
||||
if !g.close.Load() {
|
||||
if !g.closed.Load() {
|
||||
g.reader = reader
|
||||
g.br = bufio.NewReader(reader)
|
||||
} else {
|
||||
|
@ -184,7 +184,7 @@ func (g *Conn) FrontHeadroom() int {
|
|||
}
|
||||
|
||||
func (g *Conn) Close() error {
|
||||
g.close.Store(true)
|
||||
g.closed.Store(true)
|
||||
var errorArr []error
|
||||
|
||||
if reader := g.reader; reader != nil {
|
||||
|
@ -224,7 +224,11 @@ func (g *Conn) SetDeadline(t time.Time) error {
|
|||
}
|
||||
|
||||
func NewHTTP2Client(dialFn DialFn, tlsConfig *tls.Config, Fingerprint string, realityConfig *tlsC.RealityConfig) *TransportWrap {
|
||||
closed := &atomic.Bool{}
|
||||
dialFunc := func(ctx context.Context, network, addr string, cfg *tls.Config) (net.Conn, error) {
|
||||
if closed.Load() {
|
||||
return nil, errors.New("transport closed")
|
||||
}
|
||||
pconn, err := dialFn(ctx, network, addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -289,6 +293,7 @@ func NewHTTP2Client(dialFn DialFn, tlsConfig *tls.Config, Fingerprint string, re
|
|||
}
|
||||
wrap := &TransportWrap{
|
||||
Transport: transport,
|
||||
closed: closed,
|
||||
}
|
||||
return wrap
|
||||
}
|
||||
|
|
|
@ -1,12 +1,16 @@
|
|||
package gun
|
||||
|
||||
import (
|
||||
"golang.org/x/net/http2"
|
||||
"net"
|
||||
|
||||
"github.com/metacubex/mihomo/common/atomic"
|
||||
|
||||
"golang.org/x/net/http2"
|
||||
)
|
||||
|
||||
type TransportWrap struct {
|
||||
*http2.Transport
|
||||
closed *atomic.Bool
|
||||
}
|
||||
|
||||
type netAddr struct {
|
||||
|
|
|
@ -11,9 +11,13 @@ import (
|
|||
)
|
||||
|
||||
type clientConnPool struct {
|
||||
t *http2.Transport
|
||||
mu sync.Mutex
|
||||
conns map[string][]*http2.ClientConn // key is host:port
|
||||
t *http2.Transport
|
||||
|
||||
mu sync.Mutex
|
||||
conns map[string][]*http2.ClientConn // key is host:port
|
||||
dialing map[string]unsafe.Pointer // currently in-flight dials
|
||||
keys map[*http2.ClientConn][]string
|
||||
addConnCalls map[string]unsafe.Pointer // in-flight addConnIfNeeded calls
|
||||
}
|
||||
|
||||
type clientConn struct {
|
||||
|
@ -42,6 +46,9 @@ func closeClientConn(cc *http2.ClientConn) { // like forceCloseConn() in http2.C
|
|||
}
|
||||
|
||||
func (tw *TransportWrap) Close() error {
|
||||
if tw.closed.Swap(true) {
|
||||
return nil // already closed
|
||||
}
|
||||
connPool := transportConnPool(tw.Transport)
|
||||
p := (*clientConnPool)((*efaceWords)(unsafe.Pointer(&connPool)).data)
|
||||
p.mu.Lock()
|
||||
|
@ -51,6 +58,9 @@ func (tw *TransportWrap) Close() error {
|
|||
closeClientConn(cc)
|
||||
}
|
||||
}
|
||||
// cleanup
|
||||
p.conns = make(map[string][]*http2.ClientConn)
|
||||
p.keys = make(map[*http2.ClientConn][]string)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue