mirror of
https://gitclone.com/github.com/MetaCubeX/Clash.Meta
synced 2025-05-12 21:18:03 +08:00
fix: disallow dialFunc be called after grpc transport has be closed
This commit is contained in:
parent
efa224373f
commit
24a9ff6d03
@ -46,7 +46,7 @@ type Conn struct {
|
|||||||
|
|
||||||
reader io.ReadCloser
|
reader io.ReadCloser
|
||||||
once sync.Once
|
once sync.Once
|
||||||
close atomic.Bool
|
closed atomic.Bool
|
||||||
err error
|
err error
|
||||||
remain int
|
remain int
|
||||||
br *bufio.Reader
|
br *bufio.Reader
|
||||||
@ -71,7 +71,7 @@ func (g *Conn) initReader() {
|
|||||||
}
|
}
|
||||||
g.netAddr = addr
|
g.netAddr = addr
|
||||||
|
|
||||||
if !g.close.Load() {
|
if !g.closed.Load() {
|
||||||
g.reader = reader
|
g.reader = reader
|
||||||
g.br = bufio.NewReader(reader)
|
g.br = bufio.NewReader(reader)
|
||||||
} else {
|
} else {
|
||||||
@ -184,7 +184,7 @@ func (g *Conn) FrontHeadroom() int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (g *Conn) Close() error {
|
func (g *Conn) Close() error {
|
||||||
g.close.Store(true)
|
g.closed.Store(true)
|
||||||
var errorArr []error
|
var errorArr []error
|
||||||
|
|
||||||
if reader := g.reader; reader != nil {
|
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 {
|
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) {
|
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)
|
pconn, err := dialFn(ctx, network, addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -289,6 +293,7 @@ func NewHTTP2Client(dialFn DialFn, tlsConfig *tls.Config, Fingerprint string, re
|
|||||||
}
|
}
|
||||||
wrap := &TransportWrap{
|
wrap := &TransportWrap{
|
||||||
Transport: transport,
|
Transport: transport,
|
||||||
|
closed: closed,
|
||||||
}
|
}
|
||||||
return wrap
|
return wrap
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,16 @@
|
|||||||
package gun
|
package gun
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"golang.org/x/net/http2"
|
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
|
"github.com/metacubex/mihomo/common/atomic"
|
||||||
|
|
||||||
|
"golang.org/x/net/http2"
|
||||||
)
|
)
|
||||||
|
|
||||||
type TransportWrap struct {
|
type TransportWrap struct {
|
||||||
*http2.Transport
|
*http2.Transport
|
||||||
|
closed *atomic.Bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type netAddr struct {
|
type netAddr struct {
|
||||||
|
@ -11,9 +11,13 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type clientConnPool struct {
|
type clientConnPool struct {
|
||||||
t *http2.Transport
|
t *http2.Transport
|
||||||
mu sync.Mutex
|
|
||||||
conns map[string][]*http2.ClientConn // key is host:port
|
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 {
|
type clientConn struct {
|
||||||
@ -42,6 +46,9 @@ func closeClientConn(cc *http2.ClientConn) { // like forceCloseConn() in http2.C
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (tw *TransportWrap) Close() error {
|
func (tw *TransportWrap) Close() error {
|
||||||
|
if tw.closed.Swap(true) {
|
||||||
|
return nil // already closed
|
||||||
|
}
|
||||||
connPool := transportConnPool(tw.Transport)
|
connPool := transportConnPool(tw.Transport)
|
||||||
p := (*clientConnPool)((*efaceWords)(unsafe.Pointer(&connPool)).data)
|
p := (*clientConnPool)((*efaceWords)(unsafe.Pointer(&connPool)).data)
|
||||||
p.mu.Lock()
|
p.mu.Lock()
|
||||||
@ -51,6 +58,9 @@ func (tw *TransportWrap) Close() error {
|
|||||||
closeClientConn(cc)
|
closeClientConn(cc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// cleanup
|
||||||
|
p.conns = make(map[string][]*http2.ClientConn)
|
||||||
|
p.keys = make(map[*http2.ClientConn][]string)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user