func (c *ConnectionTracker) Track(conn net.Conn) net.Conn {
	closable := &closableConn{Conn: conn}
	closable.onClose = func() {
		c.mu.Lock()
		delete(c.conns, closable)
		c.mu.Unlock()
	}
	c.mu.Lock()
	c.conns[closable] = struct{}{}
	c.mu.Unlock()
	return closable
}
Track adds the connection to the list of tracked connections,
and returns a wrapped copy of the connection that stops tracking the connection
when it is closed.
package connrotation
import (
	"context"
	"net"
	"sync"
)
type DialFunc func(ctx context.Context, network, address string) (net.Conn, error)
type Dialer struct {
	dial DialFunc
	*ConnectionTracker
}
func NewDialer(dial DialFunc) *Dialer {
	return NewDialerWithTracker(dial, nil)
}
func NewDialerWithTracker(dial DialFunc, tracker *ConnectionTracker) *Dialer {
	if tracker == nil {
		tracker = NewConnectionTracker()
	}
	return &Dialer{
		dial:              dial,
		ConnectionTracker: tracker,
	}
}
type ConnectionTracker struct {
	mu    sync.Mutex
	conns map[*closableConn]struct{}
}
func NewConnectionTracker() *ConnectionTracker {
	return &ConnectionTracker{
		conns: make(map[*closableConn]struct{}),
	}
}
func (c *ConnectionTracker) CloseAll() {
	c.mu.Lock()
	conns := c.conns
	c.conns = make(map[*closableConn]struct{})
	c.mu.Unlock()
	for conn := range conns {
		conn.Close()
	}
}