dns: Unable to parse AAAA record with IPv4 IP

Some DNS servers respond with AAAA records that contain IPv4 addresses. This is not too unusual, and dns.UnpackRR works correctly on these records.

However, if this dns library receives one of these packets, unpacks it into a RR, and converts it to its string representation, it is unable to parse it back again.

The way to encode these addresses is to prefix them with ::ffff: so 192.168.1.1 would become ::ffff:192.168.1.1 RFC: https://tools.ietf.org/html/rfc4291#section-2.2

I would suggest treating AAAA records that contain IPv4 addresses as IPv4 addresses in IPv6 notation like the above example, instead of erroring.

Below is a example to demo this behavior with a real record I’ve come across:

package main

import (
	"encoding/hex"
	"log"

	"github.com/miekg/dns"
)

var rrHex = "036e733104696c706d026d7900001c000100015180001000000000000000000000ffff6e042d04"

/* rrHex is equivalent to:
rr := &dns.AAAA{
	Hdr: dns.RR_Header{
		Name:   "ns1.ilpm.my.",
		Rrtype: dns.TypeAAAA,
		Class:  dns.ClassINET,
		Ttl:    86400,
		Rdlength: 16,
	},
	AAAA: net.ParseIP("110.4.45.4"),
} */

func main() {
	log.Printf("Hex: %s", rrHex)
	rrBytes, err := hex.DecodeString(rrHex)
	if err != nil {
		log.Fatal(err)
	}
	rr, _, err := dns.UnpackRR(rrBytes, 0)
	if err != nil {
		log.Fatal(err)
	}
	rrString := rr.String()
	log.Printf("Parsed RR: %s", rrString)

	rr2, err := dns.NewRR(rrString)
	if err != nil { // err: dns: bad AAAA AAAA: "110.4.45.4" at line: 1:37
		log.Fatal(err)
	}
	log.Printf("Parsed RR from string: %s", rr2.String())
}

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 20 (3 by maintainers)

Commits related to this issue

Most upvoted comments

The textual representation of the data portion of the AAAA resource record is defined by RFC 3596 as “the textual representation of an IPv6 address as defined in [RFC 3513]”. RFC 3513 was obsoleted by RFC 4291, but the relevant “Text Representation of Addresses” section had no relevant changes.

::ffff:110.4.45.4 is a valid textual represenation of AAAA RDATA; 110.4.45.4 is not.

@lanrat I hadn’t seen that. I suppose things can get overlooked pretty easily. I’ll leave it closed for now and see what @miekg thinks.