61 lines
1.2 KiB
Go
61 lines
1.2 KiB
Go
package allowlist
|
|
|
|
import (
|
|
"fmt"
|
|
"net/netip"
|
|
"strings"
|
|
)
|
|
|
|
// ParseCommaList parses MTPROXY_ALLOWED_IPS: comma-separated IPv4/IPv6 addresses or CIDR prefixes.
|
|
// Empty or whitespace-only input returns (nil, nil) meaning no restriction.
|
|
func ParseCommaList(s string) ([]netip.Prefix, error) {
|
|
s = strings.TrimSpace(s)
|
|
if s == "" {
|
|
return nil, nil
|
|
}
|
|
var out []netip.Prefix
|
|
for _, part := range strings.Split(s, ",") {
|
|
part = strings.TrimSpace(part)
|
|
if part == "" {
|
|
continue
|
|
}
|
|
pfx, err := parseEntry(part)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("allowed_ips entry %q: %w", part, err)
|
|
}
|
|
out = append(out, pfx)
|
|
}
|
|
if len(out) == 0 {
|
|
return nil, nil
|
|
}
|
|
return out, nil
|
|
}
|
|
|
|
func parseEntry(s string) (netip.Prefix, error) {
|
|
if strings.Contains(s, "/") {
|
|
return netip.ParsePrefix(s)
|
|
}
|
|
addr, err := netip.ParseAddr(s)
|
|
if err != nil {
|
|
return netip.Prefix{}, err
|
|
}
|
|
bits := 32
|
|
if addr.Is6() {
|
|
bits = 128
|
|
}
|
|
return addr.Prefix(bits)
|
|
}
|
|
|
|
// Contains reports whether addr matches any prefix in list. Empty list means allow all.
|
|
func Contains(list []netip.Prefix, addr netip.Addr) bool {
|
|
if len(list) == 0 {
|
|
return true
|
|
}
|
|
for _, p := range list {
|
|
if p.Contains(addr) {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|