RFC 3367

Common Name Resolution Protocol (CNRP)

๐Ÿ“… published September 2002, from ietf

Common Name Resolution Protocol (CNRP) ๐ŸŽ€

okay so this is RFC 3367 ๐Ÿฆ‹ It's a Standards Track doc from the Network Working Group, dated August 2002. The authors are N. Popp and M. Mealling from VeriSign, Inc., plus M. Moseley from Netword, Inc. ๐Ÿ’… The header doesn't list anything it obsoletes or updates, so there's nothing to chase there. Let's get into it โœจ

Network Working Group                                            N. Popp
Request for Comments: 3367                                   M. Mealling
Category: Standards Track                                 VeriSign, Inc.
                                                              M. Moseley
                                                           Netword, Inc.
                                                             August 2002


                 Common Name Resolution Protocol (CNRP)

Status of this Memo ๐Ÿ“œ

bestie, this part is the official fine print ๐Ÿ™ˆ It says this is an Internet standards track protocol for the Internet community, and it's asking everyone for discussion and suggestions for improvements. For the current standardization state and status, you check the "Internet Official Protocol Standards" (STD 1) ๐Ÿ’œ Distribution of this memo is unlimited, so share away ๐Ÿซถ

Copyright (C) The Internet Society (2002). All Rights Reserved. Legal stuff, but it's there ๐ŸŒธ

Abstract ๐Ÿงš

okay so people always talk about stuff in the real world using a common name or phrase, like a trade name, a company name, or a book title ๐Ÿ“š Those names are usually easier to remember and type than URLs, which is so relatable ๐Ÿ˜ญ But URLs have limited syntax, so companies and individuals are finding that the names that would make the most sense for their stuff are already being used somewhere else ๐Ÿ’€ For this doc, a "common name" is just a word or phrase with no imposed syntactic structure that can be linked to a resource โœจ

this effort is all about making a protocol so client apps can talk to common name resolution services ๐Ÿฆ‹ That's the vibe in both the browser enhancement and the search site paradigms. Even though resolution is the main job, it's also meant to deal with internationalization and localization ๐ŸŒˆ Name resolution services aren't generic search services, so they don't need complicated Boolean queries, relevance ranking, or anything similar ๐Ÿ’… The protocol is a simple, minimal interoperable core, and there are mechanisms for extension so extra capabilities can be added later ๐Ÿ‘‘

Table of Contents ๐Ÿ—‚๏ธ

   1.      Introduction . . . . . . . . . . . . . . . . . . . . . . .  3
   2.      Important Notes  . . . . . . . . . . . . . . . . . . . . .  4
   2.1     Terminology  . . . . . . . . . . . . . . . . . . . . . . .  4
   2.2     DTD is Definitive  . . . . . . . . . . . . . . . . . . . .  4
   2.3     Uniform Resource Identifiers . . . . . . . . . . . . . . .  5
   3.      Interaction Model  . . . . . . . . . . . . . . . . . . . .  5
   3.1     Services, Servers, Datasets and Referrals  . . . . . . . .  5
   3.2     Requests and Responses . . . . . . . . . . . . . . . . . .  5
   3.3     Transport Independence . . . . . . . . . . . . . . . . . .  6
   3.4     Character encoding . . . . . . . . . . . . . . . . . . . .  6
   3.5     Queries  . . . . . . . . . . . . . . . . . . . . . . . . .  7
   3.6     Hints  . . . . . . . . . . . . . . . . . . . . . . . . . .  7
   4.      Object Model . . . . . . . . . . . . . . . . . . . . . . .  8
   4.1     Properties . . . . . . . . . . . . . . . . . . . . . . . .  8
   4.1.1   Core properties  . . . . . . . . . . . . . . . . . . . . .  8
   4.1.2   Abstract and custom properties . . . . . . . . . . . . . .  9
   4.1.3   Base properties  . . . . . . . . . . . . . . . . . . . . .  9
   4.1.4   Common name string encoding and equivalence rules  . . . . 11
   4.2     Objects  . . . . . . . . . . . . . . . . . . . . . . . . . 11
   4.2.1   Query  . . . . . . . . . . . . . . . . . . . . . . . . . . 11
   4.2.1.1 Logical operations within a Query  . . . . . . . . . . . . 12
   4.2.2   Results  . . . . . . . . . . . . . . . . . . . . . . . . . 13
   4.2.2.1 ResourceDescriptor . . . . . . . . . . . . . . . . . . . . 13
   4.2.3   Service  . . . . . . . . . . . . . . . . . . . . . . . . . 14
   4.2.3.1 Datasets . . . . . . . . . . . . . . . . . . . . . . . . . 14
   4.2.3.2 Servers  . . . . . . . . . . . . . . . . . . . . . . . . . 16
   4.2.4   Status Messages  . . . . . . . . . . . . . . . . . . . . . 19
   4.2.4.1 Status of CNRP, Not the Transport  . . . . . . . . . . . . 19
   4.2.4.2 Codes and Description  . . . . . . . . . . . . . . . . . . 19
   4.2.4.3 Status Codes . . . . . . . . . . . . . . . . . . . . . . . 19
   4.2.5   Referral . . . . . . . . . . . . . . . . . . . . . . . . . 21
   4.2.5.1 Loop Detection and Dataset Handling in Servers . . . . . . 22
   4.2.6   Discoverability: ServiceQuery and Schema . . . . . . . . . 24
   5.      XML DTD for CNRP . . . . . . . . . . . . . . . . . . . . . 26
   6.      Examples . . . . . . . . . . . . . . . . . . . . . . . . . 28
   6.1     Service Description Request  . . . . . . . . . . . . . . . 28
   6.2     Sending A Query and Getting A Response . . . . . . . . . . 29
   7.      Transport  . . . . . . . . . . . . . . . . . . . . . . . . 30
   7.1     HTTP Transport . . . . . . . . . . . . . . . . . . . . . . 30
   7.2     SMTP Transport . . . . . . . . . . . . . . . . . . . . . . 31
   8.      Registration: application/cnrp+xml . . . . . . . . . . . . 31
   9.      Security Considerations  . . . . . . . . . . . . . . . . . 32
   10.     IANA Considerations  . . . . . . . . . . . . . . . . . . . 32
           References . . . . . . . . . . . . . . . . . . . . . . . . 33

   A.      Appendix A: Well Known Property and Type Registration
           Templates  . . . . . . . . . . . . . . . . . . . . . . . . 35
   A.1     Properties . . . . . . . . . . . . . . . . . . . . . . . . 35
   A.2     Types  . . . . . . . . . . . . . . . . . . . . . . . . . . 35
   B.      Status Codes . . . . . . . . . . . . . . . . . . . . . . . 37
   B.1     Level 1 (Informative) Codes  . . . . . . . . . . . . . . . 37
   B.2     Level 2 (Success) Codes  . . . . . . . . . . . . . . . . . 38
   B.3     Level 3 (Partial Success) Codes  . . . . . . . . . . . . . 38
   B.4     Level 4 (Transient Failure) Codes  . . . . . . . . . . . . 40
   B.5     Level 5 (Permanent Failures) Codes . . . . . . . . . . . . 40
           Authors' Addresses . . . . . . . . . . . . . . . . . . . . 41
           Full Copyright Statement . . . . . . . . . . . . . . . . . 42

1. Introduction ๐ŸŒธ

okay so services are popping up that map common names to Internet resources, like things identified by a URI โœจ These services usually handle common name categories such as company names, trade names, or common keywords ๐Ÿ’… So a resolution service might work in one category or domain (or a small number of them), or it might expect the client to narrow the resolution scope to a few categories or domains ๐ŸŽ€ For example, "Internet Engineering Task Force" is a common name in the "organization" category, and "Moby Dick" is one in the book category ๐Ÿ“š

there are two kinds of clients being built for these services: browser improvements and web-accessible front-end services ๐Ÿฆ‹ Browser enhancements tweak the "open" or "address" field of a browser so you can type a common name instead of a URL ๐Ÿ’ป Internet search sites plug in common name resolution services as a complement to regular search ๐Ÿ” In both cases, these can be clients of back-end resolution services. The browser has to talk to a service that will resolve the common name, and search sites are accessed through a browser ๐ŸŒˆ Sometimes the search site is also the back-end resolution service, but other times it's a front-end sitting on top of a bunch of back-end services ๐Ÿงš

this effort is all about making a protocol for client apps to talk to common name resolution services, as shown in both the browser enhancement and search site paradigms ๐Ÿ’œ Resolution services aren't generic search services, so they don't need complex Boolean queries, relevance ranking, or anything similar ๐Ÿ’… The protocol is a simple, minimal interoperable core, and mechanisms for extension are provided so extra capabilities can be added ๐Ÿ‘‘

