Skip to content

Commit aeb39e7

Browse files
authored
Merge pull request #1104 from Nino-K/fix-unambiguous-host-to-ip
Convert built-in hosts to unambiguous domain names
2 parents 3de7635 + e78d91d commit aeb39e7

File tree

5 files changed

+84
-56
lines changed

5 files changed

+84
-56
lines changed

pkg/hostagent/dns/dns.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import (
88
"runtime"
99
"strings"
1010

11-
"github.com/lima-vm/lima/pkg/limayaml"
1211
"github.com/miekg/dns"
1312
"github.com/sirupsen/logrus"
1413
)
@@ -132,10 +131,11 @@ func NewHandler(opts HandlerOptions) (dns.Handler, error) {
132131
hostToIP: make(map[string]net.IP),
133132
}
134133
for host, address := range opts.StaticHosts {
134+
cname := dns.CanonicalName(host)
135135
if ip := net.ParseIP(address); ip != nil {
136-
h.hostToIP[host] = ip
136+
h.hostToIP[cname] = ip
137137
} else {
138-
h.cnameToHost[host] = limayaml.Cname(address)
138+
h.cnameToHost[cname] = dns.CanonicalName(address)
139139
}
140140
}
141141
return h, nil

pkg/hostagent/dns/dns_test.go

Lines changed: 71 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,7 @@ var (
1919
dnsResult *dns.Msg
2020
)
2121

