mirror of
https://github.com/MetaCubeX/mihomo.git
synced 2025-12-19 08:20:05 +08:00
chore: simplify tuic client
This commit is contained in:
parent
ac90543548
commit
bc719eb96d
@ -70,12 +70,7 @@ type TuicOption struct {
|
||||
|
||||
// DialContext implements C.ProxyAdapter
|
||||
func (t *Tuic) DialContext(ctx context.Context, metadata *C.Metadata) (C.Conn, error) {
|
||||
return t.DialContextWithDialer(ctx, dialer.NewDialer(t.DialOptions()...), metadata)
|
||||
}
|
||||
|
||||
// DialContextWithDialer implements C.ProxyAdapter
|
||||
func (t *Tuic) DialContextWithDialer(ctx context.Context, dialer C.Dialer, metadata *C.Metadata) (C.Conn, error) {
|
||||
conn, err := t.client.DialContextWithDialer(ctx, metadata, dialer, t.dialWithDialer)
|
||||
conn, err := t.client.DialContext(ctx, metadata)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -84,11 +79,6 @@ func (t *Tuic) DialContextWithDialer(ctx context.Context, dialer C.Dialer, metad
|
||||
|
||||
// ListenPacketContext implements C.ProxyAdapter
|
||||
func (t *Tuic) ListenPacketContext(ctx context.Context, metadata *C.Metadata) (_ C.PacketConn, err error) {
|
||||
return t.ListenPacketWithDialer(ctx, dialer.NewDialer(t.DialOptions()...), metadata)
|
||||
}
|
||||
|
||||
// ListenPacketWithDialer implements C.ProxyAdapter
|
||||
func (t *Tuic) ListenPacketWithDialer(ctx context.Context, dialer C.Dialer, metadata *C.Metadata) (_ C.PacketConn, err error) {
|
||||
if err = t.ResolveUDP(ctx, metadata); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -98,7 +88,7 @@ func (t *Tuic) ListenPacketWithDialer(ctx context.Context, dialer C.Dialer, meta
|
||||
uotMetadata := *metadata
|
||||
uotMetadata.Host = uotDestination.Fqdn
|
||||
uotMetadata.DstPort = uotDestination.Port
|
||||
c, err := t.DialContextWithDialer(ctx, dialer, &uotMetadata)
|
||||
c, err := t.DialContext(ctx, &uotMetadata)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -112,21 +102,17 @@ func (t *Tuic) ListenPacketWithDialer(ctx context.Context, dialer C.Dialer, meta
|
||||
return newPacketConn(uot.NewLazyConn(c, uot.Request{Destination: destination}), t), nil
|
||||
}
|
||||
}
|
||||
pc, err := t.client.ListenPacketWithDialer(ctx, metadata, dialer, t.dialWithDialer)
|
||||
pc, err := t.client.ListenPacket(ctx, metadata)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return newPacketConn(pc, t), nil
|
||||
}
|
||||
|
||||
// SupportWithDialer implements C.ProxyAdapter
|
||||
func (t *Tuic) SupportWithDialer() C.NetWork {
|
||||
return C.ALLNet
|
||||
}
|
||||
|
||||
func (t *Tuic) dialWithDialer(ctx context.Context, dialer C.Dialer) (transport *quic.Transport, addr net.Addr, err error) {
|
||||
func (t *Tuic) dial(ctx context.Context) (transport *quic.Transport, addr net.Addr, err error) {
|
||||
var cDialer C.Dialer = dialer.NewDialer(t.DialOptions()...)
|
||||
if len(t.option.DialerProxy) > 0 {
|
||||
dialer, err = proxydialer.NewByName(t.option.DialerProxy, dialer)
|
||||
cDialer, err = proxydialer.NewByName(t.option.DialerProxy, cDialer)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@ -141,7 +127,7 @@ func (t *Tuic) dialWithDialer(ctx context.Context, dialer C.Dialer) (transport *
|
||||
}
|
||||
addr = udpAddr
|
||||
var pc net.PacketConn
|
||||
pc, err = dialer.ListenPacket(ctx, "udp", "", udpAddr.AddrPort())
|
||||
pc, err = cDialer.ListenPacket(ctx, "udp", "", udpAddr.AddrPort())
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@ -313,7 +299,7 @@ func NewTuic(option TuicOption) (*Tuic, error) {
|
||||
CWND: option.CWND,
|
||||
}
|
||||
|
||||
t.client = tuic.NewPoolClientV4(clientOption)
|
||||
t.client = tuic.NewPoolClientV4(clientOption, t.dial)
|
||||
} else {
|
||||
maxUdpRelayPacketSize := option.MaxUdpRelayPacketSize
|
||||
if maxUdpRelayPacketSize > tuic.MaxFragSizeV5 {
|
||||
@ -332,7 +318,7 @@ func NewTuic(option TuicOption) (*Tuic, error) {
|
||||
CWND: option.CWND,
|
||||
}
|
||||
|
||||
t.client = tuic.NewPoolClientV5(clientOption)
|
||||
t.client = tuic.NewPoolClientV5(clientOption, t.dial)
|
||||
}
|
||||
|
||||
return t, nil
|
||||
|
||||
@ -18,13 +18,12 @@ var (
|
||||
TooManyOpenStreams = errors.New("tuic: too many open streams")
|
||||
)
|
||||
|
||||
type DialFunc func(ctx context.Context, dialer C.Dialer) (transport *quic.Transport, addr net.Addr, err error)
|
||||
type DialFunc func(ctx context.Context) (transport *quic.Transport, addr net.Addr, err error)
|
||||
|
||||
type Client interface {
|
||||
DialContextWithDialer(ctx context.Context, metadata *C.Metadata, dialer C.Dialer, dialFn DialFunc) (net.Conn, error)
|
||||
ListenPacketWithDialer(ctx context.Context, metadata *C.Metadata, dialer C.Dialer, dialFn DialFunc) (net.PacketConn, error)
|
||||
DialContext(ctx context.Context, metadata *C.Metadata) (net.Conn, error)
|
||||
ListenPacket(ctx context.Context, metadata *C.Metadata) (net.PacketConn, error)
|
||||
OpenStreams() int64
|
||||
DialerRef() C.Dialer
|
||||
LastVisited() time.Time
|
||||
SetLastVisited(last time.Time)
|
||||
Close()
|
||||
|
||||
@ -6,6 +6,7 @@ import (
|
||||
"net"
|
||||
"runtime"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
N "github.com/metacubex/mihomo/common/net"
|
||||
@ -17,30 +18,21 @@ import (
|
||||
list "github.com/bahlo/generic-list-go"
|
||||
)
|
||||
|
||||
type dialResult struct {
|
||||
transport *quic.Transport
|
||||
addr net.Addr
|
||||
err error
|
||||
}
|
||||
|
||||
type PoolClient struct {
|
||||
newClientOptionV4 *ClientOptionV4
|
||||
newClientOptionV5 *ClientOptionV5
|
||||
dialResultMap map[C.Dialer]dialResult
|
||||
dialResultMutex *sync.Mutex
|
||||
tcpClients *list.List[Client]
|
||||
tcpClientsMutex *sync.Mutex
|
||||
udpClients *list.List[Client]
|
||||
udpClientsMutex *sync.Mutex
|
||||
|
||||
dialHelper *poolDialHelper
|
||||
tcpClients list.List[Client]
|
||||
tcpClientsMutex sync.Mutex
|
||||
udpClients list.List[Client]
|
||||
udpClientsMutex sync.Mutex
|
||||
}
|
||||
|
||||
func (t *PoolClient) DialContextWithDialer(ctx context.Context, metadata *C.Metadata, dialer C.Dialer, dialFn DialFunc) (net.Conn, error) {
|
||||
newDialFn := func(ctx context.Context, dialer C.Dialer) (transport *quic.Transport, addr net.Addr, err error) {
|
||||
return t.dial(ctx, dialer, dialFn)
|
||||
}
|
||||
conn, err := t.getClient(false, dialer).DialContextWithDialer(ctx, metadata, dialer, newDialFn)
|
||||
func (t *PoolClient) DialContext(ctx context.Context, metadata *C.Metadata) (net.Conn, error) {
|
||||
conn, err := t.getClient(false).DialContext(ctx, metadata)
|
||||
if errors.Is(err, TooManyOpenStreams) {
|
||||
conn, err = t.newClient(false, dialer).DialContextWithDialer(ctx, metadata, dialer, newDialFn)
|
||||
conn, err = t.newClient(false).DialContext(ctx, metadata)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -48,13 +40,10 @@ func (t *PoolClient) DialContextWithDialer(ctx context.Context, metadata *C.Meta
|
||||
return N.NewRefConn(conn, t), err
|
||||
}
|
||||
|
||||
func (t *PoolClient) ListenPacketWithDialer(ctx context.Context, metadata *C.Metadata, dialer C.Dialer, dialFn DialFunc) (net.PacketConn, error) {
|
||||
newDialFn := func(ctx context.Context, dialer C.Dialer) (transport *quic.Transport, addr net.Addr, err error) {
|
||||
return t.dial(ctx, dialer, dialFn)
|
||||
}
|
||||
pc, err := t.getClient(true, dialer).ListenPacketWithDialer(ctx, metadata, dialer, newDialFn)
|
||||
func (t *PoolClient) ListenPacket(ctx context.Context, metadata *C.Metadata) (net.PacketConn, error) {
|
||||
pc, err := t.getClient(true).ListenPacket(ctx, metadata)
|
||||
if errors.Is(err, TooManyOpenStreams) {
|
||||
pc, err = t.newClient(true, dialer).ListenPacketWithDialer(ctx, metadata, dialer, newDialFn)
|
||||
pc, err = t.newClient(true).ListenPacket(ctx, metadata)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -62,58 +51,63 @@ func (t *PoolClient) ListenPacketWithDialer(ctx context.Context, metadata *C.Met
|
||||
return N.NewRefPacketConn(pc, t), nil
|
||||
}
|
||||
|
||||
func (t *PoolClient) dial(ctx context.Context, dialer C.Dialer, dialFn DialFunc) (transport *quic.Transport, addr net.Addr, err error) {
|
||||
t.dialResultMutex.Lock()
|
||||
dr, ok := t.dialResultMap[dialer]
|
||||
t.dialResultMutex.Unlock()
|
||||
if ok {
|
||||
return dr.transport, dr.addr, dr.err
|
||||
// poolDialHelper is a helper for dialFn
|
||||
// using a standalone struct to let finalizer working
|
||||
type poolDialHelper struct {
|
||||
dialFn DialFunc
|
||||
dialResult atomic.Pointer[dialResult]
|
||||
}
|
||||
|
||||
type dialResult struct {
|
||||
transport *quic.Transport
|
||||
addr net.Addr
|
||||
}
|
||||
|
||||
func (t *poolDialHelper) dial(ctx context.Context) (transport *quic.Transport, addr net.Addr, err error) {
|
||||
if dr := t.dialResult.Load(); dr != nil {
|
||||
return dr.transport, dr.addr, nil
|
||||
}
|
||||
|
||||
transport, addr, err = dialFn(ctx, dialer)
|
||||
transport, addr, err = t.dialFn(ctx)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if _, ok := transport.Conn.(*net.UDPConn); ok { // only cache the system's UDPConn
|
||||
transport.SetSingleUse(false) // don't close transport in each dial
|
||||
dr.transport, dr.addr, dr.err = transport, addr, err
|
||||
|
||||
t.dialResultMutex.Lock()
|
||||
t.dialResultMap[dialer] = dr
|
||||
t.dialResultMutex.Unlock()
|
||||
dr := &dialResult{transport: transport, addr: addr}
|
||||
t.dialResult.Store(dr)
|
||||
}
|
||||
|
||||
return transport, addr, err
|
||||
}
|
||||
|
||||
func (t *PoolClient) forceClose() {
|
||||
t.dialResultMutex.Lock()
|
||||
defer t.dialResultMutex.Unlock()
|
||||
for key := range t.dialResultMap {
|
||||
transport := t.dialResultMap[key].transport
|
||||
func (t *poolDialHelper) forceClose() {
|
||||
if dr := t.dialResult.Swap(nil); dr != nil {
|
||||
transport := dr.transport
|
||||
if transport != nil {
|
||||
_ = transport.Close()
|
||||
}
|
||||
delete(t.dialResultMap, key)
|
||||
}
|
||||
}
|
||||
|
||||
func (t *PoolClient) newClient(udp bool, dialer C.Dialer) (client Client) {
|
||||
clients := t.tcpClients
|
||||
clientsMutex := t.tcpClientsMutex
|
||||
func (t *PoolClient) newClient(udp bool) (client Client) {
|
||||
clients := &t.tcpClients
|
||||
clientsMutex := &t.tcpClientsMutex
|
||||
if udp {
|
||||
clients = t.udpClients
|
||||
clientsMutex = t.udpClientsMutex
|
||||
clients = &t.udpClients
|
||||
clientsMutex = &t.udpClientsMutex
|
||||
}
|
||||
|
||||
clientsMutex.Lock()
|
||||
defer clientsMutex.Unlock()
|
||||
|
||||
dialHelper := t.dialHelper
|
||||
if t.newClientOptionV4 != nil {
|
||||
client = NewClientV4(t.newClientOptionV4, udp, dialer)
|
||||
client = NewClientV4(t.newClientOptionV4, udp, dialHelper.dial)
|
||||
} else {
|
||||
client = NewClientV5(t.newClientOptionV5, udp, dialer)
|
||||
client = NewClientV5(t.newClientOptionV5, udp, dialHelper.dial)
|
||||
}
|
||||
|
||||
client.SetLastVisited(time.Now())
|
||||
@ -122,12 +116,12 @@ func (t *PoolClient) newClient(udp bool, dialer C.Dialer) (client Client) {
|
||||
return client
|
||||
}
|
||||
|
||||
func (t *PoolClient) getClient(udp bool, dialer C.Dialer) Client {
|
||||
clients := t.tcpClients
|
||||
clientsMutex := t.tcpClientsMutex
|
||||
func (t *PoolClient) getClient(udp bool) Client {
|
||||
clients := &t.tcpClients
|
||||
clientsMutex := &t.tcpClientsMutex
|
||||
if udp {
|
||||
clients = t.udpClients
|
||||
clientsMutex = t.udpClientsMutex
|
||||
clients = &t.udpClients
|
||||
clientsMutex = &t.udpClientsMutex
|
||||
}
|
||||
var bestClient Client
|
||||
|
||||
@ -142,46 +136,39 @@ func (t *PoolClient) getClient(udp bool, dialer C.Dialer) Client {
|
||||
it = next
|
||||
continue
|
||||
}
|
||||
if client.DialerRef() == dialer {
|
||||
if bestClient == nil {
|
||||
if bestClient == nil {
|
||||
bestClient = client
|
||||
} else {
|
||||
if client.OpenStreams() < bestClient.OpenStreams() {
|
||||
bestClient = client
|
||||
} else {
|
||||
if client.OpenStreams() < bestClient.OpenStreams() {
|
||||
bestClient = client
|
||||
}
|
||||
}
|
||||
}
|
||||
it = it.Next()
|
||||
}
|
||||
}()
|
||||
for it := clients.Front(); it != nil; {
|
||||
client := it.Value
|
||||
if client != bestClient && client.OpenStreams() == 0 && time.Now().Sub(client.LastVisited()) > 30*time.Minute {
|
||||
client.Close()
|
||||
next := it.Next()
|
||||
clients.Remove(it)
|
||||
it = next
|
||||
continue
|
||||
for it := clients.Front(); it != nil; {
|
||||
client := it.Value
|
||||
if client != bestClient && client.OpenStreams() == 0 && time.Now().Sub(client.LastVisited()) > 30*time.Minute {
|
||||
client.Close()
|
||||
next := it.Next()
|
||||
clients.Remove(it)
|
||||
it = next
|
||||
continue
|
||||
}
|
||||
it = it.Next()
|
||||
}
|
||||
it = it.Next()
|
||||
}
|
||||
}()
|
||||
|
||||
if bestClient == nil {
|
||||
return t.newClient(udp, dialer)
|
||||
return t.newClient(udp)
|
||||
} else {
|
||||
bestClient.SetLastVisited(time.Now())
|
||||
return bestClient
|
||||
}
|
||||
}
|
||||
|
||||
func NewPoolClientV4(clientOption *ClientOptionV4) *PoolClient {
|
||||
func NewPoolClientV4(clientOption *ClientOptionV4, dialFn DialFunc) *PoolClient {
|
||||
p := &PoolClient{
|
||||
dialResultMap: make(map[C.Dialer]dialResult),
|
||||
dialResultMutex: &sync.Mutex{},
|
||||
tcpClients: list.New[Client](),
|
||||
tcpClientsMutex: &sync.Mutex{},
|
||||
udpClients: list.New[Client](),
|
||||
udpClientsMutex: &sync.Mutex{},
|
||||
dialHelper: &poolDialHelper{dialFn: dialFn},
|
||||
}
|
||||
newClientOption := *clientOption
|
||||
p.newClientOptionV4 = &newClientOption
|
||||
@ -190,14 +177,9 @@ func NewPoolClientV4(clientOption *ClientOptionV4) *PoolClient {
|
||||
return p
|
||||
}
|
||||
|
||||
func NewPoolClientV5(clientOption *ClientOptionV5) *PoolClient {
|
||||
func NewPoolClientV5(clientOption *ClientOptionV5, dialFn DialFunc) *PoolClient {
|
||||
p := &PoolClient{
|
||||
dialResultMap: make(map[C.Dialer]dialResult),
|
||||
dialResultMutex: &sync.Mutex{},
|
||||
tcpClients: list.New[Client](),
|
||||
tcpClientsMutex: &sync.Mutex{},
|
||||
udpClients: list.New[Client](),
|
||||
udpClientsMutex: &sync.Mutex{},
|
||||
dialHelper: &poolDialHelper{dialFn: dialFn},
|
||||
}
|
||||
newClientOption := *clientOption
|
||||
p.newClientOptionV5 = &newClientOption
|
||||
@ -208,5 +190,5 @@ func NewPoolClientV5(clientOption *ClientOptionV5) *PoolClient {
|
||||
|
||||
func closeClientPool(client *PoolClient) {
|
||||
log.Debugln("Close Tuic PoolClient at %p", client)
|
||||
client.forceClose()
|
||||
client.dialHelper.forceClose()
|
||||
}
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
package tuic
|
||||
|
||||
import (
|
||||
C "github.com/metacubex/mihomo/constant"
|
||||
"github.com/metacubex/mihomo/transport/tuic/common"
|
||||
v4 "github.com/metacubex/mihomo/transport/tuic/v4"
|
||||
v5 "github.com/metacubex/mihomo/transport/tuic/v5"
|
||||
@ -12,12 +11,12 @@ type ClientOptionV5 = v5.ClientOption
|
||||
|
||||
type Client = common.Client
|
||||
|
||||
func NewClientV4(clientOption *ClientOptionV4, udp bool, dialerRef C.Dialer) Client {
|
||||
return v4.NewClient(clientOption, udp, dialerRef)
|
||||
func NewClientV4(clientOption *ClientOptionV4, udp bool, dialFn DialFunc) Client {
|
||||
return v4.NewClient(clientOption, udp, dialFn)
|
||||
}
|
||||
|
||||
func NewClientV5(clientOption *ClientOptionV5, udp bool, dialerRef C.Dialer) Client {
|
||||
return v5.NewClient(clientOption, udp, dialerRef)
|
||||
func NewClientV5(clientOption *ClientOptionV5, udp bool, dialFn DialFunc) Client {
|
||||
return v5.NewClient(clientOption, udp, dialFn)
|
||||
}
|
||||
|
||||
type DialFunc = common.DialFunc
|
||||
|
||||
@ -40,7 +40,8 @@ type ClientOption struct {
|
||||
|
||||
type clientImpl struct {
|
||||
*ClientOption
|
||||
udp bool
|
||||
dialFn common.DialFunc
|
||||
udp bool
|
||||
|
||||
quicConn *quic.Conn
|
||||
connMutex sync.Mutex
|
||||
@ -51,7 +52,6 @@ type clientImpl struct {
|
||||
udpInputMap xsync.Map[uint32, net.Conn]
|
||||
|
||||
// only ready for PoolClient
|
||||
dialerRef C.Dialer
|
||||
lastVisited atomic2.TypedValue[time.Time]
|
||||
}
|
||||
|
||||
@ -59,10 +59,6 @@ func (t *clientImpl) OpenStreams() int64 {
|
||||
return t.openStreams.Load()
|
||||
}
|
||||
|
||||
func (t *clientImpl) DialerRef() C.Dialer {
|
||||
return t.dialerRef
|
||||
}
|
||||
|
||||
func (t *clientImpl) LastVisited() time.Time {
|
||||
return t.lastVisited.Load()
|
||||
}
|
||||
@ -71,13 +67,13 @@ func (t *clientImpl) SetLastVisited(last time.Time) {
|
||||
t.lastVisited.Store(last)
|
||||
}
|
||||
|
||||
func (t *clientImpl) getQuicConn(ctx context.Context, dialer C.Dialer, dialFn common.DialFunc) (*quic.Conn, error) {
|
||||
func (t *clientImpl) getQuicConn(ctx context.Context) (*quic.Conn, error) {
|
||||
t.connMutex.Lock()
|
||||
defer t.connMutex.Unlock()
|
||||
if t.quicConn != nil {
|
||||
return t.quicConn, nil
|
||||
}
|
||||
transport, addr, err := dialFn(ctx, dialer)
|
||||
transport, addr, err := t.dialFn(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -262,7 +258,7 @@ func (t *clientImpl) forceClose(quicConn *quic.Conn, err error) {
|
||||
if quicConn != nil {
|
||||
_ = quicConn.CloseWithError(ProtocolError, errStr)
|
||||
}
|
||||
udpInputMap := t.udpInputMap
|
||||
udpInputMap := &t.udpInputMap
|
||||
udpInputMap.Range(func(key uint32, value net.Conn) bool {
|
||||
conn := value
|
||||
_ = conn.Close()
|
||||
@ -278,8 +274,8 @@ func (t *clientImpl) Close() {
|
||||
}
|
||||
}
|
||||
|
||||
func (t *clientImpl) DialContextWithDialer(ctx context.Context, metadata *C.Metadata, dialer C.Dialer, dialFn common.DialFunc) (net.Conn, error) {
|
||||
quicConn, err := t.getQuicConn(ctx, dialer, dialFn)
|
||||
func (t *clientImpl) DialContext(ctx context.Context, metadata *C.Metadata) (net.Conn, error) {
|
||||
quicConn, err := t.getQuicConn(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -353,8 +349,8 @@ func (t *clientImpl) DialContextWithDialer(ctx context.Context, metadata *C.Meta
|
||||
return bufConn, nil
|
||||
}
|
||||
|
||||
func (t *clientImpl) ListenPacketWithDialer(ctx context.Context, metadata *C.Metadata, dialer C.Dialer, dialFn common.DialFunc) (net.PacketConn, error) {
|
||||
quicConn, err := t.getQuicConn(ctx, dialer, dialFn)
|
||||
func (t *clientImpl) ListenPacket(ctx context.Context, metadata *C.Metadata) (net.PacketConn, error) {
|
||||
quicConn, err := t.getQuicConn(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -397,16 +393,16 @@ type Client struct {
|
||||
*clientImpl // use an independent pointer to let Finalizer can work no matter somewhere handle an influence in clientImpl inner
|
||||
}
|
||||
|
||||
func (t *Client) DialContextWithDialer(ctx context.Context, metadata *C.Metadata, dialer C.Dialer, dialFn common.DialFunc) (net.Conn, error) {
|
||||
conn, err := t.clientImpl.DialContextWithDialer(ctx, metadata, dialer, dialFn)
|
||||
func (t *Client) DialContext(ctx context.Context, metadata *C.Metadata) (net.Conn, error) {
|
||||
conn, err := t.clientImpl.DialContext(ctx, metadata)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return N.NewRefConn(conn, t), err
|
||||
}
|
||||
|
||||
func (t *Client) ListenPacketWithDialer(ctx context.Context, metadata *C.Metadata, dialer C.Dialer, dialFn common.DialFunc) (net.PacketConn, error) {
|
||||
pc, err := t.clientImpl.ListenPacketWithDialer(ctx, metadata, dialer, dialFn)
|
||||
func (t *Client) ListenPacket(ctx context.Context, metadata *C.Metadata) (net.PacketConn, error) {
|
||||
pc, err := t.clientImpl.ListenPacket(ctx, metadata)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -417,11 +413,11 @@ func (t *Client) forceClose() {
|
||||
t.clientImpl.forceClose(nil, common.ClientClosed)
|
||||
}
|
||||
|
||||
func NewClient(clientOption *ClientOption, udp bool, dialerRef C.Dialer) *Client {
|
||||
func NewClient(clientOption *ClientOption, udp bool, dialFn common.DialFunc) *Client {
|
||||
ci := &clientImpl{
|
||||
ClientOption: clientOption,
|
||||
dialFn: dialFn,
|
||||
udp: udp,
|
||||
dialerRef: dialerRef,
|
||||
}
|
||||
c := &Client{ci}
|
||||
runtime.SetFinalizer(c, closeClient)
|
||||
|
||||
@ -39,7 +39,8 @@ type ClientOption struct {
|
||||
|
||||
type clientImpl struct {
|
||||
*ClientOption
|
||||
udp bool
|
||||
dialFn common.DialFunc
|
||||
udp bool
|
||||
|
||||
quicConn *quic.Conn
|
||||
connMutex sync.Mutex
|
||||
@ -50,7 +51,6 @@ type clientImpl struct {
|
||||
udpInputMap xsync.Map[uint16, net.Conn]
|
||||
|
||||
// only ready for PoolClient
|
||||
dialerRef C.Dialer
|
||||
lastVisited atomic2.TypedValue[time.Time]
|
||||
}
|
||||
|
||||
@ -58,10 +58,6 @@ func (t *clientImpl) OpenStreams() int64 {
|
||||
return t.openStreams.Load()
|
||||
}
|
||||
|
||||
func (t *clientImpl) DialerRef() C.Dialer {
|
||||
return t.dialerRef
|
||||
}
|
||||
|
||||
func (t *clientImpl) LastVisited() time.Time {
|
||||
return t.lastVisited.Load()
|
||||
}
|
||||
@ -70,13 +66,13 @@ func (t *clientImpl) SetLastVisited(last time.Time) {
|
||||
t.lastVisited.Store(last)
|
||||
}
|
||||
|
||||
func (t *clientImpl) getQuicConn(ctx context.Context, dialer C.Dialer, dialFn common.DialFunc) (*quic.Conn, error) {
|
||||
func (t *clientImpl) getQuicConn(ctx context.Context) (*quic.Conn, error) {
|
||||
t.connMutex.Lock()
|
||||
defer t.connMutex.Unlock()
|
||||
if t.quicConn != nil {
|
||||
return t.quicConn, nil
|
||||
}
|
||||
transport, addr, err := dialFn(ctx, dialer)
|
||||
transport, addr, err := t.dialFn(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -270,7 +266,7 @@ func (t *clientImpl) forceClose(quicConn *quic.Conn, err error) {
|
||||
if quicConn != nil {
|
||||
_ = quicConn.CloseWithError(ProtocolError, errStr)
|
||||
}
|
||||
udpInputMap := t.udpInputMap
|
||||
udpInputMap := &t.udpInputMap
|
||||
udpInputMap.Range(func(key uint16, value net.Conn) bool {
|
||||
conn := value
|
||||
_ = conn.Close()
|
||||
@ -286,8 +282,8 @@ func (t *clientImpl) Close() {
|
||||
}
|
||||
}
|
||||
|
||||
func (t *clientImpl) DialContextWithDialer(ctx context.Context, metadata *C.Metadata, dialer C.Dialer, dialFn common.DialFunc) (net.Conn, error) {
|
||||
quicConn, err := t.getQuicConn(ctx, dialer, dialFn)
|
||||
func (t *clientImpl) DialContext(ctx context.Context, metadata *C.Metadata) (net.Conn, error) {
|
||||
quicConn, err := t.getQuicConn(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -337,8 +333,8 @@ func (t *clientImpl) DialContextWithDialer(ctx context.Context, metadata *C.Meta
|
||||
return stream, nil
|
||||
}
|
||||
|
||||
func (t *clientImpl) ListenPacketWithDialer(ctx context.Context, metadata *C.Metadata, dialer C.Dialer, dialFn common.DialFunc) (net.PacketConn, error) {
|
||||
quicConn, err := t.getQuicConn(ctx, dialer, dialFn)
|
||||
func (t *clientImpl) ListenPacket(ctx context.Context, metadata *C.Metadata) (net.PacketConn, error) {
|
||||
quicConn, err := t.getQuicConn(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -381,16 +377,16 @@ type Client struct {
|
||||
*clientImpl // use an independent pointer to let Finalizer can work no matter somewhere handle an influence in clientImpl inner
|
||||
}
|
||||
|
||||
func (t *Client) DialContextWithDialer(ctx context.Context, metadata *C.Metadata, dialer C.Dialer, dialFn common.DialFunc) (net.Conn, error) {
|
||||
conn, err := t.clientImpl.DialContextWithDialer(ctx, metadata, dialer, dialFn)
|
||||
func (t *Client) DialContext(ctx context.Context, metadata *C.Metadata) (net.Conn, error) {
|
||||
conn, err := t.clientImpl.DialContext(ctx, metadata)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return N.NewRefConn(conn, t), err
|
||||
}
|
||||
|
||||
func (t *Client) ListenPacketWithDialer(ctx context.Context, metadata *C.Metadata, dialer C.Dialer, dialFn common.DialFunc) (net.PacketConn, error) {
|
||||
pc, err := t.clientImpl.ListenPacketWithDialer(ctx, metadata, dialer, dialFn)
|
||||
func (t *Client) ListenPacket(ctx context.Context, metadata *C.Metadata) (net.PacketConn, error) {
|
||||
pc, err := t.clientImpl.ListenPacket(ctx, metadata)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -401,11 +397,11 @@ func (t *Client) forceClose() {
|
||||
t.clientImpl.forceClose(nil, common.ClientClosed)
|
||||
}
|
||||
|
||||
func NewClient(clientOption *ClientOption, udp bool, dialerRef C.Dialer) *Client {
|
||||
func NewClient(clientOption *ClientOption, udp bool, dialFn common.DialFunc) *Client {
|
||||
ci := &clientImpl{
|
||||
ClientOption: clientOption,
|
||||
dialFn: dialFn,
|
||||
udp: udp,
|
||||
dialerRef: dialerRef,
|
||||
}
|
||||
c := &Client{ci}
|
||||
runtime.SetFinalizer(c, closeClient)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user