a few other issues matter for deploying these services, but they're outside the resolution protocol itself and not in the initial scope ๐Ÿ™ˆ They include discovering and selecting resolution service providers, administering resolution services, name registration, name ownership, and ways of creating, identifying, or insuring unique common names ๐Ÿ’€

for the purposes of this document, a "common name" is a word or phrase with no imposed syntactic structure that may be associated with a resource โœจ These common names are mainly for humans, not machine agents ๐Ÿซถ A common name "resolution service" handles the associations between common names and data, like resources, information about resources, pointers to locations, and so on ๐Ÿฆ‹ A single common name can be associated with different data records, and more than one resolution service is expected to exist. Any common name may be used in any resolution service ๐ŸŒˆ

common names aren't URIs (Uniform Resource Identifiers), because they lack the syntactic structure URIs have ๐Ÿ˜ญ Also, unlike URNs, there's no requirement that the association between a common name and a resource be unique or persistent ๐Ÿ’… (Note: common names may be expressed in a URI, the syntax for which is described in RFC 3368 [9].) ๐ŸŽ€

this document will define a protocol for the parameterized resolution needed to make common names useful ๐Ÿงš "Resolution" is defined as retrieving the data associated (a priori) with descriptors that match the input request ๐Ÿ” "Parameterized" means having a multi-property descriptor ๐Ÿ’œ Descriptors aren't required to provide unique identification, so 0 or more records may be returned to meet a specific input query ๐ŸŒธ

2. Important Notes ๐Ÿ“

2.1 Terminology ๐Ÿ’…

the key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 [7] โœจ

2.2 DTD is Definitive ๐Ÿ‘‘

the descriptive parts of this document contain pieces of XML that are illustrative examples only ๐ŸŽ€ Section 5 of this document contains the XML DTD for CNRP, and that one is definitive ๐Ÿ’– If any discrepancies are found, the DTD wins ๐Ÿซถ

2.3 Uniform Resource Identifiers ๐Ÿฆ‹

all URIs used within the CNRP protocol MUST adhere to the 'absoluteURI' production found in the ABNF of [3] ๐Ÿ’… CNRP does not define the semantics of a Base, so it isn't capable of expressing the 'URI-Reference' production ๐Ÿ™ˆ

3. Interaction Model ๐Ÿงš

3.1 Services, Servers, Datasets and Referrals โœจ

okay so CNRP has this whole interaction model ๐Ÿ’… where a generalized "service" gives you common name resolution across one or more actual "servers" ๐Ÿงš. If every server holds identical data (mirrors), the service doesn't need to name any particular subset. But if it serves different collections through different servers (subsets, specialized collections, etc.), it SHOULD indicate what subset of its data each server offers ๐Ÿ—‚๏ธ. It does this with URIs, which uniquely tell one dataset apart from another ๐Ÿ”—. And if the service offers a copy of a collection on agreement with a foreign service, the foreign service SHOULD provide a dataset URI so that collection can be linked back to its own offerings ๐Ÿซถ.

Referrals are the tea โ˜•. A server can know that another Service exists (inside the same Service or somewhere else) that can give more answers to a query, but instead of chaining the query for the client, it decides to forward that fact to the client ๐Ÿฆ‹. A referral is sent along with the rest of the results from a server, if there are any. Referrals to a service SHOULD indicate the particular dataseturi that triggered the referral, if it's known ๐Ÿ’œ. See Section 4.2.5 for details on referrals and loop detection โญ.


3.2 Requests and Responses ๐ŸŽ€

the protocol is giving simple request/response energy ๐ŸŒธ. A client sends one of a few types of requests to a server, and the server responds with the results of that request. Every request and response is encoded with XML [8] using the DTD found in Section 5. There are two types of requests: a general query for a common-name, and a request for an object that describes the service and its capabilities ๐Ÿ“‹. There's only one type of response, which is a set of results. Results can contain actual result items, referrals and/or status messages โœจ.


3.3 Transport Independence ๐Ÿฆ‹

CNRP is completely encapsulated within its XML definition, so its specification is transport-independent ๐ŸŒˆ. Still, clients need a clearly defined way to bootstrap a connection with a server, bestie ๐Ÿซถ.

It's possible to make special-purpose applications that use CNRP but never need the HTTP bootstrapping method we'll get into below. Those applications MUST define how to find the appropriate server/port/protocol ๐Ÿ”. CNRP servers dedicated to those apps may only provide service on the ports/transport protocols the application defines ๐ŸŽฏ.

All other (generic) CNRP clients and servers MUST support the HTTP (Section 7.1) transport on the default CNRP port of 1096 ๐Ÿ”ฅ.

A particular service may choose to switch to a different transport or port through statements inside a CNRP service description request, but initial contact between a client and a server is over HTTP on port 1096 ๐Ÿ’–. For a short explanation of how CNRP uses HTTP, check Section 7.1 of this document ๐Ÿ“–. If other transports are used, they MUST be handled over a port other than the default CNRP port ๐Ÿšฆ.


3.4 Character Encoding ๐Ÿ“

to guarantee interoperability, these provisions apply ๐Ÿซถ:

  • XML queries and responses MUST be encoded as UTF-8.

Note: As in any XML document, numeric character references may be used.

  • The encoding of characters in the CNRP URI is based on UTF-8. For details, see [9].

any interfaces that choose to present or accept protocol elements in other representations are responsible for accurate transcoding for use in CNRP protocol elements, following the provisions above ๐Ÿ’….


3.5 Queries ๐Ÿ”

queries are sent by the client to the server, and there are two types ๐Ÿ’œ.

  1. A 'special' initial query that establishes the schema for a particular CNRP database and tells the client about it ๐Ÿ“œ. The CNRP client sends this query and gets back an XML document defining the query properties that the database supports. (In CNRP, XML [8] is used to define and express all objects.) This query is called the 'servicequery' in the DTD. If a client doesn't know anything about the Service, the client MAY assume that it can at least issue the request via HTTP ๐Ÿฆ‹.
  2. A 'standard' query, which is the submission of the CNRP search string to the database ๐Ÿ”Ž. The query will conform to the schema that MAY have been previously retrieved from the service.

there's a set of query properties, listed below, that the server treats as hints ๐Ÿ’ก. Note: a CNRP database will accept any correctly encoded CNRP query property. How responsive a query result is to those properties is a service differentiator ๐ŸŒŸ. The base properties that are always supported are common name, language, geography, category, and range (start and length of the result set) ๐Ÿ“ฆ. CNRP also lets database service providers create unique data types and expose them to any CNRP client through the CNRP schema XML documents ๐Ÿงš.


3.6 Hints ๐Ÿ’ก

a hint is an assertion the user makes about themselves (or itself) and the context they're operating in ๐Ÿชž. There's no data type called hint. A hint is expressed within the structure of the query itself, and how many hints you can give is limited or enabled by how rich the defined query namespace is ๐ŸŽ€. Basically, a query and any property inside it is a hint ๐Ÿ˜ญ.

For example, the "language" property can be given as a hint in a query, and it may be used to order the search results ๐ŸŒ. If you want results first in US English, then European French, and finally South American Spanish, you'd include the following in the query:

<property name="language" type="rfc1766">en-US</property>

<property name="language" type="rfc1766">fr-FR</property>

<property name="language" type="rfc1766">sp-MX</property>

the property statements don't say anything about whether a language is primary, secondary, and so on ๐Ÿ™ˆ. In this example, the ordering of the statements controls that. The first statement, being first, means US English is the primary language. The second statement specifies the second region/language, and so on ๐Ÿ‘‘. But this is only an example. ๐Ÿ’€ How well hints are supported (or not) is a service differentiator.

the fact that a hint exists does not mean that a CNRP database must respond to it. This best-effort approach is similar to relevance ranking in a search engine (high precision, low recall), and hints are similar to a search engine's selection criteria ๐Ÿง . CNRP services will attempt to return the results "closest" to the selection criteria. This is quite different from a SQL database approach, where a SQL query returns the entire results set and each result in the set must match all the requirements expressed by the qualifier (the SQL WHERE clause) ๐Ÿ’….

4. Object Model โœจ

4.1 Properties ๐ŸŒธ

in CNRP, objects are property lists ๐Ÿ“. A property is a named attribute, and it also has a well-defined type ๐Ÿท๏ธ. Some properties can be part of the query, the results list, or both. For simplicity, CNRP limits property values to string values ๐Ÿซถ.

4.1.1 Core Properties ๐Ÿ‘‘

