|
| 1 | +package services |
| 2 | + |
| 3 | +import ( |
| 4 | + "net" |
| 5 | + |
| 6 | + "github.com/pkg/errors" |
| 7 | +) |
| 8 | + |
| 9 | +var disallowedPorts = map[int]string{ |
| 10 | + // Anything <= 1024 |
| 11 | + 1433: "MS-SQL (Microsoft SQL Server database management system)", |
| 12 | + 1434: "MS-SQL (Microsoft SQL Server database management system)", |
| 13 | + 1521: "Oracle SQL", |
| 14 | + 1701: "L2TP (Layer 2 Tunneling Protocol)", |
| 15 | + 1723: "PPTP (Point-to-Point Tunneling Protocol)", |
| 16 | + 2049: "NFS (Network File System)", |
| 17 | + 3000: "Node.js (Server-side JavaScript environment)", |
| 18 | + 3001: "Node.js (Server-side JavaScript environment)", |
| 19 | + 3306: "MySQL (Database system)", |
| 20 | + 3389: "RDP (Remote Desktop Protocol)", |
| 21 | + 5060: "SIP (Session Initiation Protocol)", |
| 22 | + 5145: "RSH (Remote Shell)", |
| 23 | + 5353: "mDNS (Multicast DNS)", |
| 24 | + 5432: "PostgreSQL (Database system)", |
| 25 | + 5900: "VNC (Virtual Network Computing)", |
| 26 | + 6379: "Redis (Database system)", |
| 27 | + 8000: "HTTP Alternate (http_alt)", |
| 28 | + 8080: "HTTP Alternate (http_alt)", |
| 29 | + 8082: "PHP FPM", |
| 30 | + 8443: "HTTPS Alternate (https_alt)", |
| 31 | + 9443: "Redis Enterprise (Database system)", |
| 32 | +} |
| 33 | + |
| 34 | +func getAvailablePort() (int, error) { |
| 35 | + get := func() (int, error) { |
| 36 | + addr, err := net.ResolveTCPAddr("tcp", "localhost:0") |
| 37 | + if err != nil { |
| 38 | + return 0, errors.WithStack(err) |
| 39 | + } |
| 40 | + |
| 41 | + l, err := net.ListenTCP("tcp", addr) |
| 42 | + if err != nil { |
| 43 | + return 0, errors.WithStack(err) |
| 44 | + } |
| 45 | + defer l.Close() |
| 46 | + return l.Addr().(*net.TCPAddr).Port, nil |
| 47 | + } |
| 48 | + |
| 49 | + for range 1000 { |
| 50 | + port, err := get() |
| 51 | + if err != nil { |
| 52 | + return 0, errors.WithStack(err) |
| 53 | + } |
| 54 | + |
| 55 | + if isAllowed(port) { |
| 56 | + return port, nil |
| 57 | + } |
| 58 | + } |
| 59 | + |
| 60 | + return 0, errors.New("no available port") |
| 61 | +} |
| 62 | + |
| 63 | +func isAllowed(port int) bool { |
| 64 | + return port > 1024 && disallowedPorts[port] == "" |
| 65 | +} |
0 commit comments