22-
func TestTXTRecords(t *testing.T) {
23-
testDomains := make([]string, 3)
24-
testDomains[0] = "onerecord.com"
25-
testDomains[1] = "multistringrecord.com"
26-
testDomains[2] = "multiplerecords.com"
27-
28-
expectedResults := make([]string, 3)
29-
expectedResults[0] = `onerecord.com.\s+5\s+IN\s+TXT\s+"My txt record"`
30-
expectedResults[1] = `multistringrecord.com.\s+5\s+IN\s+TXT\s+"123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345" "67890123456789012345678901234567890"`
31-
expectedResults[2] = `multiplerecords.com.\s+5\s+IN\s+TXT\s+"record 1"\nmultiplerecords.com.\s*5\s*IN\s*TXT\s*"record 2"`
22+
func TestDNSRecords(t *testing.T) {
3223

3324
srv, _ := mockdns.NewServerWithLogger(map[string]mockdns.Zone{
3425
"onerecord.com.": {
@@ -52,33 +43,79 @@ func TestTXTRecords(t *testing.T) {
5243
}
5344
srv.PatchNet(net.DefaultResolver)
5445
defer mockdns.UnpatchNet(net.DefaultResolver)
46+
w := new(TestResponseWriter)
47+
options := HandlerOptions{
48+
IPv6: true,
49+
StaticHosts: map[string]string{
50+
"MY.DOMAIN.COM": "192.168.0.23",
51+
"host.lima.internal": "10.10.0.34",
52+
"my.host": "host.lima.internal",
53+
"default": "my.domain.com",
54+
},
55+
}
5556

57+
h, err := NewHandler(options)
58+
assert.NilError(t, err)
59+
60+
regexMatch := func(value string, pattern string) cmp.Comparison {
61+
return func() cmp.Result {
62+
re := regexp.MustCompile(pattern)
63+
if re.MatchString(value) {
64+
return cmp.ResultSuccess
65+
}
66+
return cmp.ResultFailure(
67+
fmt.Sprintf("%q did not match pattern %q", value, pattern))
68+
}
69+
}
5670
t.Run("test TXT records", func(t *testing.T) {
57-
w := new(TestResponseWriter)
58-
options := HandlerOptions{
59-
IPv6: true,
60-
StaticHosts: map[string]string{
61-
"MY.Host": "host.lima.internal",
62-
},
71+
tests := []struct {
72+
testDomain string
73+
expectedTXTRecord string
74+
}{
75+
{testDomain: "onerecord.com", expectedTXTRecord: `onerecord.com.\s+5\s+IN\s+TXT\s+"My txt record"`},
76+
{testDomain: "multistringrecord.com", expectedTXTRecord: `multistringrecord.com.\s+5\s+IN\s+TXT\s+"123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345" "67890123456789012345678901234567890"`},
77+
{testDomain: "multiplerecords.com", expectedTXTRecord: `multiplerecords.com.\s+5\s+IN\s+TXT\s+"record 1"\nmultiplerecords.com.\s*5\s*IN\s*TXT\s*"record 2"`},
6378
}
64-
h, err := NewHandler(options)
65-
if err == nil {
66-
for i := 0; i < len(testDomains); i++ {
67-
req := new(dns.Msg)
68-
req.SetQuestion(dns.Fqdn(testDomains[i]), dns.TypeTXT)
69-
h.ServeDNS(w, req)
70-
regexMatch := func(value string, pattern string) cmp.Comparison {
71-
return func() cmp.Result {
72-
re := regexp.MustCompile(pattern)
73-
if re.MatchString(value) {
74-
return cmp.ResultSuccess
75-
}
76-
return cmp.ResultFailure(
77-
fmt.Sprintf("%q did not match pattern %q", value, pattern))
78-
}
79-
}
80-
assert.Assert(t, regexMatch(dnsResult.String(), expectedResults[i]))
81-
}
79+
80+
for _, tc := range tests {
81+
req := new(dns.Msg)
82+
req.SetQuestion(dns.Fqdn(tc.testDomain), dns.TypeTXT)
83+
h.ServeDNS(w, req)
84+
assert.Assert(t, regexMatch(dnsResult.String(), tc.expectedTXTRecord))
85+
}
86+
})
87+
88+
t.Run("test A records", func(t *testing.T) {
89+
tests := []struct {
90+
testDomain string
91+
expectedARecord string
92+
}{
93+
{testDomain: "my.domain.com", expectedARecord: `my.domain.com.\s+5\s+IN\s+A\s+192.168.0.23`},
94+
{testDomain: "host.lima.internal", expectedARecord: `host.lima.internal.\s+5\s+IN\s+A\s+10.10.0.34`},
95+
}
96+
97+
for _, tc := range tests {
98+
req := new(dns.Msg)
99+
req.SetQuestion(dns.Fqdn(tc.testDomain), dns.TypeA)
100+
h.ServeDNS(w, req)
101+
assert.Assert(t, regexMatch(dnsResult.String(), tc.expectedARecord))
102+
}
103+
})
104+
105+
t.Run("test CNAME records", func(t *testing.T) {
106+
tests := []struct {
107+
testDomain string
108+
expectedCNAME string
109+
}{
110+
{testDomain: "my.host", expectedCNAME: `my.host.\s+5\s+IN\s+CNAME\s+host.lima.internal.`},
111+
{testDomain: "default", expectedCNAME: `default.\s+5\s+IN\s+CNAME\s+my.domain.com.`},
112+
}
113+
114+
for _, tc := range tests {
115+
req := new(dns.Msg)
116+
req.SetQuestion(dns.Fqdn(tc.testDomain), dns.TypeCNAME)
117+
h.ServeDNS(w, req)
118+
assert.Assert(t, regexMatch(dnsResult.String(), tc.expectedCNAME))
82119
}
83120
})
84121
}

pkg/hostagent/hostagent.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -307,8 +307,8 @@ func (a *HostAgent) Run(ctx context.Context) error {
307307

308308
if *a.y.HostResolver.Enabled {
309309
hosts := a.y.HostResolver.Hosts
310-
hosts["host.lima.internal."] = qemuconst.SlirpGateway
311-
hosts[fmt.Sprintf("lima-%s.", a.instName)] = qemuconst.SlirpIPAddress
310+
hosts["host.lima.internal"] = qemuconst.SlirpGateway
311+
hosts[fmt.Sprintf("lima-%s", a.instName)] = qemuconst.SlirpIPAddress
312312
srvOpts := dns.ServerOptions{
313313
UDPPort: a.udpDNSLocalPort,
314314
TCPPort: a.tcpDNSLocalPort,

pkg/limayaml/defaults.go

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import (
99
"path/filepath"
1010
"runtime"
1111
"strconv"
12-
"strings"
1312
"text/template"
1413

1514
"github.com/lima-vm/lima/pkg/guestagent/api"
@@ -233,13 +232,13 @@ func FillDefault(y, d, o *LimaYAML, filePath string) {
233232
hosts := make(map[string]string)
234233
// Values can be either names or IP addresses. Name values are canonicalized in the hostResolver.
235234
for k, v := range d.HostResolver.Hosts {
236-
hosts[Cname(k)] = v
235+
hosts[k] = v
237236
}
238237
for k, v := range y.HostResolver.Hosts {
239-
hosts[Cname(k)] = v
238+
hosts[k] = v
240239
}
241240
for k, v := range o.HostResolver.Hosts {
242-
hosts[Cname(k)] = v
241+
hosts[k] = v
243242
}
244243
y.HostResolver.Hosts = hosts
245244

@@ -667,14 +666,6 @@ func IsNativeArch(arch Arch) bool {
667666
return nativeX8664 || nativeAARCH64 || nativeRISCV64
668667
}
669668

670-
func Cname(host string) string {
671-
host = strings.ToLower(host)
672-
if !strings.HasSuffix(host, ".") {
673-
host += "."
674-
}
675-
return host
676-
}
677-
678669
func unique(s []string) []string {
679670
keys := make(map[string]bool)
680671
list := []string{}

pkg/limayaml/defaults_test.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ func TestFillDefault(t *testing.T) {
149149

150150
expect := builtin
151151
expect.HostResolver.Hosts = map[string]string{
152-
"my.host.": "host.lima.internal",
152+
"MY.Host": "host.lima.internal",
153153
}
154154

155155
expect.Mounts = y.Mounts
@@ -319,7 +319,7 @@ func TestFillDefault(t *testing.T) {
319319
expect.Mounts[0].NineP.Msize = pointer.String(Default9pMsize)
320320
expect.Mounts[0].NineP.Cache = pointer.String(Default9pCacheForRO)
321321
expect.HostResolver.Hosts = map[string]string{
322-
"default.": d.HostResolver.Hosts["default"],
322+
"default": d.HostResolver.Hosts["default"],
323323
}
324324
expect.MountType = pointer.String(REVSSHFS)
325325
expect.CACertificates.RemoveDefaults = pointer.Bool(true)
@@ -348,7 +348,7 @@ func TestFillDefault(t *testing.T) {
348348
expect.Mounts = append(d.Mounts, y.Mounts...)
349349
expect.Networks = append(d.Networks, y.Networks...)
350350

351-
expect.HostResolver.Hosts["default."] = d.HostResolver.Hosts["default"]
351+
expect.HostResolver.Hosts["default"] = d.HostResolver.Hosts["default"]
352352

353353
// d.DNS will be ignored, and not appended to y.DNS
354354

@@ -474,8 +474,8 @@ func TestFillDefault(t *testing.T) {
474474
expect.PortForwards = append(append(o.PortForwards, y.PortForwards...), d.PortForwards...)
475475
expect.Containerd.Archives = append(append(o.Containerd.Archives, y.Containerd.Archives...), d.Containerd.Archives...)
476476

477-
expect.HostResolver.Hosts["default."] = d.HostResolver.Hosts["default"]
478-
expect.HostResolver.Hosts["my.host."] = d.HostResolver.Hosts["host.lima.internal"]
477+
expect.HostResolver.Hosts["default"] = d.HostResolver.Hosts["default"]
478+
expect.HostResolver.Hosts["MY.Host"] = d.HostResolver.Hosts["host.lima.internal"]
479479

480480
// o.Mounts just makes d.Mounts[0] writable because the Location matches
481481
expect.Mounts = append(d.Mounts, y.Mounts...)

0 commit comments

Comments
 (0)