CNRP introduces a set of core properties ๐Ÿ’œ. These are the minimal set of properties that all CNRP services MUST support in order to reach CNRP compliance ๐Ÿ”ฅ. So the core properties define the level of interoperability between all CNRP services. The core properties are:

  1. CommonName: the common name associated with a resource.
  2. ID: an opaque string that serves as a unique identifier for a result from a Service (typically a database ID). The ID is not globally unique, nor necessarily persistent (e.g., between queries at a given Service).
  3. resourceURI: An 'absoluteURI' as defined in the collected ABNF found in RFC 2396 [3].
  4. description: A free text description of the resource.

4.1.2 Abstract and Custom Properties ๐Ÿฆ‹

on top of core properties, CNRP brings in the notion of abstract properties ๐ŸŒˆ. The abstract property element gives schema extensibility beyond the core properties, and this is a huge deal because it opens the door to a wider range of CNRP-based services than the core properties alone would allow ๐Ÿš€.

To create concrete custom properties, a CNRP service must define a property name and a property type ๐ŸŽ€. So there are really two ways to make a custom property. The first is to create a new property name and define at least one type for it. The second is to extend an existing property by defining a new type. The "geography" property discussed in the next section is an example of a multi-type property ๐ŸŒ. Note that a type only applies to the property it's defined for. If a new property is defined, a new type MUST be defined, even if the value set for that type is identical to an existing type for an existing property ๐Ÿ˜ค. In other words, types are scoped to a given property. Custom properties MUST be registered with IANA ๐Ÿ“ฎ. You can find details about the registration process for new properties in Section 10 ๐Ÿ”.

For example, let's say a CNRP service that specializes in online books wants to introduce the ISBN property of type "number" ๐Ÿ“š. This property would hold the ISBN number of the book online and would look like this in XML:

<property name="isbn" type="number">92347231</property>

4.1.3 Base Properties โœจ

Okay so this is where CNRP shows off the abstract property trick to extend the core schema ๐Ÿ’… It also defines a whole set of custom properties called base properties ๐ŸŽ€ To keep the requirements super simple, these are not mandatory to implement to reach CNRP compliance. But even though they aren't required, it's expected that lots of services, especially the big ones, will implement them ๐Ÿซถ Another goal is giving us a results filtering mechanism, which is basically a must for huge namespaces with several million names ๐Ÿ˜ญ

The base properties and their types are defined in Appendix A, but here they are listed for clarity ๐ŸŒธ

  • Language: The language associated with a resource. The default type of this property is 'RFC1766', and the vocabulary comes from the list of languages in RFC 1766 [4]. If RFC 1766 gets updated, then the values listed in the updated version are also valid for this type ๐ŸŒˆ
  • Geography: The geographical region or location associated with a resource. Some of the possible types are below, and Appendix A has the complete list of types specified by this document ๐Ÿ—บ๏ธ
    • 'freeform': a free form expression for a geographical location (e.g., "palo alto in california").
    • 'ISO3166-1': geographical region expressed using a standard country code as defined by ISO3166-1 (e.g., "US").
    • 'ISO3166-2': value = a geographical region expressed using a standard region and country codes as defined by ISO3166-2 (e.g., "US-CA").
    • 'lat-long': the latitude and longitude of a geographical location.
  • Category: The category associated with a resource. There are SO many possible types for this one ๐Ÿ˜ตโ€๐Ÿ’ซ Two of them are:
    1. 'freeform': a free form expression for a category (e.g., "movies").
    2. 'NAICS': The North American Industry Code System.
  • Range: The range is a results set control property ๐ŸŽฏ It's used to specify the starting point and the length of a results set (e.g., I want 5 records starting at the 10th record). It should only ever have one type, but in the interest of extensibility and consistency, others can be created if there's a need. The default type is 'start-length', which takes the form of two integers separated by a dash. The first integer is the starting number and the second is the number of values to include โœจ
  • Dataseturi: An absoluteURI (as defined in [3]) that identifies a defined set of Common Names and associated data ๐Ÿ“š

Note: For many properties the default "type" is "freeform". The free form type value is important because it allows a very simple user interface where the user can type a value into a text field ๐Ÿ’– It's up to the service to interpret the value correctly and take advantage of it to increase the relevance of results (using specialized dictionaries, for instance) ๐Ÿงš

4.1.4 Common Name String Encoding and Equivalence Rules

CNRP specifies that common name strings should be encoded using UTF-8 ๐Ÿ“ CNRP does not specify any string equivalence rules for matching a common name in the query against a common name of a Resource. String equivalence rules are language and service dependent ๐ŸŒ They are specific to relevance ranking algorithms, so they're treated as CNRP services. Consequently, string equivalence rules are not part of the CNRP protocol specification ๐Ÿ™ˆ For example, the query member:

<commonname>bmw</commonname>

should be read as a selection criterion for a resource with a common name LIKE (similar to) the string "bmw", where the exact definition of the LIKE operator is intuitive, yet specific to the queried CNRP service ๐Ÿฆ‹

It is also important to note that XML treats whitespace as a special case in many situations. In some cases, it collapses whitespace into a single space. Both client and server Implementors are warned to reference the XML standard for the various ramifications of using whitespace in queries and/or results ๐Ÿ‘‘

4.2 Objects ๐ŸŽ€

4.2.1 Query

The Query object encapsulates all the query components, such as CommonName, ID, and any properties ๐Ÿซง A Query cannot be empty. A Query must contain either one and only one common name, or one and only one ID. A Query can also contain the custom properties defined by a specific CNRP service ๐Ÿ’œ

For example, a query for the first 5 resources whose common name is like "bmw" would be expressed as:

<query>
        <commonname>bmw</commonname>
        <property name="range" type="start-length">1-5</property>
</query>

4.2.1.1 Logical Operations Within a Query

The Query syntax is extremely simple ๐Ÿฅน CNRP doesn't really support Boolean logic operators such as OR, AND or NOT. BUT there are two implicit logical operations you can express through the Query object and its properties โœจ First, a query with multiple property-value pairs implicitly expresses an AND operation on the query terms. For instance, the CNRP query to request all the resources whose common name is like "bmw" AND whose language is "German" can be expressed as:

<query>
        <commonname>bmw</commonname>
        <property name="language" type="rfc1766">
           de-DE
        </property>
</query>

Note however, that because the server is only trying to best match the Query criteria, there is no guarantee that all or any of the resources in the results match both requirements ๐Ÿ˜ฌ

In addition, CNRP lets the client express a logical OR by specifying multiple values for the same property within the Query. For example, the logical expression:

property = value1 OR property = value2 OR property = valueN

Will be expressed as:

<property>value1</property>
<property>value2</property>
<property>valueN</property>

So if different properties are expressed, CNRP ANDs them; if there are multiple instances of the same property expressed, CNRP ORs them ๐Ÿ”ฅ

It's important to underline that this form only applies to properties (with the exception of the CommonName itself, which, even though it is a property, is the entire point of the query). In particular, logical OR operations on the common name are not supported ๐Ÿ™…โ€โ™€๏ธ Note that the ordering of the property-value pairs in the query implies a precedence. As a consequence, CNRP also introduces one special string value: "*". Not surprisingly, "*" means all admissible values for the typed property. For example, the following query requests all the resources whose common name is like BMW and whose language is preferably German or French or any other language ๐ŸŒˆ

<query>
        <commonname>bmw</commonname>
        <property name="language" type="rfc1766">de-DE</property>
        <property name="language" type="rfc1766">fr-FR</property>
        <property name="language" type="rfc1766">*</property>
</query>

4.2.2 Results

The results object is a container for CNRP results ๐Ÿงบ The type of objects contained in Results can be: ResourceDescriptor, Error, Referral and Schema. Results from a CNRP service are ordered by decreasing relevance. When the results set contains results from multiple CNRP services, the results can no longer be ordered (since relevance ranking is specific to a given service). In that case, though, results originating from the same service remain ordered ๐Ÿซถ

4.2.2.1 ResourceDescriptor

