dns icon indicating copy to clipboard operation
dns copied to clipboard

dns.RR - JSON Unmarshal

Open Neo-Desktop opened this issue 7 years ago • 11 comments

Hello!

I'm attempting to populate record data from JSON. Marshaling RRs -to- JSON has been handled by the language already. Unmarshaling back to the requisite resource types is another matter entirely.

I believe this functionality is best handled by the package owner where it can be available to all.

Please implement the Unmarshaler interface for dns.RR()

Many Thanks!

Neo-Desktop avatar Mar 19 '18 10:03 Neo-Desktop

[ Quoting [email protected] in "[miekg/dns] dns.RR - JSON Unmarshal..." ]

Hello!

I'm attempting to populate record data from JSON. Marshaling RRs -to- JSON has been handled by the language already. Unmarshaling back to the requisite resource types is another matter entirely.

I believe this functionality is best handled by the package owner where it can be available to all.

Please implement the Unmarshaler interface for dns.RR()

Where is this interface defined?

The various Pack/Unpack methods are available for this.

miekg avatar Mar 19 '18 10:03 miekg

Where is this interface defined?

https://github.com/miekg/dns/blob/master/dns.go#L28 I'm referencing the generic RR interface which indeed does implement a pack() function Unfortunately, this doesn't do any good when storing data as a JSON object i.e. calling json.Marshal() or json.Unmarshal() on a dns.RR{}

I would like to store records as JSON due to its ubiquity and nearly every programming language can manipulate it with ease, unlike RFC 3597

Neo-Desktop avatar Mar 19 '18 11:03 Neo-Desktop

[ Quoting [email protected] in "Re: [miekg/dns] dns.RR - JSON Unmar..." ]

Where is this interface defined?

https://github.com/miekg/dns/blob/master/dns.go#L28 I'm referencing the generic RR interface which indeed does implement a pack() function Unfortunately, this doesn't do any good when storing data as a JSON object i.e. calling json.Marshal() or json.Unmarshal() on a dns.RR{}

I would like to store records as JSON due to its ubiquity and nearly every programming language can manipulate it with ease, unlike RFC 3597

You're going to have a hard time doing that, because json is not a good fit for DNS data, see https://miek.nl/2017/november/17/switching-to-vodafone-uncovered-a-bug/ for a fun bug.

What do you want to store the binary or some kind of text representation?

Even so this library is not a good place for having json marshal functions.

/Miek

-- Miek Gieben

miekg avatar Mar 19 '18 11:03 miekg

What do you want to store the binary or some kind of text representation? I'm attempting to use JSON as a common interchange format

Clearly, Google is using it already, it's unfortunate that the embedded quotes are being stripped somewhere along the lines.

To clarify: I would like to store the JSON representation of a master zone in something like a redis/mongo/some NoSQL backend.

It would be invaluable to turn the JSON representation of a Resource Record, as defined by the package's dns.RR{} interface, back into the corresponding object type. (probably like switching on Hdr.Rrtype)

Running:

package main

import (
	"encoding/json"
	"fmt"
	"log"
	"strings"

	"github.com/coredns/coredns/plugin/file"
)

func main() {

	zone, err := file.Parse(strings.NewReader(ZONEFILE), "neo.yt.", "stdin", 0)
	if err != nil {
		log.Println("Error encountered during Parse")
		log.Fatal(err)
	}

	output, err := json.Marshal(zone.All())
	if err != nil {
		log.Println("Error encountered during Marshal")
		log.Fatal(err)
	}

	fmt.Println(string(output))
}

const ZONEFILE = `
; neo.yt Dumped Mon Mar 19 04:23:10 2018
;
neo.yt. 86400   IN  SOA ns1.he.net. hostmaster.he.net. (
                    2018022702  ;serial
                    10800       ;refresh
                    1800        ;retry
                    604800      ;expire
                    86400   )   ;minimum
neo.yt. 300 IN  A   104.168.144.17
neo.yt. 300 IN  AAAA    2001:470:8269::1
`

