@marcel91200 / caddy Mirror · read-only / commits / c7772588
Fork 0

Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS

Mirrored from https://github.com/Slazee/caddy.git

Synced Nov 13, 15:30 UTC

core: Change net.IP to netip.Addr; use netip.Prefix (#4966)

Co-authored-by: Matt Holt <mholt@users.noreply.github.com>

WilczyńskiT committed Aug 18, 2022 at 00:10 UTC c7772588bd44ceffcc0ba4817e4d43c826675379
5 files changed +50 -57
caddyconfig/httpcaddyfile/addresses.go
+4 -3
@@ -17,6 +17,7 @@ package httpcaddyfile
17 import (
18 "fmt"
19 "net"
20 + "net/netip"
21 "reflect"
22 "sort"
23 "strconv"
@@ -354,9 +355,9 @@ func (a Address) Normalize() Address {
355
356 // ensure host is normalized if it's an IP address
357 host := strings.TrimSpace(a.Host)
357 - if ip := net.ParseIP(host); ip != nil {
358 - if ipv6 := ip.To16(); ipv6 != nil && ipv6.DefaultMask() == nil {
359 - host = ipv6.String()
358 + if ip, err := netip.ParseAddr(host); err == nil {
359 + if ip.Is6() && !ip.Is4() && !ip.Is4In6() {
360 + host = ip.String()
361 }
362 }
363
listeners.go
+3 -2
@@ -20,6 +20,7 @@ import (
20 "errors"
21 "fmt"
22 "net"
23 + "net/netip"
24 "os"
25 "strconv"
26 "strings"
@@ -400,7 +401,7 @@ func (na NetworkAddress) isLoopback() bool {
401 if na.Host == "localhost" {
402 return true
403 }
403 - if ip := net.ParseIP(na.Host); ip != nil {
404 + if ip, err := netip.ParseAddr(na.Host); err == nil {
405 return ip.IsLoopback()
406 }
407 return false
@@ -410,7 +411,7 @@ func (na NetworkAddress) isWildcardInterface() bool {
411 if na.Host == "" {
412 return true
413 }
413 - if ip := net.ParseIP(na.Host); ip != nil {
414 + if ip, err := netip.ParseAddr(na.Host); err == nil {
415 return ip.IsUnspecified()
416 }
417 return false
modules/caddyhttp/matchers.go
+14 -16
@@ -20,6 +20,7 @@ import (
20 "fmt"
21 "net"
22 "net/http"
23 + "net/netip"
24 "net/textproto"
25 "net/url"
26 "path"
@@ -171,7 +172,7 @@ type (
172
173 // cidrs and zones vars should aligned always in the same
174 // length and indexes for matching later
174 - cidrs []*net.IPNet
175 + cidrs []*netip.Prefix
176 zones []string
177 logger *zap.Logger
178 }
@@ -1311,27 +1312,24 @@ func (m *MatchRemoteIP) Provision(ctx caddy.Context) error {
1312 m.zones = append(m.zones, "")
1313 }
1314 if strings.Contains(str, "/") {
1314 - _, ipNet, err := net.ParseCIDR(str)
1315 + ipNet, err := netip.ParsePrefix(str)
1316 if err != nil {
1317 return fmt.Errorf("parsing CIDR expression '%s': %v", str, err)
1318 }
1318 - m.cidrs = append(m.cidrs, ipNet)
1319 + m.cidrs = append(m.cidrs, &ipNet)
1320 } else {
1320 - ip := net.ParseIP(str)
1321 - if ip == nil {
1322 - return fmt.Errorf("invalid IP address: %s", str)
1321 + ipAddr, err := netip.ParseAddr(str)
1322 + if err != nil {
1323 + return fmt.Errorf("invalid IP address: '%s': %v", str, err)
1324 }
1324 - mask := len(ip) * 8
1325 - m.cidrs = append(m.cidrs, &net.IPNet{
1326 - IP: ip,
1327 - Mask: net.CIDRMask(mask, mask),
1328 - })
1325 + ipNew := netip.PrefixFrom(ipAddr, ipAddr.BitLen())
1326 + m.cidrs = append(m.cidrs, &ipNew)
1327 }
1328 }
1329 return nil
1330 }
1331
1334 -func (m MatchRemoteIP) getClientIP(r *http.Request) (net.IP, string, error) {
1332 +func (m MatchRemoteIP) getClientIP(r *http.Request) (netip.Addr, string, error) {
1333 remote := r.RemoteAddr
1334 zoneID := ""
1335 if m.Forwarded {
@@ -1350,11 +1348,11 @@ func (m MatchRemoteIP) getClientIP(r *http.Request) (net.IP, string, error) {
1348 ipStr = split[0]
1349 zoneID = split[1]
1350 }
1353 - ip := net.ParseIP(ipStr)
1354 - if ip == nil {
1355 - return nil, zoneID, fmt.Errorf("invalid client IP address: %s", ipStr)
1351 + ipAddr, err := netip.ParseAddr(ipStr)
1352 + if err != nil {
1353 + return netip.IPv4Unspecified(), "", err
1354 }
1357 - return ip, zoneID, nil
1355 + return ipAddr, zoneID, nil
1356 }
1357
1358 // Match returns true if r matches m.
modules/caddyhttp/reverseproxy/reverseproxy.go
+13 -18
@@ -24,6 +24,7 @@ import (
24 "net"
25 "net/http"
26 "net/http/httptrace"
27 + "net/netip"
28 "net/textproto"
29 "net/url"
30 "regexp"
@@ -180,7 +181,7 @@ type Handler struct {
181 DynamicUpstreams UpstreamSource `json:"-"`
182
183 // Holds the parsed CIDR ranges from TrustedProxies
183 - trustedProxies []*net.IPNet
184 + trustedProxies []netip.Prefix
185
186 // Holds the named response matchers from the Caddyfile while adapting
187 responseMatchers map[string]caddyhttp.ResponseMatcher
@@ -251,24 +252,18 @@ func (h *Handler) Provision(ctx caddy.Context) error {
252 // parse trusted proxy CIDRs ahead of time
253 for _, str := range h.TrustedProxies {
254 if strings.Contains(str, "/") {
254 - _, ipNet, err := net.ParseCIDR(str)
255 + ipNet, err := netip.ParsePrefix(str)
256 if err != nil {
256 - return fmt.Errorf("parsing CIDR expression: %v", err)
257 + return fmt.Errorf("parsing CIDR expression: '%s': %v", str, err)
258 }
259 h.trustedProxies = append(h.trustedProxies, ipNet)
260 } else {
260 - ip := net.ParseIP(str)
261 - if ip == nil {
262 - return fmt.Errorf("invalid IP address: %s", str)
263 - }
264 - if ipv4 := ip.To4(); ipv4 != nil {
265 - ip = ipv4
261 + ipAddr, err := netip.ParseAddr(str)
262 + if err != nil {
263 + return fmt.Errorf("invalid IP address: '%s': %v", str, err)
264 }
267 - mask := len(ip) * 8
268 - h.trustedProxies = append(h.trustedProxies, &net.IPNet{
269 - IP: ip,
270 - Mask: net.CIDRMask(mask, mask),
271 - })
265 + ipNew := netip.PrefixFrom(ipAddr, ipAddr.BitLen())
266 + h.trustedProxies = append(h.trustedProxies, ipNew)
267 }
268 }
269
@@ -672,15 +667,15 @@ func (h Handler) addForwardedHeaders(req *http.Request) error {
667 if before, _, found := strings.Cut(clientIP, "%"); found {
668 clientIP = before
669 }
675 - ip := net.ParseIP(clientIP)
676 - if ip == nil {
677 - return fmt.Errorf("invalid client IP address: %s", clientIP)
670 + ipAddr, err := netip.ParseAddr(clientIP)
671 + if err != nil {
672 + return fmt.Errorf("invalid IP address: '%s': %v", clientIP, err)
673 }
674
675 // Check if the client is a trusted proxy
676 trusted := false
677 for _, ipRange := range h.trustedProxies {
683 - if ipRange.Contains(ip) {
678 + if ipRange.Contains(ipAddr) {
679 trusted = true
680 break
681 }
modules/caddytls/matchers.go
+16 -18
@@ -18,6 +18,7 @@ import (
18 "crypto/tls"
19 "fmt"
20 "net"
21 + "net/netip"
22 "strings"
23
24 "github.com/caddyserver/caddy/v2"
@@ -65,8 +66,8 @@ type MatchRemoteIP struct {
66 // The IPs or CIDR ranges to *NOT* match.
67 NotRanges []string `json:"not_ranges,omitempty"`
68
68 - cidrs []*net.IPNet
69 - notCidrs []*net.IPNet
69 + cidrs []netip.Prefix
70 + notCidrs []netip.Prefix
71 logger *zap.Logger
72 }
73
@@ -105,38 +106,35 @@ func (m MatchRemoteIP) Match(hello *tls.ClientHelloInfo) bool {
106 if err != nil {
107 ipStr = remoteAddr // weird; maybe no port?
108 }
108 - ip := net.ParseIP(ipStr)
109 - if ip == nil {
109 + ipAddr, err := netip.ParseAddr(ipStr)
110 + if err != nil {
111 m.logger.Error("invalid client IP addresss", zap.String("ip", ipStr))
112 return false
113 }
113 - return (len(m.cidrs) == 0 || m.matches(ip, m.cidrs)) &&
114 - (len(m.notCidrs) == 0 || !m.matches(ip, m.notCidrs))
114 + return (len(m.cidrs) == 0 || m.matches(ipAddr, m.cidrs)) &&
115 + (len(m.notCidrs) == 0 || !m.matches(ipAddr, m.notCidrs))
116 }
117
117 -func (MatchRemoteIP) parseIPRange(str string) ([]*net.IPNet, error) {
118 - var cidrs []*net.IPNet
118 +func (MatchRemoteIP) parseIPRange(str string) ([]netip.Prefix, error) {
119 + var cidrs []netip.Prefix
120 if strings.Contains(str, "/") {
120 - _, ipNet, err := net.ParseCIDR(str)
121 + ipNet, err := netip.ParsePrefix(str)
122 if err != nil {
123 return nil, fmt.Errorf("parsing CIDR expression: %v", err)
124 }
125 cidrs = append(cidrs, ipNet)
126 } else {
126 - ip := net.ParseIP(str)
127 - if ip == nil {
128 - return nil, fmt.Errorf("invalid IP address: %s", str)
127 + ipAddr, err := netip.ParseAddr(str)
128 + if err != nil {
129 + return nil, fmt.Errorf("invalid IP address: '%s': %v", str, err)
130 }
130 - mask := len(ip) * 8
131 - cidrs = append(cidrs, &net.IPNet{
132 - IP: ip,
133 - Mask: net.CIDRMask(mask, mask),
134 - })
131 + ip := netip.PrefixFrom(ipAddr, ipAddr.BitLen())
132 + cidrs = append(cidrs, ip)
133 }
134 return cidrs, nil
135 }
136
139 -func (MatchRemoteIP) matches(ip net.IP, ranges []*net.IPNet) bool {
137 +func (MatchRemoteIP) matches(ip netip.Addr, ranges []netip.Prefix) bool {
138 for _, ipRange := range ranges {
139 if ipRange.Contains(ip) {
140 return true