pomerium/pkg/netutil/netutil.go
2025-02-19 09:45:21 -07:00

47 lines
973 B
Go

// Package netutil contains various functions that help with networking.
package netutil
import (
"net"
"sync"
"time"
)
var (
allocatedPortsMu sync.Mutex
allocatedPorts = map[string]time.Time{}
)
// AllocatePorts allocates random ports suitable for listening.
func AllocatePorts(count int) ([]string, error) {
allocatedPortsMu.Lock()
defer allocatedPortsMu.Unlock()
now := time.Now()
cooloff := 10 * time.Minute
// clear any expired ports
for port, tm := range allocatedPorts {
if tm.Add(cooloff).Before(now) {
delete(allocatedPorts, port)
}
}
var ports []string
for len(ports) < count {
li, err := net.Listen("tcp", "127.0.0.1:0")
if err != nil {
return nil, err
}
_, port, _ := net.SplitHostPort(li.Addr().String())
defer li.Close()
// if this port has been allocated recently, skip it
if _, ok := allocatedPorts[port]; ok {
continue
}
allocatedPorts[port] = now
ports = append(ports, port)
}
return ports, nil
}