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 }