Browse code

daemon/config: make DNSConfig.DNS a netip.Addr

Modernize the field and allow using it as-is in some places, or
convert it to a string (which won't produce an error down the line).

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>

Sebastiaan van Stijn authored on 2025/08/02 01:27:42
Showing 9 changed files
... ...
@@ -45,7 +45,7 @@ func installCommonConfigFlags(conf *config.Config, flags *pflag.FlagSet) {
45 45
 	_ = flags.MarkHidden("network-diagnostic-port")
46 46
 
47 47
 	flags.BoolVar(&conf.RawLogs, "raw-logs", false, "Full timestamps without ANSI coloring")
48
-	flags.IPSliceVar(&conf.DNS, "dns", conf.DNS, "DNS server to use")
48
+	flags.Var(dopts.NewNamedIPListOptsRef("dns", &conf.DNS), "dns", "DNS server to use")
49 49
 	flags.Var(opts.NewNamedListOptsRef("dns-opts", &conf.DNSOptions, nil), "dns-opt", "DNS options to use")
50 50
 	flags.Var(opts.NewListOptsRef(&conf.DNSSearch, opts.ValidateDNSSearch), "dns-search", "DNS search domains to use")
51 51
 	flags.Var(dopts.NewNamedIPListOptsRef("host-gateway-ips", &conf.HostGatewayIPs), "host-gateway-ip", "IP addresses that the special 'host-gateway' string in --add-host resolves to. Defaults to the IP addresses of the default bridge")
... ...
@@ -170,7 +170,7 @@ type TLSOptions struct {
170 170
 
171 171
 // DNSConfig defines the DNS configurations.
172 172
 type DNSConfig struct {
173
-	DNS            []net.IP     `json:"dns,omitempty"`
173
+	DNS            []netip.Addr `json:"dns,omitempty"`
174 174
 	DNSOptions     []string     `json:"dns-opts,omitempty"`
175 175
 	DNSSearch      []string     `json:"dns-search,omitempty"`
176 176
 	HostGatewayIP  net.IP       `json:"host-gateway-ip,omitempty"` // Deprecated: this single-IP is migrated to HostGatewayIPs
... ...
@@ -658,12 +658,12 @@ func TestConfigInvalidDNS(t *testing.T) {
658 658
 		{
659 659
 			doc:         "single DNS, invalid IP-address",
660 660
 			input:       `{"dns": ["1.1.1.1o"]}`,
661
-			expectedErr: `invalid IP address: 1.1.1.1o`,
661
+			expectedErr: `ParseAddr("1.1.1.1o"): unexpected character (at "o")`,
662 662
 		},
663 663
 		{
664 664
 			doc:         "multiple DNS, invalid IP-address",
665 665
 			input:       `{"dns": ["2.2.2.2", "1.1.1.1o"]}`,
666
-			expectedErr: `invalid IP address: 1.1.1.1o`,
666
+			expectedErr: `ParseAddr("1.1.1.1o"): unexpected character (at "o")`,
667 667
 		},
668 668
 	}
669 669
 
... ...
@@ -671,7 +671,7 @@ func TestConfigInvalidDNS(t *testing.T) {
671 671
 		t.Run(tc.doc, func(t *testing.T) {
672 672
 			var cfg Config
673 673
 			err := json.Unmarshal([]byte(tc.input), &cfg)
674
-			assert.Check(t, is.Error(err, tc.expectedErr))
674
+			assert.Check(t, is.Error(err, tc.expectedErr), "type: %T", err)
675 675
 		})
676 676
 	}
677 677
 }
... ...
@@ -5,6 +5,7 @@ import (
5 5
 	"errors"
6 6
 	"fmt"
7 7
 	"net"
8
+	"net/netip"
8 9
 	"os"
9 10
 	"runtime"
10 11
 	"strings"
... ...
@@ -36,12 +37,16 @@ import (
36 36
 
37 37
 const errSetupNetworking = "failed to set up container networking"
38 38
 
39
-func ipAddresses(ips []net.IP) []string {
40
-	var addrs []string
41
-	for _, ip := range ips {
42
-		addrs = append(addrs, ip.String())
39
+func toNetIP(ips []string) ([]netip.Addr, error) {
40
+	var dnsAddrs []netip.Addr
41
+	for _, ns := range ips {
42
+		addr, err := netip.ParseAddr(ns)
43
+		if err != nil {
44
+			return nil, fmt.Errorf("bad nameserver address %s: %w", ns, err)
45
+		}
46
+		dnsAddrs = append(dnsAddrs, addr)
43 47
 	}
44
-	return addrs
48
+	return dnsAddrs, nil
45 49
 }
46 50
 
47 51
 func buildSandboxOptions(cfg *config.Config, ctr *container.Container) ([]libnetwork.SandboxOption, error) {
... ...
@@ -62,9 +67,13 @@ func buildSandboxOptions(cfg *config.Config, ctr *container.Container) ([]libnet
62 62
 	}
63 63
 
64 64
 	if len(ctr.HostConfig.DNS) > 0 {
65
-		sboxOptions = append(sboxOptions, libnetwork.OptionDNS(ctr.HostConfig.DNS))
65
+		dnsAddrs, err := toNetIP(ctr.HostConfig.DNS)
66
+		if err != nil {
67
+			return nil, err
68
+		}
69
+		sboxOptions = append(sboxOptions, libnetwork.OptionDNS(dnsAddrs))
66 70
 	} else if len(cfg.DNS) > 0 {
67
-		sboxOptions = append(sboxOptions, libnetwork.OptionDNS(ipAddresses(cfg.DNS)))
71
+		sboxOptions = append(sboxOptions, libnetwork.OptionDNS(cfg.DNS))
68 72
 	}
69 73
 	if len(ctr.HostConfig.DNSSearch) > 0 {
70 74
 		sboxOptions = append(sboxOptions, libnetwork.OptionDNSSearch(ctr.HostConfig.DNSSearch))
... ...
@@ -711,7 +720,7 @@ func (daemon *Daemon) connectToNetwork(ctx context.Context, cfg *config.Config,
711 711
 		return err
712 712
 	}
713 713
 
714
-	createOptions, err := buildCreateEndpointOptions(ctr, n, endpointConfig, sb, ipAddresses(cfg.DNS))
714
+	createOptions, err := buildCreateEndpointOptions(ctr, n, endpointConfig, sb, cfg.DNS)
715 715
 	if err != nil {
716 716
 		return err
717 717
 	}
... ...
@@ -2,7 +2,7 @@ package buildkit
2 2
 
3 3
 import (
4 4
 	"context"
5
-	"net"
5
+	"net/netip"
6 6
 	"os"
7 7
 	"path/filepath"
8 8
 	"sync"
... ...
@@ -110,7 +110,7 @@ func getDNSConfig(cfg config.DNSConfig) *oci.DNSConfig {
110 110
 	return nil
111 111
 }
112 112
 
113
-func ipAddresses(ips []net.IP) []string {
113
+func ipAddresses(ips []netip.Addr) []string {
114 114
 	var addrs []string
115 115
 	for _, ip := range ips {
116 116
 		addrs = append(addrs, ip.String())
... ...
@@ -5,6 +5,7 @@ import (
5 5
 	"encoding/json"
6 6
 	"fmt"
7 7
 	"net"
8
+	"net/netip"
8 9
 	"slices"
9 10
 	"sort"
10 11
 	"strings"
... ...
@@ -80,7 +81,7 @@ type resolvConfPathConfig struct {
80 80
 	resolvConfPath       string
81 81
 	originResolvConfPath string
82 82
 	resolvConfHashFile   string
83
-	dnsList              []string
83
+	dnsList              []netip.Addr
84 84
 	dnsSearchList        []string
85 85
 	dnsOptionsList       []string
86 86
 }
... ...
@@ -254,15 +254,7 @@ func (sb *Sandbox) loadResolvConf(path string) (*resolvconf.ResolvConf, error) {
254 254
 # This file can be edited; Docker Engine will not make further changes once it
255 255
 # has been modified.`)
256 256
 	if len(sb.config.dnsList) > 0 {
257
-		var dnsAddrs []netip.Addr
258
-		for _, ns := range sb.config.dnsList {
259
-			addr, err := netip.ParseAddr(ns)
260
-			if err != nil {
261
-				return nil, errors.Wrapf(err, "bad nameserver address %s", ns)
262
-			}
263
-			dnsAddrs = append(dnsAddrs, addr)
264
-		}
265
-		rc.OverrideNameServers(dnsAddrs)
257
+		rc.OverrideNameServers(sb.config.dnsList)
266 258
 	}
267 259
 	if len(sb.config.dnsSearchList) > 0 {
268 260
 		rc.OverrideSearch(sb.config.dnsSearchList)
... ...
@@ -1,6 +1,8 @@
1 1
 package libnetwork
2 2
 
3 3
 import (
4
+	"net/netip"
5
+
4 6
 	"github.com/moby/moby/v2/daemon/libnetwork/netlabel"
5 7
 	"github.com/moby/moby/v2/daemon/libnetwork/osl"
6 8
 	"github.com/moby/moby/v2/daemon/libnetwork/types"
... ...
@@ -64,7 +66,7 @@ func OptionOriginResolvConfPath(path string) SandboxOption {
64 64
 
65 65
 // OptionDNS function returns an option setter for dns entry option to
66 66
 // be passed to container Create method.
67
-func OptionDNS(dns []string) SandboxOption {
67
+func OptionDNS(dns []netip.Addr) SandboxOption {
68 68
 	return func(sb *Sandbox) {
69 69
 		sb.config.dnsList = dns
70 70
 	}
... ...
@@ -5,6 +5,7 @@ import (
5 5
 	"errors"
6 6
 	"fmt"
7 7
 	"net"
8
+	"net/netip"
8 9
 	"sort"
9 10
 	"strconv"
10 11
 	"strings"
... ...
@@ -831,7 +832,7 @@ func (daemon *Daemon) clearAttachableNetworks() {
831 831
 }
832 832
 
833 833
 // buildCreateEndpointOptions builds endpoint options from a given network.
834
-func buildCreateEndpointOptions(c *container.Container, n *libnetwork.Network, epConfig *network.EndpointSettings, sb *libnetwork.Sandbox, daemonDNS []string) ([]libnetwork.EndpointOption, error) {
834
+func buildCreateEndpointOptions(c *container.Container, n *libnetwork.Network, epConfig *network.EndpointSettings, sb *libnetwork.Sandbox, daemonDNS []netip.Addr) ([]libnetwork.EndpointOption, error) {
835 835
 	var createOptions []libnetwork.EndpointOption
836 836
 	genericOptions := make(options.Generic)
837 837
 
... ...
@@ -914,7 +915,11 @@ func buildCreateEndpointOptions(c *container.Container, n *libnetwork.Network, e
914 914
 		if len(c.HostConfig.DNS) > 0 {
915 915
 			createOptions = append(createOptions, libnetwork.CreateOptionDNS(c.HostConfig.DNS))
916 916
 		} else if len(daemonDNS) > 0 {
917
-			createOptions = append(createOptions, libnetwork.CreateOptionDNS(daemonDNS))
917
+			dns := make([]string, len(daemonDNS))
918
+			for i, a := range daemonDNS {
919
+				dns[i] = a.String()
920
+			}
921
+			createOptions = append(createOptions, libnetwork.CreateOptionDNS(dns))
918 922
 		}
919 923
 	}
920 924