mirror of
https://github.com/caddyserver/caddy.git
synced 2024-11-25 08:27:39 +08:00
core: Change net.IP to netip.Addr; use netip.Prefix (#4966)
Co-authored-by: Matt Holt <mholt@users.noreply.github.com>
This commit is contained in:
parent
a944de4ab7
commit
c7772588bd
|
@ -17,6 +17,7 @@ package httpcaddyfile
|
|||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"net/netip"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strconv"
|
||||
|
@ -354,9 +355,9 @@ func (a Address) Normalize() Address {
|
|||
|
||||
// ensure host is normalized if it's an IP address
|
||||
host := strings.TrimSpace(a.Host)
|
||||
if ip := net.ParseIP(host); ip != nil {
|
||||
if ipv6 := ip.To16(); ipv6 != nil && ipv6.DefaultMask() == nil {
|
||||
host = ipv6.String()
|
||||
if ip, err := netip.ParseAddr(host); err == nil {
|
||||
if ip.Is6() && !ip.Is4() && !ip.Is4In6() {
|
||||
host = ip.String()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/netip"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
@ -400,7 +401,7 @@ func (na NetworkAddress) isLoopback() bool {
|
|||
if na.Host == "localhost" {
|
||||
return true
|
||||
}
|
||||
if ip := net.ParseIP(na.Host); ip != nil {
|
||||
if ip, err := netip.ParseAddr(na.Host); err == nil {
|
||||
return ip.IsLoopback()
|
||||
}
|
||||
return false
|
||||
|
@ -410,7 +411,7 @@ func (na NetworkAddress) isWildcardInterface() bool {
|
|||
if na.Host == "" {
|
||||
return true
|
||||
}
|
||||
if ip := net.ParseIP(na.Host); ip != nil {
|
||||
if ip, err := netip.ParseAddr(na.Host); err == nil {
|
||||
return ip.IsUnspecified()
|
||||
}
|
||||
return false
|
||||
|
|
|
@ -20,6 +20,7 @@ import (
|
|||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/netip"
|
||||
"net/textproto"
|
||||
"net/url"
|
||||
"path"
|
||||
|
@ -171,7 +172,7 @@ type (
|
|||
|
||||
// cidrs and zones vars should aligned always in the same
|
||||
// length and indexes for matching later
|
||||
cidrs []*net.IPNet
|
||||
cidrs []*netip.Prefix
|
||||
zones []string
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
@ -1311,27 +1312,24 @@ func (m *MatchRemoteIP) Provision(ctx caddy.Context) error {
|
|||
m.zones = append(m.zones, "")
|
||||
}
|
||||
if strings.Contains(str, "/") {
|
||||
_, ipNet, err := net.ParseCIDR(str)
|
||||
ipNet, err := netip.ParsePrefix(str)
|
||||
if err != nil {
|
||||
return fmt.Errorf("parsing CIDR expression '%s': %v", str, err)
|
||||
}
|
||||
m.cidrs = append(m.cidrs, ipNet)
|
||||
m.cidrs = append(m.cidrs, &ipNet)
|
||||
} else {
|
||||
ip := net.ParseIP(str)
|
||||
if ip == nil {
|
||||
return fmt.Errorf("invalid IP address: %s", str)
|
||||
ipAddr, err := netip.ParseAddr(str)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid IP address: '%s': %v", str, err)
|
||||
}
|
||||
mask := len(ip) * 8
|
||||
m.cidrs = append(m.cidrs, &net.IPNet{
|
||||
IP: ip,
|
||||
Mask: net.CIDRMask(mask, mask),
|
||||
})
|
||||
ipNew := netip.PrefixFrom(ipAddr, ipAddr.BitLen())
|
||||
m.cidrs = append(m.cidrs, &ipNew)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m MatchRemoteIP) getClientIP(r *http.Request) (net.IP, string, error) {
|
||||
func (m MatchRemoteIP) getClientIP(r *http.Request) (netip.Addr, string, error) {
|
||||
remote := r.RemoteAddr
|
||||
zoneID := ""
|
||||
if m.Forwarded {
|
||||
|
@ -1350,11 +1348,11 @@ func (m MatchRemoteIP) getClientIP(r *http.Request) (net.IP, string, error) {
|
|||
ipStr = split[0]
|
||||
zoneID = split[1]
|
||||
}
|
||||
ip := net.ParseIP(ipStr)
|
||||
if ip == nil {
|
||||
return nil, zoneID, fmt.Errorf("invalid client IP address: %s", ipStr)
|
||||
ipAddr, err := netip.ParseAddr(ipStr)
|
||||
if err != nil {
|
||||
return netip.IPv4Unspecified(), "", err
|
||||
}
|
||||
return ip, zoneID, nil
|
||||
return ipAddr, zoneID, nil
|
||||
}
|
||||
|
||||
// Match returns true if r matches m.
|
||||
|
|
|
@ -24,6 +24,7 @@ import (
|
|||
"net"
|
||||
"net/http"
|
||||
"net/http/httptrace"
|
||||
"net/netip"
|
||||
"net/textproto"
|
||||
"net/url"
|
||||
"regexp"
|
||||
|
@ -180,7 +181,7 @@ type Handler struct {
|
|||
DynamicUpstreams UpstreamSource `json:"-"`
|
||||
|
||||
// Holds the parsed CIDR ranges from TrustedProxies
|
||||
trustedProxies []*net.IPNet
|
||||
trustedProxies []netip.Prefix
|
||||
|
||||
// Holds the named response matchers from the Caddyfile while adapting
|
||||
responseMatchers map[string]caddyhttp.ResponseMatcher
|
||||
|
@ -251,24 +252,18 @@ func (h *Handler) Provision(ctx caddy.Context) error {
|
|||
// parse trusted proxy CIDRs ahead of time
|
||||
for _, str := range h.TrustedProxies {
|
||||
if strings.Contains(str, "/") {
|
||||
_, ipNet, err := net.ParseCIDR(str)
|
||||
ipNet, err := netip.ParsePrefix(str)
|
||||
if err != nil {
|
||||
return fmt.Errorf("parsing CIDR expression: %v", err)
|
||||
return fmt.Errorf("parsing CIDR expression: '%s': %v", str, err)
|
||||
}
|
||||
h.trustedProxies = append(h.trustedProxies, ipNet)
|
||||
} else {
|
||||
ip := net.ParseIP(str)
|
||||
if ip == nil {
|
||||
return fmt.Errorf("invalid IP address: %s", str)
|
||||
ipAddr, err := netip.ParseAddr(str)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid IP address: '%s': %v", str, err)
|
||||
}
|
||||
if ipv4 := ip.To4(); ipv4 != nil {
|
||||
ip = ipv4
|
||||
}
|
||||
mask := len(ip) * 8
|
||||
h.trustedProxies = append(h.trustedProxies, &net.IPNet{
|
||||
IP: ip,
|
||||
Mask: net.CIDRMask(mask, mask),
|
||||
})
|
||||
ipNew := netip.PrefixFrom(ipAddr, ipAddr.BitLen())
|
||||
h.trustedProxies = append(h.trustedProxies, ipNew)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -672,15 +667,15 @@ func (h Handler) addForwardedHeaders(req *http.Request) error {
|
|||
if before, _, found := strings.Cut(clientIP, "%"); found {
|
||||
clientIP = before
|
||||
}
|
||||
ip := net.ParseIP(clientIP)
|
||||
if ip == nil {
|
||||
return fmt.Errorf("invalid client IP address: %s", clientIP)
|
||||
ipAddr, err := netip.ParseAddr(clientIP)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid IP address: '%s': %v", clientIP, err)
|
||||
}
|
||||
|
||||
// Check if the client is a trusted proxy
|
||||
trusted := false
|
||||
for _, ipRange := range h.trustedProxies {
|
||||
if ipRange.Contains(ip) {
|
||||
if ipRange.Contains(ipAddr) {
|
||||
trusted = true
|
||||
break
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ import (
|
|||
"crypto/tls"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/netip"
|
||||
"strings"
|
||||
|
||||
"github.com/caddyserver/caddy/v2"
|
||||
|
@ -65,8 +66,8 @@ type MatchRemoteIP struct {
|
|||
// The IPs or CIDR ranges to *NOT* match.
|
||||
NotRanges []string `json:"not_ranges,omitempty"`
|
||||
|
||||
cidrs []*net.IPNet
|
||||
notCidrs []*net.IPNet
|
||||
cidrs []netip.Prefix
|
||||
notCidrs []netip.Prefix
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
|
@ -105,38 +106,35 @@ func (m MatchRemoteIP) Match(hello *tls.ClientHelloInfo) bool {
|
|||
if err != nil {
|
||||
ipStr = remoteAddr // weird; maybe no port?
|
||||
}
|
||||
ip := net.ParseIP(ipStr)
|
||||
if ip == nil {
|
||||
ipAddr, err := netip.ParseAddr(ipStr)
|
||||
if err != nil {
|
||||
m.logger.Error("invalid client IP addresss", zap.String("ip", ipStr))
|
||||
return false
|
||||
}
|
||||
return (len(m.cidrs) == 0 || m.matches(ip, m.cidrs)) &&
|
||||
(len(m.notCidrs) == 0 || !m.matches(ip, m.notCidrs))
|
||||
return (len(m.cidrs) == 0 || m.matches(ipAddr, m.cidrs)) &&
|
||||
(len(m.notCidrs) == 0 || !m.matches(ipAddr, m.notCidrs))
|
||||
}
|
||||
|
||||
func (MatchRemoteIP) parseIPRange(str string) ([]*net.IPNet, error) {
|
||||
var cidrs []*net.IPNet
|
||||
func (MatchRemoteIP) parseIPRange(str string) ([]netip.Prefix, error) {
|
||||
var cidrs []netip.Prefix
|
||||
if strings.Contains(str, "/") {
|
||||
_, ipNet, err := net.ParseCIDR(str)
|
||||
ipNet, err := netip.ParsePrefix(str)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("parsing CIDR expression: %v", err)
|
||||
}
|
||||
cidrs = append(cidrs, ipNet)
|
||||
} else {
|
||||
ip := net.ParseIP(str)
|
||||
if ip == nil {
|
||||
return nil, fmt.Errorf("invalid IP address: %s", str)
|
||||
ipAddr, err := netip.ParseAddr(str)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid IP address: '%s': %v", str, err)
|
||||
}
|
||||
mask := len(ip) * 8
|
||||
cidrs = append(cidrs, &net.IPNet{
|
||||
IP: ip,
|
||||
Mask: net.CIDRMask(mask, mask),
|
||||
})
|
||||
ip := netip.PrefixFrom(ipAddr, ipAddr.BitLen())
|
||||
cidrs = append(cidrs, ip)
|
||||
}
|
||||
return cidrs, nil
|
||||
}
|
||||
|
||||
func (MatchRemoteIP) matches(ip net.IP, ranges []*net.IPNet) bool {
|
||||
func (MatchRemoteIP) matches(ip netip.Addr, ranges []netip.Prefix) bool {
|
||||
for _, ipRange := range ranges {
|
||||
if ipRange.Contains(ip) {
|
||||
return true
|
||||
|
|
Loading…
Reference in New Issue
Block a user