of namespaces should the typical domain administrator need to use
regexps.
On a related note, beware of interactions with the shell when
manipulating regexps from the command line. Since '\' is a common
escape character in shells, there is a good chance that when you
think you are saying "\\" you are actually saying "\". Similar
caveats apply to characters such as
The "a" flag allows the next lookup to be for A records rather than
SRV records. Since there is no place for a port specification in the
NAPTR record, when the "A" flag is used the specified protocol must
be running on its default port.
The URN Sytnax draft defines a canonical form for each URN, which
requires %encoding characters outside a limited repertoire. The
regular expressions MUST be written to operate on that canonical
form. Since international character sets will end up with extensive
use of %encoded characters, regular expressions operating on them
will be essentially impossible to read or write by hand.
Usage
=====
For the edification of implementers, pseudocode for a client routine
using NAPTRs is given below. This code is provided merely as a
convience, it does not have any weight as a standard way to process
NAPTR records. Also, as is the case with pseudocode, it has never
been executed and may contain logical errors. You have been warned.
//
// findResolver(URN)
// Given a URN, find a host that can resolve it.
//
findResolver(string URN) {
// prepend prefix to urn.net
sprintf(key, "%s.urn.net", extractNS(URN));
do {
RFC 2168 Resolution of URIs Using the DNS June 1997
rewrite_flag = false;
terminal = false;
if (key has been seen) {
quit with a loop detected error
}
add key to list of "seens"
records = lookup(type=NAPTR, key); // get all NAPTR RRs for 'key'
discard any records with an unknown value in the "flags" field.
sort NAPTR records by "order" field and "preference" field
(with "order" being more significant than "preference").
n_naptrs = number of NAPTR records in response.
curr_order = records[0].order;
max_order = records[n_naptrs-1].order;
// Process current batch of NAPTRs according to "order" field.
for (j=0; j < n_naptrs && records[j].order <= max_order; j++) {
if (unknown_flag) // skip this record and go to next one
continue;
newkey = rewrite(URN, naptr[j].replacement, naptr[j].regexp);
if (!newkey) // Skip to next record if the rewrite didn't
match continue;
// We did do a rewrite, shrink max_order to current value
// so that delegation works properly
max_order = naptr[j].order;
// Will we know what to do with the protocol and services
// specified in the NAPTR? If not, try next record.
if(!isKnownProto(naptr[j].services)) {
continue;
}
if(!isKnownService(naptr[j].services)) {
continue;
}
// At this point we have a successful rewrite and we will
// know how to speak the protocol and request a known
// resolution service. Before we do the next lookup, check
// some optimization possibilities.
if (strcasecmp(flags, "S")
|| strcasecmp(flags, "P"))
|| strcasecmp(flags, "A")) {
terminal = true;
services = naptr[j].services;
addnl = any SRV and/or A records returned as additional
info for naptr[j].
}
key = newkey;
RFC 2168 Resolution of URIs Using the DNS June 1997
=9= |