The ResourceDescriptor object describes an Internet resource (e.g., a Web page, a person, any object identified by a URI) ๐ŸŒ Therefore, the ResourceDescriptor MUST always include the resourceURI property. The ResourceDescriptor can also contain the commonname, URI, ID (the ID of this entry in the service's database), description, language, geography, and category of the resource. A ResourceDescriptor can also be augmented using custom properties, and it can reference a service object to indicate its origin (using the serviceRef element). As with referrals, a resourcedescriptor block can also contain an ID attribute that is used by a status message to refer to a particular resourcedescriptor. Be careful not to confuse this ID with the id tag itself, which refers to the database id of the actual database entry. โš ๏ธ

<results>
        <service id="i0">
             <serviceuri>http://cnrp.bar.com/</serviceuri>
        </service>
        <resourcedescriptor id="i1">
             <commonname>bmw</commonname>
             <id>foo.com:234364</id>
             <resourceuri>http://www.bmw.de/</resourceuri>
             <serviceref ref="i0" />
             <description>BMW Motorcycles, International</description>
             <property name="language" type="rfc1766">de-DE</property>
        </resourcedescriptor>
        <referral>
             <serviceref ref="i0" />
        </referral>
</results>

4.2.3 Service

The Service object is an encapsulation of an instance of a CNRP service ๐Ÿ  A service is uniquely identified through the serviceuri tag, which MUST be included in the Service object. A Service object MAY include a brief textual description of the service. It MAY include datasets, servers and custom properties ๐Ÿ’…

<service>
        <serviceuri>http://cnrp.foo.com</serviceuri>
        <description>foo.com is a CNRP service specialized on cocktail
           recipes</description>
</service>

The service object MAY also be extended by including existing properties to further describe the service ๐Ÿธ For instance, a service that focuses on French companies could be expressed as:

<service>
        <serviceuri>http://cnrp.foo.com</serviceuri>
        <property name="category" type="freeform">companies</property>
        <property name="geography" type="ISO3166-1">FR</property>
</service>

4.2.3.1 Datasets ๐Ÿ“šโœจ

okay so a dataset is basically a set of CN-to-URI mappings ๐Ÿ—บ๏ธ like, the database of AOL keywords and their URIs? that's a dataset bestie. it lets a CNRP implementation uniquely identify the database(s) of mappings it resolves ๐Ÿซถ and that's the whole point: datasets split resolution from data, so a CNRP service can resolve common-names on behalf of another CNRP service, or even on behalf of multiple services ๐Ÿฆ‹ and the flip side is also iconic, the same dataset can be served by two different CNRP services ๐Ÿ’… since one service can resolve names within one or more datasets, the service object can hold one or more dataset objects. (or zero, if the dataset isn't formally declared ๐Ÿ™ˆ)

inside the service object, a dataset is uniquely defined by its dataseturi property ๐ŸŽ€ other properties, like language and description, can describe it further. just like the service object, the dataset object has an ID attribute that's unique within one XML message ๐ŸŒธ and this ID is what resourcedescriptors and referrals use to say which service and/or dataset they came from, or which one they're pointing to ๐Ÿ’œ

now the default dataset ๐Ÿ‘‘ every service can be said to have one. it's the dataset that's considered to have been used when a server just answers a client's query that didn't include a dataset. the default dataset can also be described as the only dataset used by services that don't support datasets at all ๐ŸŒˆ this is lowkey super useful for clients that wanna do rigorous loop detection by keeping a list of visited service/dataset nodes ๐Ÿ”ฅ

here's how a service object looks when it defines two datasets ๐Ÿ‘‡

<service id="i0">
 <serviceuri>http://acmecorp.com</serviceuri>
 <dataset id="i1">
   <property name="dataseturi">
      urn:oid:1.2.3.4.666.5.4.3.1
   </property>
   <property name="language">en-us</property>
   <property name="language">en-gb</property>
 </dataset>
 <dataset id="i2">
   <property name="dataseturi">
      urn:oid:1.2.3.4.666.10.9.8.7.6
   </property>
   <property name="language">fr</property>
 </dataset>
</service>

the dataseturi property can also show up inside a query, as a hint to the service about which dataset the commonname should be resolved in ๐Ÿ“

<query>
   <commonname>toys r us</commonname>
   <property name="dataseturi">urn:oid:1.2.3.4.666.5.4.3.1</property>
</query>
โš ๏ธ resolution rules (like string equivalence, relevance ranking, etc.) are likely to be dataset-specific! and that stays true even when the same service is doing the resolving ๐Ÿ™ˆ

another use of dataseturi is in a referral ๐Ÿฆ‹ there, the datasetref tag is what pinpoints one specific dataset inside the service โœจ

<referral>
   <serviceref ref="i0" /><datasetref ref="i1" />
</referral>

datasets are super important for services that want to make their data available through other services, BUT the declaring and using of datasets is completely optional ๐Ÿ’– CNRP compliance does not require a service object to define or reference any dataset object. the only requirement for compliance is that a client and/or server knows the format of the particular XML tags and deals with them syntactically. and if it chooses to ignore them? totally within its rights ๐Ÿซถ

4.2.3.2 Servers ๐Ÿ–ฅ๏ธ

the service object also wraps up a list of server objects ๐ŸŽ€ a server object describes a CNRP server or a set of servers, and a server is identified through its serveruri. the URI used to identify a server is not a CNRP URI [9], it's a URI of the scheme used as the CNRP transport mechanism ๐Ÿฆ‹ so for a CNRP server that talks HTTP to the host foo.com on port 6543, the serveruri would be http://foo.com:6543 โœจ if some other info is needed to get the right transport working, that info can ride along in other properties ๐Ÿ’… and here's the big one: a Service MUST have at least one Server that responds on the default CNRP port, so a client can get the initial Service object ๐Ÿ‘‘ no cap, that's non-negotiable bestie.

a server can serve one or more datasets declared by its service ๐ŸŒธ the served databases are specified with the dataseturi property. like other objects, a server can get extra descriptive properties too, such as geography and description ๐ŸŒˆ the XML below finishes the service definition from the previous example by defining two CNRP servers: one in the US and one in France. the US server is specialized and only serves the French dataset ๐Ÿ‡ซ๐Ÿ‡ท (yes the US one is the picky one, iconic behavior tbh ๐Ÿ’€)

  <servers>
     <server>
        <serveruri>cnrp://router.us.widgetco.com:4321</serveruri>
        <property name="geography" type="ISO3166-1">US</property>
     </server>
     <server>
        <serveruri>cnrp://router.fr.acmeco.com:4321</serveruri>
        <property name="geography" type="ISO3166-1">FR</property>
     </server>
  </servers>

as we'll see in a following section, the Service object can contain Schema objects ๐Ÿ“‹ those fully describe the query and response interfaces a CNRP service implements, so the Service object is essential to discoverability ๐Ÿ” it's the main entry point for a CNRP client to dynamically discover what a resolution service can do โญ the Service object can be returned as part of the response to any resolution query, and it's also the dedicated response to the specialized servicequery (see Section 4.2.6) ๐Ÿ’œ

another use of Service is for other objects to show their CNRP service of origin ๐Ÿซถ system messages, referrals and resourcedescriptors can all include a reference to their Service object. picture a CNRP service acting as a proxy for multiple CNRP services ๐Ÿงš it's a requirement that CNRP allows aggregation of results from different sources, so the proxy contacts each CNRP sub-service in parallel or serially, then combines the individual result sets into one unique response for the CNRP client ๐Ÿ’– since the aggregate result set has resourcedescriptors from different services, the proxy adds a servicereference tag within each individual result to show its service of origin โœจ and if one of the referred services resolves names within multiple datasets, these objects can point to a specific dataset inside that service using the datasetref tag ๐Ÿฆ‹ here's an example of a hybrid result set, with resourcedescriptors referencing their service and dataset of origin ๐Ÿ‘‡

<?xml version="1.0"?>
<!DOCTYPE cnrp PUBLIC "-//IETF//DTD CNRP 1.0//EN"
    "http://ietf.org/dtd/cnrp-1.0.dtd">
<cnrp>
     <results>
          <service id="i0">
               <serviceuri>http://acmecorp.com</serviceuri>
               <dataset id="i1">
                  <property name="dataseturi">
                   urn:oid:1.2.3.4.666.5.4.3.1
                  </property>
               </dataset>
               <dataset id="i2">
                  <property name="dataseturi">
                   urn:oid:1.2.3.4.666.10.9.8.7.6
                  </property>
               </dataset>
          </service>
          <service id="i3">
             <serviceuri>http://serverfarm.acmecorp.com</serviceuri>
          </service>
          <service id="i4">
              <serviceuri>http://servers.acmecorp.co.uk</serviceuri>
              <dataset id="i5">
                  <property name="dataseturi">
                    urn:oid:1.2.3.4.666.5.4.3.1
                  </property>
              </dataset>
          </service>
          <resourcedescriptor>
                    <commonname>Fidonet</commonname>
                    <id>1333459455</id>
                    <resourceuri>http://www.fidonet.ca</resourceuri>
                    <serviceref ref="i0" /><datasetref ref="i1" />
                    <description>This is ye olde Canadian
                     Fidonet</description>
          </resourcedescriptor>
          <resourcedescriptor>
                    <commonname>Fidonet</commonname>
                    <id>1333459455</id>
                    <resourceuri>http://host:port/bla</resourceuri>
                    <serviceref ref="i3" />
                    <description>An old Fidonet node</description>
          </resourcedescriptor>
          <referral>
              <serviceref ref="i0" /><datasetref ref="i2" />
          </referral>
     </results>

</cnrp>

4.2.4 Status Messages ๐Ÿšฆ

4.2.4.1 Status of CNRP, Not the Transport ๐Ÿšซ

the status messages defined here only apply to operations defined by CNRP itself ๐Ÿ’… if some feature or operation is defined by the transport (security via HTTP, mail failure via SMTP, etc.), then any status messages about that operation MUST be sent according to that transport's reporting mechanism, not via CNRP ๐Ÿ™…โ€โ™€๏ธ (the transport handles its own drama, bestie ๐Ÿ˜ญ)

4.2.4.2 Codes and Description ๐ŸŒท

a Status object indicates a message to the client in the results set ๐Ÿ’Œ it wraps up two values: a status code and a description. the description can contain a textual description of the status being communicated, and in lots of cases, extra diagnostic info can get added too ๐Ÿ” no attempt is made to standardize the description of a given status code, because the only programmatic element that matters is the actual code ๐Ÿ’œ

a status message can also say which other CNRP element it refers to, by including a reference to that element's ID ๐ŸŽฏ so if a Service block has an ID of "i2" and a status message refers to that block, it can put that ID in its ref attribute ๐ŸŒˆ

         <status code="x.y.z" ref="i2">
              The CNRP foo.com database is temporarily unreachable
         </status>

4.2.4.3 Status Codes โœจ

okay so the status codes are basically borrowed from RFC 1893 [10], which means they follow the x.yyy.zzz shape ๐Ÿ’… Here's the ABNF, straight from RFC 1893:

status-code = class "." subject "." detail
class = "2"/"3"/"4"/"5"
subject = 1*3digit
detail = 1*3digit

The first number tells you how serious the situation is, so think of it as the severity level ๐Ÿšฆ

  • 1.X.X Informational
    • The info here has no bearing on whether a request worked or didn't. It's purely FYI, nothing more ๐Ÿงš
  • 2.X.X Success
    • The request got processed and results came back. Honestly, this class usually isn't even sent, because the results themselves already scream "success" ๐ŸŽ€ Sometimes results come back but the client still needs some extra info, and that's when you'd see it.
  • 3.X.X Partial Success
    • The request got processed and results came back, but some of the values in it were invalid or ignored. The server still counts the response as a win though, so it's not a real error ๐ŸŒธ
  • 4.X.X Transient Failure
    • The request was legit as sent, but some temporary hiccup stopped it from finishing and/or sending the results. Trying again later might work ๐Ÿฆ‹
  • 5.X.X Permanent Failure
    • This one is not likely to fix itself if you just resend the exact same request ๐Ÿ’€ Something about the request or the destination has to change before it can succeed.

The second number tells you the subject of the message, and it applies to all five classes. If the server recognizes the subject sub-code, it must be reported, even if the detail sub-code isn't recognized ๐Ÿซถ The enumerated subject values are:

  • X.0.X Other or Undefined Status
    • No specific info about what subject this message belongs to ๐ŸŒˆ
  • X.1.X Query Related
    • Anything about how the query was encoded or what its values were, except for properties โœจ
  • X.2.X Service Related
    • Anything about the service this server is helping to provide ๐Ÿ’œ

Appendix B contains a list of all predefined status codes ๐Ÿ“

4.2.5 Referral ๐Ÿฆ‹

okay this one is my favorite, it's giving hierarchy and I'm obsessed ๐Ÿ˜ญ A Referral object in the results set is basically a placeholder for results you haven't fetched yet. They might live in a different service and maybe a different dataset too. Referrals usually show up when a CNRP server knows about another service that could help with the query, and it wants to give the client a heads up ๐Ÿ”ฅ The client gets to decide if it wants to follow the referral and go grab those extra results. It does that by contacting the referred-to service with the info inside the Referral object, which is a Service object plus possible properties. Referrals are the simple trick that makes hierarchical resolution possible and lets multiple resolution services link up together ๐Ÿ‘‘

Here's what a results set with a referral looks like:

<results>
     <service id="i0">
          <serviceuri>http://cnrp.bar.com/</serviceuri>
          <dataset id="i1">
             <property name="dataseturi">
               urn:oid:1.3.6.1.4.1.782.1
             </property>
          </dataset>
          <dataset id="i2">
             <property name="dataseturi">
               urn:oid:1.3.6.1.4.1.782.2
             </property>
          </dataset>
     </service>
     <resourcedescriptor>
          <commonname>bmw</commonname>
          <id>foo.com:234364</id>
          <resourceuri>http://www.bmw.de/</resourceuri>
          <serviceref ref="i0" /><datasetref ref="i1" />
          <description>BMW Motorcycles, International</description>
          <property name="language" type="iso646">de-DE</property>
     </resourcedescriptor>
     <referral>
          <serviceref ref="i0" /><datasetref ref="i2" />
     </referral>
</results>

Like every other CNRP object, a referral can be described with custom properties ๐Ÿงš And just like a resourcedescriptor, a referral can have an ID attribute, which a status message can use to talk about one particular referral block ๐Ÿ’–

4.2.5.1 Loop Detection and Dataset Handling in Servers ๐Ÿ”

Referrals in CNRP can be handled in three ways:

  • application specific,
  • as hints only,
  • rigorous loop detection.

For the first two, the client's behavior when it gets a referral isn't defined in this memo ๐Ÿ™ˆ A client can chase a referral in a way that treats it as a hint only. In that case, datasets may or may not get handled. Loop detection can be as simple as "Have I talked to this hostname before?" or "Stop after the 3rd referral" ๐ŸŒธ These two options are most likely for simple or constrained implementations, where clients and servers already know a bunch about each other ahead of time. Without that knowledge, there's just too much ambiguity around services and datasets for a client to do reliable loop detection ๐Ÿ˜ตโ€๐Ÿ’ซ

The last option is for when a client expects to talk to multiple servers that might know nothing about each other. This is the basic semantics of what a server should tell a client if it understands datasets or referrals ๐Ÿ‘‘ Since a referral points at one exact dataset, each node in the list of visited nodes is a serviceuri and a dataseturi together. Both values need to be considered during loop detection. If a service doesn't support datasets, the visited node is the service plus the 'default dataset' ๐ŸŽ€

The big thing to remember when doing loop detection across servers is that some servers don't understand datasets at all, while others totally rely on them ๐Ÿ’… To help figure out how loop detection nodes should be marked, three specific status messages were defined:

The 3.1.3 (Datasets not supported) status message means the server doesn't support datasets at all. It's sent in response to a query that contains datasets. The client should treat it as the server having ignored the datasets, and the client should consider this node visited for every possible dataset, including the 'default' dataset ๐Ÿซ 

The 3.1.4 (First dataset only supported) status message is how a server says that a client sent several dataseturis in one query but it can only handle one at a time ๐Ÿงš The server is explicitly saying it used only the first dataseturi. The client should consider that only the first dataseturi was processed correctly, and that the rest of the datasets were ignored completely. If the client really cares about those results, it'll need to send them individually as referrals. Only the first serviceuri/dataseturi pair should be marked as visited ๐Ÿฆ‹

The 3.1.5 (This dataset not supported) status message says that a specific dataseturi a client sent in a query isn't supported by the server. That serviceuri/dataseturi pair should be considered visited by the client. If this message comes back in reply to a query that specified multiple datasets, the client should act the same as if it got the 3.1.3 message ๐ŸŒˆ It should be considered bad form for a server to send this status message in response to a query with multiple datasets, because it's ambiguous ๐Ÿ™ˆ

There's no exact loop detection algorithm that clients are encouraged to support, but these status messages let the server be super clear about which Services and Datasets it considers queried โœจ What the client does with them, and how closely it tries to do loop detection, is totally up to the client ๐Ÿ’œ

4.2.6 Discoverability: ServiceQuery and Schema ๐Ÿ”

A ServiceQuery object is a subclass of Query, and it supports dynamically discovering a specific CNRP service's characteristics ๐Ÿงš Heads up: CNRP compliance doesn't require a service to fully implement discoverability. Returning the Service object with its serviceuri is a minimal, yet sufficient, compliant implementation ๐Ÿซถ That said, we expect advanced CNRP services will choose to return a full description of their supported interfaces ๐ŸŒŸ

The complete response to a servicequery returns the Service object described in section 5.3.2 along with this schema info:

  1. The base and custom properties used by the CNRP service (Property schema),
  2. The properties used to describe the Service object (Service schema),
  3. The properties that belong to the query interface (Query schema),
  4. The properties that belong to a resource within the results (Resource schema).

These lead to the following new object definitions:

  • propertyschema -- A property schema describes all the custom properties that are part of the service โœจ
  • propertydeclaration -- A property declaration describes a base or custom property used by the CNRP service. It has a name and a type, which are the name and type of the property it refers to. Note that as part of the property schema, one MUST declare both existing and newly defined properties ๐Ÿšจ
  • propertyreference -- A property reference is a reference to a property declaration, so a given schema (a service, query or resource schema) can declare the property within its interface. Note that a property reference specifies whether the use of the property is required or optional only ๐Ÿ’…
  • serviceschema -- The service schema defines the properties used to describe the service ๐ŸŽ€
  • queryschema -- A query schema describes the structure of a query handled by the CNRP service. The properties referred to within the query schema are part of the query interface of the resolution service ๐ŸŒธ
  • resourcedescriptorschema -- A ResourceDescriptor schema describes the resource returned as a result by the CNRP service ๐Ÿฆ‹

For example, a CNRP query to discover a service's capabilities looks like this:

<cnrp> <servicequery/> </cnrp>

And for a CNRP service that serves cocktail recipes in French, the response would be:

<service>
     <serviceuri>http://cnrp.recipe.com</serviceuri>
     <propertyschema>
        <propertydeclaration id="i1">
              <propertyname>language</propertyname>
              <propertytype>rfc1766</propertytype>
        </propertydeclaration>
        <propertydeclaration id="i2">
              <propertyname>cocktailrecipe</propertyname>
              <propertytype>freeform</propertytype>
        </propertydeclaration>
     </propertyschema>
     <queryschema>
          <propertyreference required="yes" ref="i1"/>
     </queryschema>
     <resourcedescriptorschema>
          <propertyreference required="yes" ref="i1"/>
          <propertyreference required="yes" ref="i2"/>
     </resourcedescriptorschema>
</service>

This response stipulates that the service accepts the property language as part of the query interface, and returns resourcedescriptors that contain both the language and cocktailRecipe properties. ๐Ÿธ๐Ÿ’–


5. XML DTD for CNRP โœจ

Okay bestie, this is the DTD, the blueprint that says exactly what a valid CNRP message looks like ๐Ÿงš Here it is, copied exactly, comments and all ๐Ÿ’…

<!-- The document tag -->
<!ELEMENT cnrp (query|results|servicequery)>

<!-- Used to request a Service object -->
<!ELEMENT servicequery EMPTY>

<!-- A query can either request a schema, a specific record by -->
<!-- id, or a common-name with a set of properties (or         -->
<!-- assertions) about the entity doing the query.             -->
<!ELEMENT query (id|(commonname,property*))>
<!ELEMENT id (#PCDATA)>

<!ELEMENT commonname (#PCDATA)>
<!-- NOTE: CNRP defines several well known properties          -->
<!-- and types. See Appendix A for details.                    -->
<!ELEMENT property (#PCDATA)>
<!-- The name of the property -->
<!ATTLIST property name CDATA #REQUIRED>
<!-- The type of the property -->
<!ATTLIST property type CDATA "freeform">

<!ELEMENT results (status? |
                   ( service+,
                        ( status  | resourcedescriptor | referral )*
                   )*
                  )>

<!ELEMENT resourcedescriptor (commonname,id,resourceuri,
    serviceref, datasetref?,
    description,
    property*)>
<!ATTLIST resourcedescriptor id ID #IMPLIED>

<!-- The entire point of all this... -->
<!ELEMENT resourceuri (#PCDATA)>
<!ELEMENT description (#PCDATA)>

<!ELEMENT referral (serviceref, datasetref?)>
<!ATTLIST referral id ID #IMPLIED>

<!ELEMENT status (#PCDATA)>
<!ATTLIST status code CDATA #REQUIRED>
<!ATTLIST status ref IDREF #IMPLIED>

<!-- serviceRef is used to point to one of a set of provided   -->
<!-- service objects. This is so that a resource can point to  -->
<!-- which service it came from. We could include the entire   -->
<!-- service object but then we would be repeating large       -->
<!-- amounts of information.                                   -->

<!ELEMENT serviceref EMPTY>
<!ATTLIST serviceref ref IDREF #IMPLIED>

<!ELEMENT service (serviceuri, dataset*,
   servers?,
   description?,
   property*,propertyschema?,queryschema?,resourcedescriptorschema?,
   serviceschema?)>
<!-- The time to live of the schema in seconds since it was   -->
<!-- retrieved -->
<!ATTLIST service ttl CDATA "0">
<!ATTLIST service id ID #IMPLIED>
<!ELEMENT serviceuri (#PCDATA)>
<!ELEMENT servers (server+)>
<!ELEMENT server (serveruri, property*)>
<!ELEMENT serveruri (#PCDATA)>

<!ELEMENT dataset (property*)>
<!ATTLIST dataset id ID #IMPLIED>

<!ELEMENT datasetref EMPTY>
<!ATTLIST datasetref ref IDREF #IMPLIED>

<!ELEMENT propertyschema (propertydeclaration*)>
<!ELEMENT propertydeclaration (propertyname, propertytype*)>
<!ATTLIST propertydeclaration id ID #IMPLIED>

<!ELEMENT propertyname (#PCDATA)>
<!ELEMENT propertytype (#PCDATA)>
<!-- This specifies if the type is meant to be the default -->
<!-- type. This is usually reserved for "freeform".        -->
<!ATTLIST propertytype default (no|yes) "no">

<!-- The properties you can use in a query -->
<!ELEMENT queryschema (propertyreference*)>

<!-- The properties you can expect to see in an Resource -->
<!ELEMENT resourcedescriptorschema (propertyreference*)>

<!-- The properties you can expect to find in a Service  -->
<!-- definition -->
<!ELEMENT serviceschema (propertyreference*)>

<!ELEMENT propertyreference EMPTY>
<!-- This specifies if a property is required as part of -->
<!-- the query. -->
<!ATTLIST propertyreference ref IDREF #REQUIRED>
<!ATTLIST propertyreference required (no|yes) "no">

6. Examples ๐ŸŽ€

6.1 Service Description Request

Here's what the client sends when it wants a servers schema ๐ŸŒธ

<?xml version="1.0"?>
<!DOCTYPE cnrp PUBLIC "-//IETF//DTD CNRP 1.0//EN"
 "http://ietf.org/dtd/cnrp-1.0.dtd">
<cnrp>
     <servicequery />
</cnrp>

And this is the result ๐Ÿฆ‹ Look at how the Service tag lets the service describe itself in its own terms, it's giving main character energy.

<?xml version="1.0"?>
<!DOCTYPE cnrp PUBLIC "-//IETF//DTD CNRP 1.0//EN"
 "http://ietf.org/dtd/cnrp-1.0.dtd">
<cnrp>
 <results>
  <service ttl="43200">
    <serviceuri>urn:foo:bar</serviceuri>
    <servers>
      <server>
          <serveruri>http://host1.acmecorp.com:4321/foo?</serveruri>
      </server>
      <server>
          <serveruri>smtp://host2.acmecorp.com:4321/foo?</serveruri>
      </server>
    </servers>
    <description>This is the Acme CNRP Service</description>
    <!-- This property means that Acme specializes in
         tradename services -->
    <property name="category" type="naics">544554</property>
    <property name="BannerAdServer" type="uri">
              http://adserver.acmecorp.com/
    </property>
    <propertyschema>
      <propertydeclaration id="i1">
        <propertyname>workgroupID</propertyname>
        <propertytype default="yes">freeform</propertytype>
        <propertytype default="no">domainname</propertytype>

      </propertydeclaration>
      <propertydeclaration id="i2">
        <propertyname>BannerAdServer</propertyname>
        <propertytype default="yes">URI</propertytype>
      </propertydeclaration>
    </propertyschema>
    <queryschema>
        <propertyreference ref="i1" required="yes" />
    </queryschema>
    <resourcedescriptorschema>
        <propertyreference ref="i1" required="yes" />
    </resourcedescriptorschema>
    <serviceschema>
        <propertyreference ref="i2" required="yes" />
    </serviceschema>
  </service>
 </results>
</cnrp>

6.2 Sending A Query and Getting A Response

This is the query the client sends to the server ๐Ÿ’œ

<?xml version="1.0"?>
<!DOCTYPE cnrp PUBLIC "-//IETF//DTD CNRP 1.0//EN"
 "http://ietf.org/dtd/cnrp-1.0.dtd">
<cnrp>
 <query>
    <commonname>Fido</commonname>
    <property name="geography" type="iso3166-2">
       CA-QC</property>
    <property name="geography" type="iso3166-1">CA</property>
    <property name="language" type="rfc1766">fr-CA</property>
 </query>
</cnrp>

And this is the result set that comes back in response ๐Ÿ‘‘ It includes a referral and a non-fatal error, so the server is sharing a bit of extra info without breaking anything ๐ŸŒˆ

<?xml version="1.0"?>
<!DOCTYPE cnrp PUBLIC "-//IETF//DTD CNRP 1.0//EN"
 "http://ietf.org/dtd/cnrp-1.0.dtd">
<cnrp>
  <results>
    <service id="i0">
      <serviceuri>http://acmecorp.com</serviceuri>
    </service>
    <service id="i1">

      <serviceuri>http://serverfarm.acmecorp.com</serviceuri>
    </service>
    <service id="i2">
      <serviceuri>http://servers.acmecorp.co.uk</serviceuri>
    </service>
    <resourcedescriptor>
      <commonname>Fidonet</commonname>
      <id>1333459455</id>
      <resourceuri>http://www.fidonet.ca</resourceuri>
      <serviceref ref="i0" />
      <description>This is ye olde Canadian Fidonet</description>
    </resourcedescriptor>
    <resourcedescriptor>
      <commonname>Fidonet</commonname>
      <id>1333459455</id>
      <resourceuri>http://host:port/bla</resourceuri>
      <serviceref ref="i1" />
      <description>An old Fidonet node</description>
    </resourcedescriptor>
    <referral><serviceref ref="i2" /></referral>
    <status code="3.1.1">
        The language property 'fr-CA' was ignored
    </status>
  </results>
</cnrp>

7. Transport ๐Ÿšš

Two CNRP transport protocols are specified ๐Ÿฆ‹ HTTP gets used because it's super popular and plays nicely with other web apps. SMTP is also in the mix, mostly to show what a protocol looks like when its latency is a whole different ballpark from most others.

When the transport uses MIME Media Types (HTTP and SMTP are both examples), the CNRP payload MUST use the 'application/cnrp+xml' media type. Check out Section 8 for the registration template. One important detail: since CNRP always uses UTF-8, this media type has no charset attribute ๐Ÿซถ

7.1 HTTP Transport

The HTTP transport is pretty simple ๐Ÿ’… The client connects to an HTTP based CNRP server and sends a POST request to the "/" path, with the Content-type and Accept headers both set to "application/cnrp+xml". The POST body is the CNRP XML document being sent. All HTTP 1.1 features are allowed during the request.

The results come back with a Content-Type of "application/cnrp+xml", and the body is the CNRP XML document being sent to the client.

7.2 SMTP Transport

The SMTP transport is basically the HTTP transport's twin ๐Ÿ‘ฏ Since there's no method to specify, the CNRP XML document just gets sent to a particular SMTP endpoint with its Content-Type set to "application/cnrp+xml". The server replies by sending a response to the originator of the request, with the results in the body and the Content-Type set to "application/cnrp+xml". The Service MUST specify at least one SMTP target (email address) to contact ๐Ÿ“ฌ


8. Registration: application/cnrp+xml ๐Ÿ“

This is the registration template for 'application/cnrp+xml' per [6] ๐ŸŒธ

  • MIME media type name: application
  • MIME subtype name: cnrp+xml
  • Required parameters: none
  • Optional parameters: none
  • Encoding considerations: This media type consists of 8bit text which may necessitate the use of an appropriate content transfer encoding on some transports. Since these considerations are the same as XML in general, RFC3023's [6] discussion of XML and MIME is applicable.
  • Security considerations: none specific to this media type. See Section 9 for general CNRP considerations.
  • Interoperability considerations: n/a
  • Published specification: This media type is a proper subset of the the XML 1.0 specification [8] except for the limitations placed on tags and encodings by this document.
  • Applications which use this media type: any CNRP client/server wishing to send or receive CNRP requests or responses
  • Additional Information: none
  • Contact for further information: c.f., the "Author's Address" section of this memo
  • Intended usage: limited use
  • Author/Change controller: the IESG

9. Security Considerations ๐Ÿ”

Okay, this part is serious, so please pay attention ๐Ÿ™ˆ There are three security threats for CNRP, and for any apps that rely on it: Man in the Middle attacks, malicious agents pretending to be a service by spoofing a Service object, and denial of service attacks that come from adding a new level of indirection when resolving a resource.

For Man in the Middle attacks, the proposed fix is to use transport level authentication and encryption, wherever the transport offers them. If the transport can't provide the authentication level that's required, individual entries or the whole response can be signed or encrypted using XML signature methods being developed by the XMLDSIG Working Group.

If a service tries to pose as another one by spoofing the serviceuri in its Service object, the Service object should be signed. That way a client can check the Service object's veracity by verifying the signature. How the client gets that authoritative public key is out of scope, since it depends on the service discovery problem ๐Ÿ”‘

As for Denial Of Service (DOS) attacks, this document can't propose a solution. What it can point out is that, like in many other cases, every time a new level of indirection is created, a new opportunity for a DOS attack shows up too ๐Ÿ˜ญ Service providers are encouraged to be aware of this and to act accordingly to reduce the effects of a DOS attack ๐Ÿ›ก๏ธ

10. IANA Considerations โœจ

okay so the big IANA thing is that they're registering well known properties, property types, and status messages ๐Ÿฆ‹ they are NOT registering values. And since this doc doesn't talk about CNRP service discovery, IANA isn't registering servers or Server objects either ๐Ÿ’…

There are three things IANA can register: properties, property types, and status messages. If a property or type isn't registered with IANA, it has to start with "x-" ๐ŸŒธ Status messages can be made up for local use and never registered at all. There's no requirement that new status messages be mandatory to implement unless this document gets updated. Status message registrations are mostly just for info ๐Ÿ’–

For a new property you need its name, its default type, and a general description. A new type needs its name, which properties it's valid for, and a description. A new status message needs its X.Y.ZZZ code and a short description of the state it's communicating โœจ

Everything (properties, types, status messages) gets registered First Come First Served, with no review by IANA or any expert group ๐Ÿ”ฅ The CNRP Working Group's consensus is that property registrations should get reviewed once there's real operational experience with the protocol and an actual need for it. If that policy ever needs to change, this document will be updated ๐Ÿซถ

The property and type registration templates in Appendix A should be registered by IANA when this document is published ๐ŸŽ€

IANA is also told to register the Media Type from Section 8 ๐ŸŒˆ


References ๐Ÿ“š

  • [1] United States, "North American Industry Classification System", January 1997, http://www.census.gov/epcd/www/naics.html.
  • [2] Fielding, R., Gettys, J., Mogul, J., Frystyk, H., Masinter, L., Leach, P. and T. Berners-Lee, "Hypertext Transfer Protocol -- HTTP/1.1", RFC 2616, June 1999.
  • [3] Berners-Lee, T., Fielding, R. and L. Masinter, "Uniform Resource Identifiers (URI): Generic Syntax", RFC 2396, August 1998.
  • [4] Alvestrand, H., "Tags for the Identification of Languages", RFC 1766, March 1995.
  • [5] Moats, R., "URN Syntax", RFC 2141, May 1997.
  • [6] Murata, M., St. Laurent, S. and D. Kohn, "XML Media Types", RFC 3023, January 2001.
  • [7] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997.
  • [8] Bray, T., Paoli, J. and C. Sperberg-McQueen, "Extensible Markup Language (XML) 1.0", February 1998.
  • [9] Mealling, M., "The 'go' URI Scheme for the Common Name Resolution Protocol", RFC 3368, August 2002.
  • [10] Vaudreuil, G., "Enhanced Mail System Status Codes", RFC 1893, January 1996.
  • [11] "Country and Region Codes", ISO 3166, January 1996.

Appendix A. Well Known Property and Type Registration Templates ๐Ÿงš

A.1 Properties

Here are the well known properties, each with its default type and description ๐Ÿ’œ

Property Name: geography
Default Type: iso3166-1
Description: A geographic location

Property Name: language
Default Type: rfc1766
Description: A language specification

Property Name: category
Default Type: freeform
Description: A node in some system of semantic relationships that is
considered relevant to the common-name.

Property Name: range
Default Type: range
Description: A range given in the format "x,y" where x is the
starting point and y is the length.  This property is used by the
client to tell the server that is is requesting a subrange of the
results.

Property Name: dataseturi
Default Type: uri
Description: A URI used to disambiguate between two Datasets offered
by the same Service.

A.2 Types

Now the types, and yes the lat-long one is a whole vibe ๐ŸŒท

Type: freeform
Property: category
Description: The value is to be interpreted by the server the best
way it knows how.  This value has no defined structure.

Type: freeform
Property: geography
Description: The value is to be interpreted by the server the best
way it knows how.  This value has no defined structure.

Type: freeform
Property: language
Description: The value is to be interpreted by the server the best
way it knows how.  This value has no defined structure.

Type: iso3166-2
Property: geography
Description: The combination of country and sub-region codes found in
ISO 3166-2 [11].

Type: iso3166-1
Property: Geography
Description: Country Codes found in ISO 3166-1 [11].

Type: postalcode
Property: Geography
Description: A postal code that is valid for some region.  A good
example is the Zip code system used in the US.

Type: lat-long
Property: Geography
Description:

Okay so for lat-long ๐ŸŒ latitude and longitude values shall be written as decimal fractions of degrees. Whole degrees of latitude are a two-digit decimal number from 0 through 90, and whole degrees of longitude are a decimal number from 0 through 180. If you're writing a fraction of a degree, it gets separated from the whole degrees by a decimal point. The fraction can be as precise as you want ๐Ÿค“

North of the equator gets a plus sign (+), or no minus sign (-) at all, in front of the degrees. South of the equator gets a minus sign (-) in front of the two digits. A point on the equator counts as Northern Hemisphere, so no drama there ๐ŸŒŠ

Longitudes east of the prime meridian shall be specified by a plus sign (+), or by the Longitudes west of the meridian shall be designated by minus sign (-) preceding the digits designating degrees. A point on the prime meridian counts as Eastern Hemisphere, and a point on the 180th meridian counts as Western Hemisphere. There's exactly one exception to that last rule ๐Ÿ‘‘ For describing a band of latitude around the whole earth, the East Bounding Coordinate data element shall be given the value +180 (180) degrees.

Any spatial address with a latitude of +90 (90) or -90 degrees is the North or South Pole, respectively. The longitude part can be any legal value ๐ŸงŠ

Apart from that one special case, this form comes from Department of Commerce, 1986, Representation of geographic point locations for information interchange (Federal Information Processing Standard 70-1): Washington, Department of Commerce, National Institute of Standards and Technology.

The grammar looks like this:

DEGREES   = *PLUSMINUS DIGITS '.' DIGITS
PLUSMINUS = + | -
DIGITS    = DIGIT *DIGIT
DIGIT     = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9

Back to the types list ๐Ÿ’…

Type: rfc1766
Property: Language
Description: language codes as defined by RFC 1766 [4]

Type: naics
Property: Category
Description: North American Industry Code System [1]

Type: uri
Property: dataseturi
Description: A URI adhering to the 'absoluteURI' production of the
Collected ABNF found in [3]

Appendix B. Status Codes ๐Ÿšฆ

B.1 Level 1 (Informative) Codes

1.0.0 -- Undefined Information

This one is for anything that doesn't fit a category but is still informative. If the server wanted to tell the client that the sysadmin's cat has blue hair, this is the code for that ๐Ÿˆโ€โฌ›๐Ÿ’™

This is for info about the query the client sent. Something like "The query you sent was rather interesting!" ๐Ÿคญ

1.2.0 -- An informative message pertaining to the Service

This one's about the Service in general ๐ŸŒธ

B.2 Level 2 (Success) Codes

2.0.0 -- Something undefined succeeded

Something succeeded, but what it's about isn't defined ๐ŸŽ‰

2.1.0 -- Query succeeded

The query succeeded. This message MUST be returned when no results matched the query. Basically the query was handled fine, and the correct set of results just has no resources or referrals in it. No results isn't an error, it's a successful statement about the common-name โœจ

Note: The apparent lack of 2.X.X level codes is caused by success usually being indicated not by a status message but by the server returning only the objects that the client requested.

B.3 Level 3 (Partial Success) Codes

3.0.0 -- Something undefined was only partially successful

A client request only partly worked, and the exact reason isn't defined ๐Ÿฅฒ

3.1.0 -- The query was only partially successful.

Same energy, just for queries ๐Ÿซ 

3.1.1 -- The query contained invalid or unsupported properties

The query had property names, types, or values that are invalid or unsupported. Those invalid properties got ignored and the query was still processed ๐Ÿงน

3.1.2 -- The XML was well formed but invalid

The client's XML was well formed but not valid. The server was smart enough to figure out what the client meant and still sent back some results ๐Ÿง 

3.1.3 Server does not support datasets

Servers that don't handle datasets should send this status. A server can send it at any time, but it's especially useful when a query arrives with a dataseturi in it. In that case, if the client is doing rigorous loop detection, the client should consider the whole service visited ๐Ÿ”

3.1.4 The first dataset in the list of datasets you gave in the query was the only one used.

This one's for when the client put several dataseturis in one query and the server can only handle one at a time. The server is being clear that it only used the first dataseturi. The client should consider only that first dataseturi as processed correctly, and the rest as completely ignored ๐Ÿ™ˆ

They'd need to be sent individually as referrals if the client really cares about those results. If loop detection is happening, only the first serviceuri/dataseturi pair should be marked as visited ๐ŸŽ€

3.1.5 This dataset not supported.

This means a specific dataseturi in the client's query isn't supported by the server. That serviceuri/dataseturi pair should count as visited by the client. If this comes back on a query with multiple datasets, the client should act the same as if it got 3.1.3. It should be considered bad form for a server to send this back on a multi-dataset query, since it's ambiguous ๐Ÿ˜ฌ

3.2.0 -- The server caused a partially successful event

An internal server error made the results incomplete ๐Ÿ› ๏ธ

3.2.1 -- Some referral server was unavailable

One or more of the referral services that normally get queried was unavailable. Results were still generated, but they might not be a complete answer ๐ŸŒง๏ธ

B.4 Level 4 (Transient Failure) Codes ๐ŸŒธ

okay so Level 4 is the "try again, it's not you, it's us" family ๐Ÿฅบ๐Ÿ’–

  • 4.0.0: something undefined caused a persistent transient failure ๐Ÿ’ซ
  • 4.1.0: there was an error in the query that made it unable to be interpreted ๐Ÿ™ˆ
  • 4.2.0: The query was to complex. The query as specified was too complex for this Service to handle ๐Ÿง 
  • 4.2.1: The Service was too busy. Due to resource constraints, the entire service is too busy to handle requests. That means any of the Servers cooperating in providing this Service would have also returned this same message ๐Ÿ˜ญ
  • 4.2.2: The Server is in maintenance. This server is now in maintenance mode. Try another server from this service, or try again at a later time ๐Ÿ› ๏ธ
  • 4.2.3: The Server had an internal error. There was an internal error that caused the server to fail completely ๐Ÿ’€
ngl 4.2.1 is the main character of this section. It tells you the whole service is swamped, not just one server ๐Ÿ‘‘

B.5 Level 5 (Permanent Failures) Codes ๐Ÿšซ

now Level 5 is the "nope, don't bother retrying" zone ๐Ÿฅ€

  • 5.0.0: something undefined caused a permanent failure ๐ŸŒ‘
  • 5.1.0: the query permanently failed โŒ
  • 5.2.0: the service had a permanent failure ๐Ÿชฆ
  • 5.2.1: This Service is no longer available. This Service has decided to no longer make itself available. Bye bestie ๐Ÿซ 
  • 5.2.2: The Server had a permanent failure. This server has permanently failed. Try another server from this service ๐Ÿ”„

Authors' Addresses โœจ

the authors, the vibes, the contact info, all of it ๐Ÿ’œ

Nico Popp
VeriSign, Inc.
487 East Middlefield Road
Mountain View, CA 94043

Phone: (650) 426-3291
EMail: npopp@verisign.com


Michael Mealling
VeriSign, Inc.
21345 Ridgetop Circle
Sterling, VA  20166
US

EMail: michael@verisignlabs.com


Marshall Moseley
Netword, Inc.
702 Russell Avenue
Gaithersburg, MD  20877-2606
US

Phone: (240) 631-1100
EMail: marshall@netword.com

this part is legal text, so I'm keeping it word for word so nothing gets lost in translation ๐Ÿ“œ๐Ÿซถ

   Copyright (C) The Internet Society (2002).  All Rights Reserved.

   This document and translations of it may be copied and furnished to
   others, and derivative works that comment on or otherwise explain it
   or assist in its implementation may be prepared, copied, published
   and distributed, in whole or in part, without restriction of any
   kind, provided that the above copyright notice and this paragraph are
   included on all such copies and derivative works.  However, this
   document itself may not be modified in any way, such as by removing
   the copyright notice or references to the Internet Society or other
   Internet organizations, except as needed for the purpose of
   developing Internet standards in which case the procedures for
   copyrights defined in the Internet Standards process must be
   followed, or as required to translate it into languages other than
   English.

   The limited permissions granted above are perpetual and will not be
   revoked by the Internet Society or its successors or assigns.

   This document and the information contained herein is provided on an
   "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
   TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
   BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
   HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.

Acknowledgement ๐ŸŒˆ

and last but not least, the funding shoutout ๐Ÿ’…

the RFC Editor function is currently funded by the Internet Society ๐Ÿงšโœจ

๐Ÿ“ฆ where this page comes from