mirror of
https://github.com/pomerium/pomerium.git
synced 2025-04-29 18:36:30 +02:00
47 lines
973 B
Go
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
|
|
}
|