1 % JSON Domain Format as Implemented by Pdns-Pipe-Nmc
3 This document is based on
4 [Namecoin Domain Name Specification](https://wiki.namecoin.info/index.php?title=Domain_Name_Specification).
5 It tries to follow it closely, and clarify parts that are not
6 specified, or specified ambiguously, in the original document.
8 One notable deviation is the specification of `"delegate"` and `"import"`
9 attributes: domain objects to which their value point are
10 replacing/merging to the domain object in which they are defined.
11 This seems to be in line with at least one existing "real world"
14 This specification is implemented by the `pdns-pipe-nmc` program.
20 `DomObj` either a `String` containing a dotted quad (see Note below),
21 or a JSON `Map`, with the following attributes, all optional:
23 | Key | Type | Comment |
24 |-------------|---------------------------------------|--------------------------------------------|
25 | service | Array(SrvObj) | Located two levels above position |
26 | ip | Array(String) | Dotted quad format "1.2.3.4" |
27 | ip6 | Array(String) | Semicolon format "DEAD::BEEF" |
28 | tor | String | Onion name |
30 | freenet | String | |
31 | alias | String | Nullifies other attributes |
32 | translate | String | Nullifies the "map" attribute |
33 | email | String | Used in `SOA` |
34 | loc | String | Format suitable for `LOC` |
35 | info | JsonObj | Currently unspecified |
36 | ns | Array(String) | Domain names as in `NS` |
37 | delegate | String | Replaces current object |
38 | import | Array(String) | "Deep" merges into current object |
39 | map | Map(String:DomObj) | Tree of subdomain objects |
40 | fingerprint | Array(String) | |
41 | tls | Map(String:Map(String:Array(TlsObj))) | Outer `Map` by `Protocol`, inner by `Port` |
42 | ds | Array(DsObj) | |
46 * Any attribute specified as `Array(String)` may be present in the
47 JSON document as a plain `String`, which is interpreted the same way
48 as an `Array` containing a single `String` element. In other words,
49 `"ip":"1.2.3.4"` is equivalent to `"ip":["1.2.3.4"]`. (This does not
50 apply to non-string-array attributes, like "service" or "ds".)
51 * If `DomObj` is a `String`, it is interpreted as an IPv4 address.
52 In other words, string `"1.2.3.4"` is the same as the Map
53 `"{\"ip\":\"1.2.3.4\"}"`. Such "shorthand" DomObj can be present at
54 the top level or as a value in the `"map"` attribute.
58 `SrvObj` is a heterogenous Array of fixed size containing 6 elements:
60 | N | Type | Meaning |
61 |---|--------|----------|
62 | 0 | String | Service |
63 | 1 | String | Protocol |
64 | 2 | Int | Priority |
71 * `Service` and `Protocol` are two elements of the domain name, without
73 * `SrvObj` with Service `"smtp"`, Protocol `"tcp"` and Port `25` is also
74 interpteted as an `MX` DNS resource at the domain level containing the
76 * When lookup is performed for `SRV` records at fqdn
77 `"_serv._proto.sub.dom.bit"`, domain object for `"sub.dom.bit"` must be
78 fetched, and in this object, `SrvObj`s for the Service `"serv"` and
79 Protocol `"proto"` selected from its `"service"` attribute.
83 `TlsObj` is a heterogenous Array of fixed size containing 3 elements:
85 | N | Type | Meaning |
86 |---|--------|-------------------------------------------------------|
87 | 0 | Int | Match type - 0:Exact, 1:SHA-256, 2:SHA-512 |
88 | 1 | String | Match value - certificate or hash of it as hex string |
89 | 2 | Int | Include subdomains - 0:No, 1:Yes |
93 * The fields of the object correspond to the attributes defined by
94 [RFC-6698](http://tools.ietf.org/html/rfc6698) ("DANE").
98 `DsObj` is a heterogenous Array of fixed size containing 4 elements:
100 | N | Type | Meaning |
101 |---|--------|--------------------------|
102 | 0 | Int | Key Tag |
103 | 1 | Int | Key Algorithm |
104 | 2 | Int | Hash Type |
105 | 3 | String | Hash Value as hex string |
109 * The fields of the object correspond to the attributes defined by
110 [RFC-3658](http://tools.ietf.org/html/rfc3658).
112 ## Data Interpretation
114 ### Semantics of the Attributes
116 #### service attribute
118 Translates to DNS `SRV` RR, only it is located in the subdomain tree
119 two levels higher than the `SRV` record would. For example, a
120 `"service"` attribute in the `"map"` hieararchy at the point
121 corresponding to the FQDN "sub.dom.bit" with the value
124 "service": [ ["imap", "tcp", 0, 0, 143, "mail.host.com" ],
125 ["smtp", "tcp", 0, 0, 25, "relay.host.com"] ]
128 corresponds to two `SRV` RRs at two different points in the
132 _imap._tcp.sub.dom.bit. IN SRV 0 0 143 mail.host.com.
133 _smtp._tcp.sub.dom.bit. IN SRV 0 0 25 relay.host.com.
136 In addition to these, an `MX` RR is syntesized at the "sub.dom.bit"
140 sub.dom.bit. IN MX 0 relay.host.com.
143 Note: Hostname element **must** be specified as fully qualified domain
144 name of the host, and **must not** terminate with a dot.
145 This requirement seems to be in line with many existing definitions in
146 the blockchain; however it deviates from the BIND zone file format, in
147 which names that have not terminating dot are automatically expanded
148 by attaching the current origin zone to the end of the name.
152 Contains a list of strings representing IPv4 addresses in dotted
153 quad notation. For example,
156 "ip": ["1.2.3.4", "5.6.7.8"]
159 translates into a series of `A` RRs:
168 Contains a list of strings representing IPv6 addresses in semicolon
169 quads notation. For example,
172 "ip6": ["2001:4860:0:1001::68"]
175 translates into one AAAA RR:
178 IN AAAA 2001:4860:0:1001::68
183 Does not translate into any DNS RR. Contains Tor hidden service address.
187 Does not translate into any DNS RR. Contains an object with three
188 optional String attributes: `"destination"`, `"name"` and `"b32"`.
190 #### freenet attribute
192 Does not translate into any DNS RR. Contains Freesite key.
196 Translates into `CNAME` RR. Invalidates all other attributes except
197 the element of the `"map"` with empty key. Such element is analysed
198 and its contents merged into the base domain before the check.
200 Note: Hostname element **must** be specified as fully qualified domain
201 name of the host, and **must not** terminate with a dot.
203 #### translate attribute
205 Translates into `DNAME` RR. Invalidates the contents of the `"map"`
206 attribute, except the element of the `"map"` with empty key. Such
207 element is analysed and its contents merged into the base domain
212 Translates into the `email` element of the SOA and RP RRs. The
213 value `"email":"user@domain.tld"` becomes `user.domain.tld.`
218 Translates into `LOC` RR. Value must conform to the format defined
219 by [RFC-1876](http://tools.ietf.org/html/rfc1876).
223 Does not translate into any DNS RR. Contains a JSON object with
224 format unspecified at the time of this writing.
228 Translates into `NS` RR. Invalidates all other attributes, except
229 the element of the `"map"` with empty key. Such element is analysed
230 and its contents merged into the base domain before the check.
232 Note: the value of the attribute **must** be specified as fully
233 qualified domain name of the host, and **must not** terminate
236 #### delegate attribute
238 Does not translate into any DNS RR. Instead, the value is used as
239 a key for namecoin lookup (i.e. the value must be specified with
240 the namespace prefix), and the result of the lookup replaces all
241 other attributes, except the element of the `"map"` with empty key.
242 Such element is analysed and its contents merged into the base
243 domain before the check.
245 #### import attribute
247 Does not translate into any DNS RR. Instead, the value is used as
248 a key for namecoin lookup (i.e. the value must be specified with
249 the namespace prefix), and the result of the lookup is merged with
250 the current domain object.
254 JSON Map object containing subdomain names as its keys and domain
255 objects as values. Element of the map with empty key "" has special
256 meaning: the value of this map element is merged into the current
257 domain object. This operaton happens first when a new domain object
258 is analyzed, and is performed recursively. In the result of the
259 merge, the `"map"` does not contain the element with empty key.
260 Further operatons that can potentially modify the contents of the
261 current domain object (`import` and `delegate` lookups) start when
262 the empty element of the `"map"` has been recursively merged into
265 #### fingerprint attribute
267 Does not translate into any DNS RR. Contains a list of TLS
268 certificate fingerprints. Deprecated.
272 Intended to carry attributes as per
273 [RFC-6698](http://tools.ietf.org/html/rfc6698) ("DANE").
274 As of this writing, the specification is under discussion.
278 Translates into `DS` RR. Carries attributes defined by
279 [RFC-4034](http://tools.ietf.org/html/rfc4034).
283 Assuming a query is performed for
284 `sdN`++"."++{...}++"."++`sd2`++"."++`sd1`++"."++`dom`++".bit"
285 (`sdX` list possibly being empty), the lookup process starts by
286 querying the database for the object corresponding to `dom`.
287 Technically, it is easiest to populate a "seed" DomObj with a
288 single attribute `"import"` the value of which corresponds to the
289 `dom` name in the Namecoin namespace, which is `"d/" ++ dom`.
290 This domain object is then transformed by the following
293 1. Value of the element of the `"map"` attribute with the key `""`
294 (empty string) is recursively merged into the base domain. The
295 `""` element of the `"map"` is removed from the result.
296 2. If attribute `"delegate"` does not exist in the resulting object,
297 step 3 is is performed. If attribute `"delegate"` exists, in
298 the resulting object, lookup is performed for the values of this
299 attribute, and fetched object replaces the base domain completely.
300 The result is passed as base domain to step 1.
301 3. If attribute `"import"` does not exist in the resulting object,
302 recursion stops, and step 4 is performed on the result
303 If attribute `"import"` exists in the resulting object, lookup is
304 performed for the values of this attribute, and fetched objects
305 are recursively merged into the base domain. The `"import"`
306 attribute is removed from the result. Then the result is passed
307 as base domain to step 1.
308 4. If subdomain chain is empty, recursion stops, and step 5 is
309 performed on the result. If subdomain chain is not empty, next
310 element is taken out of the chain, and the `"map"` is looked
311 up for the element with the name matching the subdomain element.
312 The value of this element of the `"map"` is passed as base domain
313 to step 1. If matching element does not exist, lookup is considered
315 5. Domain object in which all `""` map elements and all `"delegate"`
316 and `"import"` elements are acted upon and removed, is then
317 "normalized" by removal of attributes that are nullified by the
318 presence of other attributes.
320 Note that the process involves recursion nested to three levels.
322 ### Merging Procedure
324 When a domain object `extra` needs merging into a domain object `base`,
325 the following rules are applied:
327 * Of `String` and other "scalar" attributes, one is chosen, the value
328 from the `base` taking precedence.
329 * On `Array` attribtes, `union` operation is performed. (Of equal
330 elements, only one copy is left.)
331 * On `Map` attributes, recursive merge is performed. On the top level,
332 elemens with keys that are only present in either `base` or `extra`
333 object are all put into result. The values of the elements that are
334 present in both `base` and `extra` objects are merged according to
335 the rules applicable to their type.