already correctly yields

[{
	"Hdr": {
		"Name": "neo.yt.",
		"Rrtype": 6,
		"Class": 1,
		"Ttl": 86400,
		"Rdlength": 0
	},
	"Ns": "ns1.he.net.",
	"Mbox": "hostmaster.he.net.",
	"Serial": 2018022702,
	"Refresh": 10800,
	"Retry": 1800,
	"Expire": 604800,
	"Minttl": 86400
}, {
	"Hdr": {
		"Name": "neo.yt.",
		"Rrtype": 1,
		"Class": 1,
		"Ttl": 300,
		"Rdlength": 0
	},
	"A": "104.168.144.17"
}, {
	"Hdr": {
		"Name": "neo.yt.",
		"Rrtype": 28,
		"Class": 1,
		"Ttl": 300,
		"Rdlength": 0
	},
	"AAAA": "2001:470:8269::1"
}]

Turning the marshaled JSON representation as displayed above back into the dns.SOA and dns.A, etc... records respectively are what I'm asking to have implemented.

To clarify again, this "zone format" is really just a snapshot of the Go structures in use. Working directly with the underlying structures is the path of least resistance and will provide the greatest accuracy for anyone importing a zone via JSON for use with this library

Neo-Desktop avatar Mar 19 '18 11:03 Neo-Desktop

[ Quoting [email protected] in "Re: [miekg/dns] dns.RR - JSON Unmar..." ]

What do you want to store the binary or some kind of text representation? I'm attempting to use JSON as a common interchange format

Clearly, Google is using it already, it's unfortunate that the embedded quotes are being stripped somewhere along the lines.

To clarify: I would like to store the JSON representation of a master zone in something like a redis/mongo/some NoSQL backend.

It would be invaluable to turn the JSON representation of a Resource Record, as defined by the package's dns.RR{} interface, back into the corresponding object type. (probably like switching on Hdr.Rrtype)

Fair enough, but until the IETF comes out with an RFC describing how things should be encoded in json I'm not going to burn any cycles on it. Are NULL bytes allowed in json?

miekg avatar Mar 19 '18 13:03 miekg

Are NULL bytes allowed in json?

Yes, escaped \u0000 is always allowed, or simply a null object depending on what you're trying to do.

the JSON standard is available here http://www.json.org/

Neo-Desktop avatar Mar 19 '18 13:03 Neo-Desktop

Please see https://tools.ietf.org/html/rfc8427

miekg avatar Nov 28 '18 19:11 miekg

Just to make sure that I get it right:

Even so this library is not a good place for having json marshal functions.

There is not going to be a JSON marshaller built into this library?

  • Fair enough, but until the IETF comes out with an RFC describing how things should be encoded in json I'm not going to burn any cycles on it.
  • Please see https://tools.ietf.org/html/rfc8427

This RFC is still not mature enough (informational?) we need to wait for a proper standard?

yan-foto avatar Feb 08 '24 10:02 yan-foto

We make heavy use of this library and are looking to support RFC8427; having this support baked in would be a tremendous help.

llorllale avatar Jun 12 '24 22:06 llorllale

coming back to this, why not?

looks most of it can be generated, just like the rest. Depends a bit on how large the actually PR would be. But as RFC 8427 exists.... why not?

miekg avatar Jun 13 '24 14:06 miekg

In response to This RFC is still not mature enough (informational?) we need to wait for a proper standard?, it will never be a standard, for the reasons stated in the RFC itself. There are too many competing choices for a desired syntax for a particular program. The RFC was published so that someone like @miekg could pick and choose which parts they want for marshalling and/or unmarshalling, with no expectation of interoperability with other applications.

paulehoffman avatar Jun 13 '24 16:06 paulehoffman

coming back to this, I don't think we want json marshalling in this lib. The dns types 'n stuff is public (exported) enough, that you can go all-in in your own pkg

miekg avatar Feb 24 '25 14:02 miekg