mirror of
https://github.com/cunnie/sslip.io.git
synced 2025-10-27 01:20:32 +08:00
DNS server: allow returning _multiple_ AAAA records
Previously the DNS server only returned the first AAAA record of a customized domain; now it will return all the AAAA records.
This commit is contained in:
@@ -204,13 +204,10 @@ func processQuestion(q dnsmessage.Question, b *dnsmessage.Builder) (logMessage s
|
|||||||
}
|
}
|
||||||
case dnsmessage.TypeAAAA:
|
case dnsmessage.TypeAAAA:
|
||||||
{
|
{
|
||||||
var nameToAAAA *dnsmessage.AAAAResource
|
var nameToAAAAs []dnsmessage.AAAAResource
|
||||||
nameToAAAA, err = NameToAAAA(q.Name.String())
|
nameToAAAAs, err = NameToAAAA(q.Name.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// There's only one possible error this can be: ErrNotFound. note that
|
// There's only one possible error this can be: ErrNotFound
|
||||||
// this could be written more efficiently; however, I wrote it to
|
|
||||||
// accommodate 'if err != nil' convention. My first version was 'if
|
|
||||||
// err == nil', and it flummoxed me.
|
|
||||||
err = noAnswersOnlyAuthorities(q, b, &logMessage)
|
err = noAnswersOnlyAuthorities(q, b, &logMessage)
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
@@ -218,18 +215,22 @@ func processQuestion(q dnsmessage.Question, b *dnsmessage.Builder) (logMessage s
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = b.AAAAResource(dnsmessage.ResourceHeader{
|
var logMessages []string
|
||||||
Name: q.Name,
|
for _, nameToAAAA := range nameToAAAAs {
|
||||||
Type: dnsmessage.TypeAAAA,
|
err = b.AAAAResource(dnsmessage.ResourceHeader{
|
||||||
Class: dnsmessage.ClassINET,
|
Name: q.Name,
|
||||||
TTL: 604800, // 60 * 60 * 24 * 7 == 1 week; long TTL, these IP addrs don't change
|
Type: dnsmessage.TypeAAAA,
|
||||||
Length: 0,
|
Class: dnsmessage.ClassINET,
|
||||||
}, *nameToAAAA)
|
TTL: 604800, // 60 * 60 * 24 * 7 == 1 week; long TTL, these IP addrs don't change
|
||||||
if err != nil {
|
Length: 0,
|
||||||
return
|
}, nameToAAAA)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ip := net.IP(nameToAAAA.AAAA[:])
|
||||||
|
logMessages = append(logMessages, ip.String())
|
||||||
}
|
}
|
||||||
ip := net.IP(nameToAAAA.AAAA[:])
|
logMessage += strings.Join(logMessages, ", ")
|
||||||
logMessage += ip.String()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case dnsmessage.TypeALL:
|
case dnsmessage.TypeALL:
|
||||||
@@ -383,14 +384,14 @@ func NameToA(fqdnString string) (*dnsmessage.AResource, error) {
|
|||||||
|
|
||||||
// NameToAAAA NameToA returns either an AAAAResource that matched the hostname
|
// NameToAAAA NameToA returns either an AAAAResource that matched the hostname
|
||||||
// or ErrNotFound
|
// or ErrNotFound
|
||||||
func NameToAAAA(fqdnString string) (*dnsmessage.AAAAResource, error) {
|
func NameToAAAA(fqdnString string) ([]dnsmessage.AAAAResource, error) {
|
||||||
fqdn := []byte(fqdnString)
|
fqdn := []byte(fqdnString)
|
||||||
// is it a customized AAAA record? If so, return early
|
// is it a customized AAAA record? If so, return early
|
||||||
if domain, ok := Customizations[fqdnString]; ok && len(domain.AAAA) > 0 {
|
if domain, ok := Customizations[fqdnString]; ok && len(domain.AAAA) > 0 {
|
||||||
return &domain.AAAA[0], nil // TODO: handle multiple AAAA records
|
return domain.AAAA, nil
|
||||||
}
|
}
|
||||||
if !ipv6RE.Match(fqdn) {
|
if !ipv6RE.Match(fqdn) {
|
||||||
return &dnsmessage.AAAAResource{}, ErrNotFound
|
return nil, ErrNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
ipv6RE.Longest()
|
ipv6RE.Longest()
|
||||||
@@ -402,7 +403,7 @@ func NameToAAAA(fqdnString string) (*dnsmessage.AAAAResource, error) {
|
|||||||
for i := range ipv16address {
|
for i := range ipv16address {
|
||||||
AAAAR.AAAA[i] = ipv16address[i]
|
AAAAR.AAAA[i] = ipv16address[i]
|
||||||
}
|
}
|
||||||
return &AAAAR, nil
|
return []dnsmessage.AAAAResource{AAAAR}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func NSResources() map[string]dnsmessage.NSResource {
|
func NSResources() map[string]dnsmessage.NSResource {
|
||||||
|
|||||||
@@ -406,9 +406,10 @@ var _ = Describe("Xip", func() {
|
|||||||
Describe("NameToAAAA()", func() {
|
Describe("NameToAAAA()", func() {
|
||||||
DescribeTable("when it succeeds",
|
DescribeTable("when it succeeds",
|
||||||
func(fqdn string, expectedAAAA dnsmessage.AAAAResource) {
|
func(fqdn string, expectedAAAA dnsmessage.AAAAResource) {
|
||||||
ipv6Answer, err := xip.NameToAAAA(fqdn)
|
ipv6Answers, err := xip.NameToAAAA(fqdn)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(*ipv6Answer).To(Equal(expectedAAAA))
|
Expect(len(ipv6Answers)).To(Equal(1))
|
||||||
|
Expect(ipv6Answers[0]).To(Equal(expectedAAAA))
|
||||||
},
|
},
|
||||||
// sslip.io website
|
// sslip.io website
|
||||||
Entry("sslip.io", "sslip.io.", xip.Customizations["sslip.io."].AAAA[0]),
|
Entry("sslip.io", "sslip.io.", xip.Customizations["sslip.io."].AAAA[0]),
|
||||||
@@ -439,12 +440,30 @@ var _ = Describe("Xip", func() {
|
|||||||
It("should succeed every time", func() {
|
It("should succeed every time", func() {
|
||||||
for i := 0; i < 1000; i++ {
|
for i := 0; i < 1000; i++ {
|
||||||
addr := randomIPv6Address()
|
addr := randomIPv6Address()
|
||||||
ipv6Answer, err := xip.NameToAAAA(strings.ReplaceAll(addr.String(), ":", "-"))
|
ipv6Answers, err := xip.NameToAAAA(strings.ReplaceAll(addr.String(), ":", "-"))
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(ipv6Answer.AAAA[:]).To(Equal([]uint8(addr)))
|
Expect(ipv6Answers[0].AAAA[:]).To(Equal([]uint8(addr)))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
When("There is more than one AAAA record", func() {
|
||||||
|
It("returns them all", func() {
|
||||||
|
fqdn := random8ByteString()
|
||||||
|
xip.Customizations[fqdn] = xip.DomainCustomization{
|
||||||
|
//copy(xip.Customizations[fqdn].AAAA, dnsmessage.AAAAResource)
|
||||||
|
AAAA: []dnsmessage.AAAAResource{
|
||||||
|
{AAAA: [16]byte{1}},
|
||||||
|
{AAAA: [16]byte{2}},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
ipv6Addrs, err := xip.NameToAAAA(fqdn)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(len(ipv6Addrs)).To(Equal(2))
|
||||||
|
Expect(ipv6Addrs[0].AAAA).To(Equal([16]byte{1}))
|
||||||
|
Expect(ipv6Addrs[1].AAAA).To(Equal([16]byte{2}))
|
||||||
|
delete(xip.Customizations, fqdn)
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -465,3 +484,13 @@ func randomIPv6Address() net.IP {
|
|||||||
}
|
}
|
||||||
return ipv6
|
return ipv6
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// random8ByteString() returns an 8-char string consisting solely of the letters a-z.
|
||||||
|
func random8ByteString() string {
|
||||||
|
var randomString []byte
|
||||||
|
for i := 0; i < 8; i++ {
|
||||||
|
// 97 == ascii 'a', and there are 26 letters in the alphabet
|
||||||
|
randomString = append(randomString, byte(97+rand.Intn(26)))
|
||||||
|
}
|
||||||
|
return string(randomString)
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user