Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions adapter/outbound/tuic.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,14 @@ func (t *Tuic) ProxyInfo() C.ProxyInfo {
return info
}

// Close implements C.ProxyAdapter
func (t *Tuic) Close() error {
if t.client != nil {
return t.client.Close()
}
return nil
}

func NewTuic(option TuicOption) (*Tuic, error) {
addr := net.JoinHostPort(option.Server, strconv.Itoa(option.Port))
serverName := option.Server
Expand Down
21 changes: 21 additions & 0 deletions transport/tuic/pool_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,27 @@ func (t *PoolClient) getClient(udp bool) Client {
}
}

// Close releases all resources held by the PoolClient by closing every
// cached clientImpl in both the tcp and udp lists. Each clientImpl owns its
// own SingleUse *quic.Transport that is auto-closed when the underlying
// quicConn closes, so no additional cleanup is needed at the pool level.
// Close is safe to call multiple times.
func (t *PoolClient) Close() error {
closeClients := func(clients *list.List[Client], mu *sync.Mutex) {
mu.Lock()
defer mu.Unlock()
for it := clients.Front(); it != nil; it = it.Next() {
if c := it.Value; c != nil {
c.Close()
}
}
clients.Init()
}
closeClients(&t.tcpClients, &t.tcpClientsMutex)
closeClients(&t.udpClients, &t.udpClientsMutex)
return nil
}

func NewPoolClientV4(clientOption *ClientOptionV4, dialFn DialFunc) *PoolClient {
p := &PoolClient{
dialFn: dialFn,
Expand Down