RFC 2163

Using the Internet DNS to Distribute MIXER Conformant Global Address Mapping (MCGAM)

๐Ÿ“… published January 1998, from ietf

RFC 2163 ๐Ÿ’– Okay bestie, this one is a Standards Track doc from the Network Working Group, written by C. Allocchio of GARR-Italy ๐ŸŽ€

It's dated January 1998 ๐Ÿ—“๏ธ and it obsoletes RFC1664 ๐Ÿซถ, so that one is getting replaced, periodt ๐Ÿ’…

Using the Internet DNS to Distribute MIXER Conformant Global Address Mapping (MCGAM) ๐Ÿฆ‹

Status of This Memo โœจ

Okay so this doc is an Internet standards track protocol for the whole Internet community, and it's literally asking everyone to chime in with discussion and suggestions for improvements ๐Ÿ—ฃ๏ธ๐Ÿ’–. For the standardization state and status of this protocol, check the current edition of the "Internet Official Protocol Standards" (STD 1) ๐Ÿ“œ. Distribution of this memo is unlimited ๐ŸŒธ.

Copyright (C) The Internet Society (1998). All Rights Reserved. ๐Ÿ’œ

Abstract ๐ŸŒธ

This memo is the complete technical spec for storing the mapping info (MCGAM) in the Internet Domain Name System (DNS). MIXER-conformant e-mail gateways and other tools need that info to map RFC822 domain names into X.400 O/R names and back again ๐Ÿ’Œ. The mapping info can be managed in a distributed way instead of a centralised one ๐ŸŒˆ. Organizations can publish their MIXER mapping or preferred gateway routing info using just local resources (their own local DNS server), so there's no need for heavy coordination with any centralised organization ๐Ÿ’…. MIXER gateways and tools on Internet hosts can grab the mapping info by querying the DNS, instead of relying on fixed tables that have to be centrally updated and distributed ๐Ÿ™Œ.

This memo obsoletes RFC1664 ๐Ÿซถ. It includes the changes the MIXER spec introduced with respect to RFC1327: the new 'gate1' (O/R addresses to domain) table is fully supported โœจ. Full backward compatibility with the RFC1664 spec is maintained too ๐Ÿ’–.

RFC1664 was a joint effort of the IETF X400 operation working group (x400ops) and the TERENA (formerly named "RARE") Mail and Messaging working group (WG-MSG) ๐Ÿค. This update was done by the IETF MIXER working group ๐ŸŽ‰.

1. Introduction ๐ŸŒท

The connectivity between Internet SMTP mail and other mail services, including Internet X.400 mail and the commercial X.400 service providers, is assured by the Mail eXchanger (MX) record info distributed via the Internet DNS ๐Ÿ“ฌ. A number of documents then spell out in detail how to convert or encode addresses from/to RFC822 style into the other mail system's syntax ๐Ÿงฉ. But only conversion methods that use some algorithm or a set of mapping rules give a smooth translation, resulting in addresses that are indistinguishable from the native ones in both the RFC822 and foreign worlds โœจ.

MIXER describes a set of mappings (MIXER Conformant Global Address Mapping - MCGAM) that will enable interworking between systems running the CCITT X.400 (1984/88/92) Recommendations and systems using the RFC822 mail protocol, or protocols derived from RFC822 ๐Ÿ’…. That document covers conversion of services, addresses, message envelopes, and message bodies between the two mail systems ๐Ÿซง. This doc is about just one piece of MIXER: the mechanism for mapping between X.400 O/R addresses and RFC822 domain names ๐Ÿ”. As described in Appendix F of MIXER, implementing the mappings requires a database that maps between X.400 O/R addresses and domain names. In RFC1327, this database was statically defined ๐Ÿ“š.

The original approach in RFC1327 took a LOT of effort to maintain the correct mapping ๐Ÿ˜ฉ. All the gateways needed to get coherent tables to apply the same mappings, the conversion tables had to be distributed among all the operational gateways, and every update also needed to be distributed ๐Ÿ“ฆ.

The mapping rules distribution concept got a glow-up in the new MIXER spec ๐Ÿ’ซ, which introduces the concept of MIXER Conformant Global Address Mapping (MCGAM). An MCGAM no longer has to be globally installed by every MIXER conformant gateway in the world ๐ŸŒ. However, MIXER now needs efficient methods to publish its MCGAM ๐Ÿ“ฃ.

Static tables are one possible method to publish MCGAM. But this static mechanism takes quite a long time to modify and distribute the info, which puts heavy constraints on the time schedule of every update โณ. In fact, it doesn't appear efficient compared to the Internet Domain Name Service (DNS) ๐Ÿ™ƒ. Moreover, it doesn't look feasible to distribute the database to a large number of other useful applications, like local address converters, e-mail User Agents, or any other tool that needs the mapping rules to produce correct results ๐Ÿ“ฑ.

MIXER proposes two much more efficient methods for publishing MCGAM: the Internet DNS and X.500 ๐Ÿš€. This memo is the complete technical spec for publishing MCGAM via the Internet DNS ๐Ÿ’–.

A first proposal to use the Internet DNS to store, retrieve, and maintain those mappings was introduced by two of the RFC1664 authors (B. Cole and R. Hagens) ๐Ÿ‘ฏ. It adopted two new DNS resource record (RR) types: TO-X400 and TO-822. This proposal now takes a more complete strategy and requires only one new RR ๐ŸŽฏ. Distributing MCGAMs via DNS is an important service for the whole Internet community โœจ. It completes the info given by the MX resource record, and it lets you produce clean addresses when messages are exchanged between the Internet RFC822 world and the X.400 one (both Internet and Public X.400 service providers) ๐Ÿ’Œ.

A first experiment in using the DNS without expanding the current set of RRs, using available ones instead, was deployed by some of the RFC1664 authors when it was being developed ๐Ÿงช. The existing PTR resource records were used to store the mapping rules, and a new DNS tree was created under the .it top level domain ๐Ÿ‡ฎ๐Ÿ‡น. The result was positive, and a few test applications ran under this provisional setup ๐Ÿฅณ. This test was also really useful for defining a possible migration strategy during the deployment of the new DNS containing the new RR ๐Ÿ›ฃ๏ธ. The Internet DNS nameservers that want to provide this mapping info need to be modified to support the new RR type, and in the real Internet, because of the large number of different implementations, this takes some time โŒ›.

The basic idea is to adopt a new DNS RR to store the mapping info ๐Ÿ’ก. The RFC822-to-X.400 mapping rules (including the so-called gate2 rules) will be stored in the ordinary DNS tree. Meanwhile, a new branch of the name space, defined under each national top level domain, is envisaged to contain the X.400-to-RFC822 mappings (table1 and gate1) ๐ŸŒณ. A "two-way" mapping resolution schema is thus fully implemented ๐Ÿ”.

Creating the new domain name space that represents the X.400 O/R names structure also gives a chance to use the DNS to dynamically distribute other X.400-related info. That solves other efficiency problems currently affecting the X.400 MHS service ๐Ÿง .

In this paper we will adopt the MCGAM syntax, showing how it can be stored in the Internet DNS ๐Ÿ“.

1.1 Definitions syntax ๐Ÿงฉ

The definitions in this document are given in BNF-like syntax, using the following conventions:

   |   means choice
   \   is used for continuation of a definition over several lines
   []  means optional
   {}  means repeated one or more times

The definitions, however, are detailed only until a certain level, and below it, self-explaining character text strings will be used ๐Ÿ’….

2. Motivation ๐Ÿฆ‹

Implementations of MIXER gateways require that a database store address mapping info for X.400 and RFC822. This info must be made available (published) to all MIXER gateways ๐Ÿ“ข. In the Internet community, the DNS has proven to be a practical means of providing a distributed name service ๐Ÿ’–. Advantages of using a DNS-based system over a table-based approach for mapping between O/R addresses and domain names are:

  • It avoids fetching and storing of entire mapping tables by every host that wishes to implement MIXER gateways and/or tools ๐Ÿ™Œ
  • Modifications to the DNS-based mapping info can be made available in a more timely manner than with a table-driven approach. โฐ
  • It allows full authority delegation, in agreement with the Internet regionalization process. ๐ŸŒ
  • Table management is not necessarily required for DNS-based MIXER gateways. ๐Ÿซถ
  • One can determine the mappings in use by a remote gateway by querying the DNS (remote debugging). ๐Ÿ”Ž

Also, many other tools, like address converters and User Agents, can take advantage of the real-time availability of MIXER tables, allowing much easier maintenance of the information ๐Ÿ’…โœจ

3. The domain space for X.400 O/R name addresses โœจ

okay so, regular domain names (the ones you see after the @ in an RFC822 email address) and all their info, like host IP addresses, mail exchanger names, etc., live in the DNS as one big distributed database spread across a bunch of top-level domains ๐ŸŒธ. Some are for traditional categories or international orgs (EDU, COM, NET, ORG, INT, MIL...). Then every country gets its own two letter ISO country code as a top-level domain (FR, DE, GB, IT, RU, ...), and yes, that includes "US" for USA ๐Ÿ‡บ๐Ÿ‡ธ. The special IN-ADDR.ARPA top-level/second-level pair is where the IP address to domain name relationship is stored ๐Ÿฆ‹. This memo says how to slot the X.400 O/R name space into that structure, so the MIXER mappings (MCGAMs) can be stored in DNS ๐Ÿ’œ.

The MIXER mapping info is made of four tables:

  • 'table1' and 'gate1' give the translation from X.400 to RFC822;
  • 'table2' and 'gate2' map RFC822 into X.400.

Each mapping table is a bunch of mapping rules, and each rule is a keyword (the argument of the mapping function, pulled from the address being translated) plus a translator (the mapping function parameter) ๐Ÿงš:

keyword#translator#

The '#' sign is a delimiter that wraps the translator. Here's an example:

foo.bar.us#PRMD$foo\.bar.ADMD$intx.C$us#

Local mappings are not meant to leave their restricted environment, so they should not be included in DNS ๐Ÿ™ˆ. If you do use local mappings, store them in static local tables, the same way local static host tables can be used alongside DNS.

The keyword of a 'table2' or 'gate2' entry is a valid RFC822 domain, so the usual domain name space works just fine for storing these entries ๐Ÿ’…. The keyword of a 'table1' or 'gate1' entry, though, belongs to the X.400 O/R name space. That space doesn't usually fit neatly into the regular domain name space, even though there are some similarities, so it needs a new name structure to represent it. This new structure holds the X.400 mail domains ๐ŸŽ€.

To keep DNS working properly, the new X.400 name structure has to be hooked onto the existing domain name space in a way that respects the existing name hierarchy ๐Ÿ‘‘.

One option was to make another special branch starting from the root of the DNS tree, kinda like the in-addr.arpa tree. But that would need a central authority to coordinate the management of every national X.400 name tree at the international level, including the X.400 public service providers. Doing that globally is a seriously heavy lift ๐Ÿ˜ญ. Plus, the X.400 name structure is very 'country oriented'. It needs coordination at the national level, but it doesn't have the idea of an international root at all. The X.400 international service really runs on a big pile of bilateral agreements, and only some communities have an international coordination service ๐Ÿ’€.

The good news is that the X.400 two letter ISO country codes are the same ones used for the RFC822 country top-level domains, which gives us the perfect hook to insert new branches โœจ. So the proposal is to create, under each national top-level ISO country code, a new branch in the name space. That branch mirrors the X.400 O/R name structure as defined in each country, following the ADMD, PRMD, O, OU hierarchy ๐ŸŒˆ. A single reserved label, 'X42D', goes under each country top-level domain, and the national X.400 name space builds its own structure from there:

                                . (root)
                                |
   +-----------------+-----------+--------+-----------------+...
   |                 |                    |                 |
  edu                it                   us                fr
   |                 |                    |                 |
+---+---+...    +-----+-----+...     +-----+-----+...     +--+---+...
|       |       |     |     |        |     |     |        |      |
...     ...     cnr   X42D  infn      va    ca   X42D     X42D  inria
                     |                    |     |        |
        +------------+------------+...   ...   ...  +----+-------+...
        |            |            |                 |            |
 ADMD-PtPostel  ADMD-garr  ADMD-Master400        ADMD-atlas  ADMD-red
                     |            |                 |            |
          +----------+----+...   ...        +-------+------+... ...
          |               |                 |              |
      PRMD-infn       PRMD-STET        PRMD-Telecom   PRMD-Renault
          |               |                 |              |
         ...             ...               ...            ...

Creating the X.400 name tree at the national level solves the international coordination problem ๐Ÿฆ‹. Honestly, the coordination problem just gets moved down to the national level, but at that level it's way easier to deal with ๐Ÿ˜Œ. Coordination at the national level between the X.400 communities and the Internet world is already needed to create the national static MIXER mapping tables, and using Internet DNS adds even more reasons to do it ๐Ÿซถ.

That national coordination also fits the new idea of MCGAM publication ๐Ÿ“ฃ. DNS allows a step-by-step distribution of authority, all the way up to a final complete delegation. So organisations that want to publish their MCGAM just need to get delegation for their branch of the new X.400 name space ๐Ÿ’œ. Going national also lets each country build its own X.400 name structure in DNS and roll out its own authority delegation on its own timeline and with its own requirements, with no loss of global service in the meantime โญ. And, last but not least, putting the new X.400 name tree and its coordination at the national level fits the wider Internet regionalization and internationalisation trend, because local bodies can handle local coordination problems ๐Ÿ“.

Here's the vibe: the DNS name space now holds everything an e-mail gateway or tool needs to do the X.400-RFC822 mapping. One simple query to the nearest nameserver gets it all ๐Ÿงš. There's no more need to store, maintain, and distribute mapping tables by hand ๐Ÿ™Œ. The new X.400 name space can also hold extra info about the X.400 community, since DNS supports a full set of resource records, which leaves room for future developments ๐ŸŒธ. For now, this set of RRs in the new X.400 name space must be considered 'reserved', so don't use them until further specifications come out ๐Ÿ”’.

Building the new domain space trees follows the same playbook used when the existing DNS space was first organised ๐Ÿ“š. Info starts out stored in a fairly centralised way, and authority gets distributed bit by bit over time. A separate document will cover the implementation phase and how to make the new service roll out smoothly ๐Ÿ’–.


4. The new DNS resource record for MIXER mapping rules: PX ๐Ÿ’…

The Internet DNS spec (RFC1035) gives us a bunch of resource records (RRs) for specific pieces of info ๐Ÿ“–. The big ones here are the Mail eXchanger (MX) RR and the host Address (A) records, which Internet SMTP mailers use ๐Ÿ“ฌ. Since we're going to store the RFC822 to X.400 mapping info in the existing DNS name tree, we need a brand new DNS RR so we don't clash with or misuse any data structures that already exist ๐Ÿ™…โ€โ™€๏ธ. That same new RR will also hold the mappings going from X.400 to RFC822 ๐Ÿ”. On top of that, the mapping info (the MCGAMs) has a very specific format and syntax, so it needs its own data structure and processing ๐Ÿงฉ. Defining a new RR also gives us flexibility for whatever future development comes along ๐Ÿฆ‹.

So the definition of the new 'PX' DNS resource record is:

   class:        IN   (Internet)

   name:         PX   (pointer to X.400/RFC822 mapping information)

   value:        26

The PX RDATA format looks like this:

       +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
       |                  PREFERENCE                   |
       +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
       /                    MAP822                     /
       /                                               /
       +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
       /                    MAPX400                    /
       /                                               /
       +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

where:

  • PREFERENCE: A 16 bit integer that sets how much this RR is preferred over the others at the same owner. Lower values are preferred ๐Ÿ†.
  • MAP822: A <domain-name> element containing <rfc822-domain>, which is the RFC822 part of the MCGAM ๐Ÿ’Œ.
  • MAPX400: A <domain-name> element containing the value of <x400-in-domain-syntax>, derived from the X.400 part of the MCGAM (see sect. 4.2) ๐ŸŒˆ.

PX records cause no additional section processing ๐Ÿ™Œ. The PX RR format is the usual one:

<name> [<class>] [<TTL>] <type> <RDATA>

When we store a 'table1' or 'gate1' entry in DNS, <name> will be an X.400 mail domain name in DNS syntax (see sect. 4.2) ๐ŸŽ€. When we store a 'table2' or 'gate2' entry, <name> will be an RFC822 mail domain name, covering both fully qualified DNS domains and mail-only domains (MX-only domains) ๐Ÿ’œ. All the normal DNS conventions, like default values, wildcards, abbreviations, and message compression, also apply to every part of the PX RR โœจ. In particular, <name>, MAP822, and MAPX400, as <domain-name> elements, must have the final "." (root) when they're fully qualified ๐Ÿซถ.

4.1 Additional features of the PX resource record โœจ

okay so the PX RDATA definition is giving major glow-up energy ๐Ÿ’… and it's built on something DNS already does: it can tell an exact value apart from a wildcard match for the <name> parameter. That makes it an extension of the MIXER mapping rules, and I'm obsessed ๐Ÿซถ

here's the tea. any MCGAM entry is an implicit wildcard entry ๐Ÿ™ˆ so this rule:

net2.it#PRMD$net2.ADMD$p400.C$it#

covers any RFC822 domain ending with 'net2.it', unless there are more detailed rules for some subdomain in 'net2.it'. which means there's no way to write a MCGAM as an exact-match-only rule. in DNS, an entry like this:

*.net2.it.   IN  PX  10   net2.it.  PRMD-net2.ADMD-p400.C-it.

gives you the usual wildcard match, same as MIXER tables. but an entry like this:

ab.net2.it.  IN  PX  10   ab.net2.it.  O-ab.PRMD-net2.ADMDb.C-it.

is valid only for an exact match of the 'ab.net2.it' RFC822 domain. main character energy โœจ

also, in DNS syntax there's no '#' delimiter around the MAP822 and MAPX400 fields ๐ŸŽ€ the syntax in sect. 4.2 doesn't allow the <blank> (ASCII decimal 32) character inside these fields, so the explicit delimiter MIXER needed in its original syntax isn't needed anymore. slay ๐Ÿ“

another upgrade is the PREFERENCE value, which is part of the PX RDATA section. it has exactly the same meaning as the one used for the MX RR ๐Ÿฆ‹ so you can have more than one mapping for a domain (from RFC822 to X.400 and vice versa), and the preference value gives the order. in MIXER static tables, though, you can't specify more than one mapping per RFC822 domain, and the same restriction applies to any X.400 domain mapping to an RFC822 one ๐Ÿ˜ญ

and the X.400 recommendations have a note suggesting that an ADMD=<blank> should be reserved for some special cases. various national functional profile specifications for an X.400 MHS say that if an X.400 PRMD is reachable through any of its national ADMDs, no matter whether it's single or multiply connected to them, it should use ADMD=<blank> to advertise that. and if a PRMD has no connections to any ADMD, it should use ADMD=0 to show its status, etc. but in most real situations today, ADMD service providers won't accept messages from their subscribers if they have a blank ADMD, so those subscribers have to have their own ADMD value. in that case it's hard to properly show the mappings that actually work for domains with multiple connectivity. the PX RDATA 'PREFERENCE' extension was introduced to deal with these problems ๐Ÿ’œ

ngl though, these extensions aren't available with MIXER static tables, so it's strongly discouraged to use them when interworking with any table based gateway or application ๐Ÿ’€ they were added to give more flexibility, like the PREFERENCE value, or they were already implicit in the DNS mechanism, like the wildcard specification. they should be used very carefully or just considered 'reserved for future use'. specifically, for current use, the PREFERENCE value in the PX record specification should be fixed to a value of 50, and only wildcard specifications should be used when specifying <name> values ๐ŸŒธ

4.2 The DNS syntax for an X.400 'domain' ๐Ÿงš

the syntax for MCGAM rules is defined in appendix F of that document. but that syntax isn't very human oriented, and it has a bunch of characters that have a special meaning in other fields of the Internet DNS ๐Ÿ˜ต so to avoid any possible problems, especially with some old DNS implementations still in use on the Internet, we define a syntax for the X.400 part of any MCGAM rule (and so for any X.400 O/R name) that's compatible with a <domain-name> element:

<domain-name>    ::= <subdomain> | " "
<subdomain>      ::= <label> | <label> "." <subdomain>
<label>          ::= <alphanum>|
                     <alphanum> {<alphanumhyphen>} <alphanum>
<alphanum>       ::= "0".."9" | "A".."Z" | "a".."z"
<alphanumhyphen> ::= "0".."9" | "A".."Z" | "a".."z" | "-"

(see RFC1035, section 2.3.1, page 8). the legal character set for <label> doesn't match the IA5 Printablestring one that MIXER uses to define MCGAM rules ๐Ÿ˜ฌ but a very simple "escape mechanism" gets around that. we can describe the X.400 part of a MCGAM rule format like this:

<map-rule>   ::= <map-elem> | <map-elem> { "." <map-elem> }
<map-elem>   ::= <attr-label> "$" <attr-value>
<attr-label> ::= "C" | "ADMD" | "PRMD" | "O" | "OU"
<attr-value> ::= " " | "@" | IA5-Printablestring

you'll notice <domain-name> and <map-rule> look alike, and <label> and <map-elem> look the same too ๐Ÿ‘€ so if we define the right way to turn a <map-elem> into a <label> and back, the problem of writing a MCGAM rule in <domain-name> syntax is solved โœจ

the RFC822 domain part of any MCGAM rule is already in <domain-name> syntax, so it stays unchanged ๐Ÿฆ‹

specifically, in a 'table1' or 'gate1' mapping rule, the 'keyword' value has to be converted into <x400-in-domain-syntax> (X.400 mail DNS mail domain), while the 'translator' value is already a valid RFC822 domain. and the other way round: in a 'table2' or 'gate2' mapping rule, the 'translator' has to be converted into <x400-in-domain-syntax>, while the 'keyword' is already a valid RFC822 domain ๐ŸŽ€

4.2.1 IA5-Printablestring to <alphanumhyphen> mappings ๐Ÿ“

the mismatch between the IA5-Printablestring and <label> character sets is fixed with a simple character mapping rule: whenever an IA5 character doesn't belong to <alphanumhyphen>, it gets mapped using its 3 digit decimal ASCII code, wrapped in hyphens. there's also a small set of special rules for the most frequent cases. and some common character combinations used in MIXER rules are mapped as special cases too ๐Ÿ’…

let's define the simple rules:

MCGAM rule            DNS store translation    conditions
-----------------------------------------------------------------
<attr-label>$@        <attr-label>             missing attribute
<attr-label>$<blank>  <attr-label>"b"          blank attribute
<attr-label>$xxx      <attr-label>-xxx         elsewhere

non <alphanumhyphen> characters in <attr-value>:

MCGAM rule            DNS store translation    conditions
-----------------------------------------------------------------
-                     -h-                      hyphen
\.                    -d-                      quoted dot
<blank>               -b-                      blank
<non A/N character>   -<3digit-decimal>-       elsewhere

if the DNS store translation of <attr-value> ends with a hyphen, then that last hyphen is omitted ๐Ÿซถ

now some examples, bestie:

MCGAM rule            DNS store translation    conditions
-----------------------------------------------------------------
PRMD$@                PRMD                     missing attribute
ADMD$<blank>          ADMDb                    blank attribute
ADMD$400-net          ADMD-400-h-net           hyphen mapping
PRMD$UK\.BD           PRMD-UK-d-BD             quoted dot mapping
O$ACME Inc\.          O-ACME-b-Inc-d           blank & final hyphen
PRMD$main-400-a       PRMD-main-h-400-h-a      hyphen mapping
O$-123-b              O--h-123-h-b             hyphen mapping
OU$123-x              OU-123-h-x               hyphen mapping
PRMD$Adis+co          PRMD-Adis-043-co         3digit mapping

so an X.400 part from a MCGAM like this:

OU$uuu.O$@.PRMD$ppp\.rrr.ADMD$aaa ddd-mmm.C$cc

translates to:

OU-uuu.O.PRMD-ppp-d-rrr.ADMD-aaa-b-ddd-h-mmm.C-cc

and another one:

OU$sales dept\..O$@.PRMD$ACME.ADMD$ .C$GB

translates to:

OU-sales-b-dept-d.O.PRMD-ACME.ADMDb.C-GB

4.2.2 Flow chart ๐ŸŒˆ

to get the right DNS store translations for the X.400 part of a MCGAM (or any other X.400 O/R name), some software tools will be used. it's honestly obvious that the above rules for converting mapping tables from MIXER to DNS format (and back) aren't user friendly enough for a human to do the conversion by hand ๐Ÿ˜ญ

to help design those tools, here's a small flow chart. the fundamental rule to apply during translation is, however, this one:

"A string must be parsed from left to right, moving appropriately the pointer in order not to consider again the already translated left section of the string in subsequent analysis."

Flow chart 1 - Translation from MIXER to DNS format:

             parse  single attribute
          (enclosed in "." separators)
                       |
        (yes)  ---  <label>$@ ?  ---  (no)
          |                             |
    map to <label>        (no)  <label>$<blank> ?  (yes)
          |                 |                        |
          |           map to <label>-        map to <label>"b"
          |                 |                        |
          |           map "\." to -d-                |
          |                 |                        |
          |           map "-" to -h-                 |
          |                 |                        |
          |    map non A/N char to -<3digit>-        |
restart   |                 |                        |
 ^        |      remove (if any) last "-"            |
 |        |                 |                        |
 |        \------->     add a  "."    <--------------/
 |                          |
 \----------  take  next  attribute  (if  any)

Flow chart 2 - Translation from DNS to MIXER format:

            parse single attribute
        (enclosed in "." separators)
                      |
        (yes) ---- <label> ? ---- (no)
          |                          |
  map to <label>$@        (no) <label>"b" ? (yes)
          |                 |                 |
          |           map to <label>$    map to <label>$<blank>
          |                 |                 |
          |           map -d- to "\."         |
          |                 |                 |
          |           map -h- to "-"          |
          |                 |                 |
          |           map -b- to " "          |
restart   |                 |                 |
 ^        |   map -<3digit>- to non A/N char  |
 |        |                 |                 |
 |        \-------->   add a "."   <----------/
 |                         |
 \------------- take next attribute (if any)

note that the above flow charts only deal with translating the attribute syntax ๐ŸŽ€

4.2.3 The Country Code convention in the <name> value โœจ

Okay so the RFC822 domain space and the X.400 O/R address space (remember section 3!) have one super specific thing in common: the X.400 ISO country codes are literally the same as the RFC822 ISO top level domains for countries ๐ŸŒ. Earlier we worked out how to write any X.400 domain in <domain-name> syntax, and section 3 described the new name space that starts at each country top level domain under X42D.cc (where 'cc' is the two letter ISO country code) ๐ŸŽ€.

So the <name> value for a 'table1' or 'gate1' entry in DNS should be built from the X.400 domain, translated into <domain-name> syntax, with 'X42D.cc.' tacked on the end. For example:

ADMD$acme.C$fr

produces this in <domain-name> syntax:

ADMD-acme.C-fr

and then gets post-fixed with 'X42D.fr.', giving:

ADMD-acme.C-fr.X42D.fr.

Here's the tea ๐Ÿซ–: because X.400 country codes and RFC822 country top level domains are encoded identically, the 'C-fr.X42D.fr.' bit is clearly redundant ๐Ÿ™„.

So we define the 'Country Code convention' for the <name> key, and it goes like this:

"The C-cc section of an X.400 domain in <domain-name> syntax must be omitted when creating a <name> key, as it is identical to the top level country code used to identify the DNS zone where the information is stored".

Thus we get these <name> key examples, and honestly they look so much cleaner ๐Ÿ’…:

X.400 domain                       DNS <name> key
--------------------------------------------------------------------
ADMD$acme.C$fr                     ADMD-acme.X42D.fr.
PRMD$ux\.av.ADMD$ .C$gb            PRMD-ux-d-av.ADMDb.X42D.gb.
PRMD$ppb.ADMD$Dat 400.C$de         PRMD-ppb.ADMD-Dat-b-400.X42D.de.

4.3. Creating the appropriate DNS files

Okay, so MIXER assumes the mapping between X.400 and RFC822 addresses is asymmetric ๐Ÿฆ‹. That means you need two separate relations to store the mapping database: MIXER 'table1' and MIXER 'table2'. So in DNS we keep two different sections too, even though both of them use the PX resource record ๐Ÿงš. MIXER also specifies two extra tables, 'gate1' and 'gate2'. These have the same syntax rules as 'table1' and 'table2' respectively, so the same translation procedure gets applied to them. We'll talk about the 'gate1' and 'gate2' details in section 4.4 ๐Ÿ’–.

Let's check how to create the right DNS entry from an MCGAM entry. We can once again define an MCGAM entry as in appendix F of that document, like this:

<x400-domain>#<rfc822-domain>#  (case A: 'table1' and 'gate1' entry)

and this:

<rfc822-domain>#<x400-domain>#  (case B: 'table2' and 'gate2' entry)

The two cases have to be handled separately, so let's start with case A ๐ŸŽฏ.

  • Take <x400-domain> and translate it into <domain-name> syntax, which gives you <x400-in-domain-syntax>.
  • Build the <name> key from <x400-in-domain-syntax>, which means applying the Country Code convention from sect. 4.2.3.
  • Construct the DNS PX record like this:
*.<name>  IN  PX  50  <rfc822-domain>  <x400-in-domain-syntax>

Please note that inside PX RDATA, <rfc822-domain> comes before <x400-in-domain-syntax>, and that's true for 'table1' and 'gate1' entries too ๐Ÿ‘€.

Here's an example. From the 'table1' rule:

PRMD$ab.ADMD$ac.C$fr#ab.fr#

we get:

*.PRMD-ab.ADMD-ac.X42D.fr. IN PX 50  ab.fr.  PRMD-ab.ADMD-ac.C-fr.

Also, <name>, <rfc822-domain> and <x400-in-domain-syntax> are all fully qualified <domain-name> elements, so they all end with a "." ๐ŸŒธ.

Now for case B ๐Ÿง.

  • Take <rfc822-domain> as the <name> key.
  • Translate <x400-domain> into <x400-in-domain-syntax>.
  • Construct the DNS PX record like this:
*.<name>  IN  PX  50  <rfc822-domain>  <x400-in-domain-syntax>

For example, from the 'table2' rule:

ab.fr#PRMD$ab.ADMD$ac.C$fr#

we get:

*.ab.fr.  IN  PX  50  ab.fr.  PRMD-ab.ADMD-ac.C-fr.

Again, notice the fully qualified <domain-name> elements ๐Ÿ™ˆ.

A file with the MIXER mapping rules and the MIXER 'gate1' and 'gate2' tables written in DNS format would look something like this. It's a fictitious example, so don't copy it into production ๐Ÿ˜ญ:

!
! MIXER table 1: X.400 --> RFC822
!
*.ADMD-acme.X42D.it.               IN  PX  50  it. ADMD-acme.C-it.
*.PRMD-accred.ADMD-tx400.X42D.it.  IN  PX  50   \
                          accred.it. PRMD-accred.ADMD-tx400.C-it.
*.O-u-h-newcity.PRMD-x4net.ADMDb.X42D.it.  IN  PX  50   \
                  cs.ncty.it. O-u-h-newcity.PRMD-x4net.ADMDb.C-it.
!
! MIXER table 2: RFC822 --> X.400
!
*.nrc.it.    IN  PX  50   nrc.it. PRMD-nrc.ADMD-acme.C-it.
*.ninp.it.   IN  PX  50   ninp.it. O.PRMD-ninp.ADMD-acme.C-it.
*.bd.it.     IN  PX  50   bd.it. PRMD-uk-d-bd.ADMDb.C-it.
!
! MIXER Gate 1 Table
!
*.ADMD-XKW-h-Mail.X42D.it.         IN  PX  50   \
                       XKW-gateway.it. ADMD-XKW-h-Mail.C-it.G.
*.PRMD-Super-b-Inc.ADMDb.X42D.it.  IN  PX  50   \
                       GlobalGw.it. PRMD-Super-b-Inc.ADMDb.C-it.G.
!
! MIXER Gate 2 Table
!
my.it.  IN PX 50  my.it. OU-int-h-gw.O.PRMD-ninp.ADMD-acme.C-it.G.
co.it.  IN PX 50  co.it. O-mhs-h-relay.PRMD-x4net.ADMDb.C-it.G.

(Quick note: the "" just means "continued on the same line". The wrapping only happens because of typography ๐Ÿ“.)

Watch out for that ".G." suffix on the right side of the 'gate1' and 'gate2' tables! Its job is described in section 4.4 ๐Ÿ‘€. The matching MIXER tables look like this:

#
# MIXER table 1: X.400 --> RFC822
#
ADMD$acme.C$it#it#
PRMD$accred.ADMD$tx400.C$it#accred.it#
O$u-newcity.PRMD$x4net.ADMD$ .C$it#cs.ncty.it#
#
# MIXER table 2: RFC822 --> X.400
#
nrc.it#PRMD$nrc.ADMD$acme.C$it#
ninp.it#O.PRMD$ninp.ADMD$acme.C$it#
bd.it#PRMD$uk\.bd.ADMD$ .C$it#
#
# MIXER Gate 1 Table
#
ADMD$XKW-Mail.C$it#XKW-gateway.it#
PRMD$Super Inc.ADMD$ .C$it#GlobalGw.it#
#
# MIXER Gate 2 Table
#
my.it#OU$int-gw.O$@.PRMD$ninp.ADMD$acme.C$it#
co.it#O$mhs-relay.PRMD$x4net.ADMD$ .C$t#

4.4. Storing the MIXER 'gate1' and 'gate2' tables

Okay, so section 4.3.4 of MIXER explains how an address should be converted between RFC822 and X.400 when a complete mapping is impossible ๐Ÿ™…. To let DDAs be used for domains that can't be mapped, the MIXER 'gate2' table gets introduced ๐ŸŽ€.

It's a similar story in the other direction. When an X.400 address can't be fully converted into RFC822, section 4.3.5 of MIXER tells you how to encode the address itself (that's the LHS encoding), and then point to the right MIXER conformant gateway, which is listed in the MIXER 'gate1' table โœจ.

DNS has to store and distribute these 'gate1' and 'gate2' data too ๐Ÿ“ฆ.

The DNS has this amazing feature where it distributes authority. A certain site runs the "primary" nameserver for one particular sub-tree, which makes it the only place allowed to update information about that sub-tree ๐Ÿ‘‘. For us, that means we get an extra bonus on top of the table-based approach: we can dodge one possible ambiguity about how the 'gate1' and 'gate2' tables get used (and therefore how LHS and DDA encoding get used) ๐Ÿซถ.

The authority that maintains a DNS entry in the usual RFC822 domain space is the only one allowed to decide whether its domain gets mapped using Standard Attributes (SA) syntax or Domain Defined Attributes (DDA) syntax. If it picks SA, the PX RDATA will be a 'table2' entry. Otherwise, it'll be a 'gate2' table entry. So for an RFC822 domain, you can never have both a 'table2' entry and a 'gate2' entry, and that makes the gateway's action clearly stated ๐Ÿ’….

Same deal for the new X.400 name space. The authority that maintains a DNS entry there is the only one allowed to decide whether its X.400 domain gets mapped using SA syntax or Left Hand Side (LHS) encoding. If it picks SA, the PX RDATA will be a 'table1' entry, otherwise it'll be a 'gate1' table entry. So for an X.400 domain, you can never have both a 'table1' entry and a 'gate1' entry either, and once again the gateway's action is clearly stated ๐ŸŒˆ.

The MIXER 'gate1' table syntax is actually identical to MIXER 'table1', and the 'gate2' table syntax is identical to MIXER 'table2'. So the same syntax translation rules from MIXER to DNS format can be used for both ๐Ÿงš. But a gateway or any other application has to know whether the answer it got back from DNS contains 'table1', 'table2', 'gate1' or 'gate2' information. The way to tell is to flag the PX RDATA with an extra ".G." postfix whenever it holds a 'gate1' or 'gate2' table entry ๐Ÿ”ฅ. The example in section 4.3 shows exactly what that looks like. Every X.400 O/R domain ends with a country code (that's "C-xx" in our DNS syntax), so the extra ".G." creates no conflicts or ambiguities whatsoever ๐Ÿ™Œ. That postfix must obviously be removed before anyone uses the MIXER 'gate1' or 'gate2' table data ๐Ÿงน.


5. Finding MIXER mapping information from DNS ๐Ÿ”

Okay, so the MIXER mapping information gets stored in DNS in two places: the normal RFC822 domain name space, and the newly defined X.400 name space ๐Ÿ—บ๏ธ. The info lives in PX resource records, and it doesn't represent a full RFC822 or X.400 O/R address. It's more like a template that specifies which fields of the domain the mapping algorithm uses ๐Ÿ’–.

When mapping info is stored in DNS, queries get sent to DNS whenever an iterative search through the mapping table would happen (that's MIXER section 4.3.4, State I, and section 4.3.5, mapping B) ๐Ÿ’ซ. Thanks to how DNS searching works, DNS by itself returns the longest possible match in the stored mapping rule with one single query, so you don't need iteration or multiple queries ๐Ÿฆ‹. As MIXER specifies, a search of the mapping table ends in either success (mapping found) or failure (query failed, mapping not found) โœ….

A DNS query can also end in a third result: timeout โฐ. If you get a timeout, the gateway operation gets delayed and then retried later. Success or failure gets processed according to the algorithms in MIXER ๐ŸŽ€. If DNS returns an error code, an error message should be logged, and the gateway operation gets delayed just like with a timeout ๐Ÿ™ˆ. These pathological situations should be avoided with a careful duplication and caching mechanism, which DNS itself provides ๐ŸŒธ.

Finally, searching the nameserver that can authoritatively answer the query is done automatically by the DNS distributed name service ๐Ÿซถ.

5.1. A DNS query example ๐Ÿงš

Okay so an MIXER mail-gateway sitting on the Internet, when it's translating addresses from RFC822 to X.400, can ask DNS about the MCGAM rule. Say it's translating SUN.CCE.NRC.IT. The gateway just queries DNS for the matching PX resource record, and DNS should contain a record like this:

*.cce.nrc.it.  IN PX 50   cce.nrc.it.  O-cce.PRMD-nrc.ADMD-acme.C-it.

The first query comes back instantly with the right mapping rule in DNS store format. ๐Ÿ’…

There's no ".G." at the end of that PX RDATA value, so applying the syntax translation from paragraph 4.2 gives you the MIXER Table 2 mapping rule. โœจ

Next up, a 'gate2' table rule. Say we're looking for an RFC822 domain ending in top level domain "MW", and DNS has this:

*.mw.   IN  PX  50  mw.  O-cce.PRMD-nrc.ADMD-acme.C-it.G.

DNS returns 'mw.' and 'O-cce.PRMD-nrc.ADMD-acme.C-it.G.', which is a 'gate2' table entry in DNS store format. Drop the final ".G." and apply the syntax translation from paragraph 4.2, and boom, you've got the original rule. The ".G." flag also tells the gateway to use DDA encoding for the inquired RFC822 domain. ๐Ÿฆ‹

Now going the other way, from X.400 to RFC822, with this address:

C=de; ADMD=pkz; PRMD=nfc; O=top;

The mail gateway converts the syntax per paragraph 4.2, applies the 'Country code convention' from 4.2.3 to get the DNS translation of the X.400 O/R name, and then queries DNS for the PX record. The record it needs is:

O-top.PRMD-nfc.ADMD-pkz.X42D.de.

DNS could contain:

*.ADMD-pkz.X42D.de.  IN  PX  50  pkz.de.  ADMD-pkz.C-de.

Assuming there are no more specific records in DNS, the wildcard mechanism returns the MIXER 'table1' rule in encoded format. ๐ŸŒธ

Last one, a 'gate1' rule. Say we're looking for an X.400 domain ending with ADMD=PWT400; C=US;, and DNS has this:

*.ADMD-PWT400.X42D.us.  IN  PX  50  intGw.com. ADMD-PWT400.C-us.G.

DNS returns 'intGw.com.' and 'ADMD-PWT400.C-us.G.', which is a 'gate1' table entry in DNS store format. Drop the final ".G." and apply the syntax translation from paragraph 4.2, and the original rule is right there. The ".G." flag also tells the gateway to use LHS encoding for the inquired X.400 domain. ๐Ÿ‘‘


6. Administration of mapping information ๐ŸŽ€

DNS, using the PX RR, can distribute MCGAM rules to all MIXER gateways on the Internet. ngl though, not every MIXER gateway can use the Internet DNS. Some gateways in a management domain are expected to follow one of these models:

  • (a) Table-based
  • (b) DNS-based
  • (c) X.500-based

Table-based domains keep publishing their MCGAM rules and grabbing mapping tables through the International Mapping Table coordinator, manually or with automated procedures. Their MCGAM info can also show up in DNS, provided by the appropriate DNS authorities, using the same mechanism already used for MX records. If a branch doesn't have its own DNS server yet, a higher authority in the DNS tree provides the service for it. A transition procedure like the one used to migrate from the 'hosts.txt' tables to DNS can also be applied to the deployment phase of this specification. An informational document describing the implementation phase and the detailed coordination procedures is expected. ๐Ÿงƒ

Another distributed directory service that can distribute MCGAM info is X.500. Coordination with table-based domains works in exactly the same way as for DNS.

Coordinating MCGAM info between DNS and X.500 is more complex, because it needs some kind of uploading between the two systems. The ideal is a dynamic alignment mechanism that transparently makes DNS mapping info available in X.500 and vice versa. Some work in this area is already happening [see Costa], which could lead to a global transparent directory service: info stored in DNS or in X.500, but fully visible from either system. ๐ŸŒ

Now, a reminder: MIXER's idea of MCGAM rule publication is different from the old RFC1327 idea of globally distributed, coordinated and unique mapping rules. MIXER doesn't require any conformant gateway or tool to know the complete set of MCGAM. It only requires using some set (eventually empty) of valid MCGAM rules, published via Tables, DNS or X.500 mechanisms, or any combination of these. MIXER also specifies that incomplete sets of MCGAM can be used, and that supplementary local unpublished (but valid) MCGAM can be used too. So the coordination problem between the three systems proposed by MIXER for MCGAM publication is non essential, and only important for efficient operational matters. It doesn't affect the correct behaviour of MIXER conformant gateways and tools. ๐Ÿ™ˆ


7. Conclusion ๐ŸŒˆ

Introducing the new PX resource record and defining the X.400 O/R name space in the DNS structure gives us a great repository for MCGAM info. The mapping info is stored in the DNS tree, so it's easy to grab using the DNS distributed name service. The appropriate DNS space for X.400 O/R names is also a place to store and distribute other X.400 MHS info. DNS has lots of known advantages for storing, managing and updating info. A successful number of tests were performed under the provisional top level domain "X400.IT" when RFC1664 was developed, and the results confirmed those advantages. Over 2 years of operational experience with the RFC1664 specification confirmed the method is feasible, and helped identify some operational procedures for deploying MCGAM insertion into DNS. ๐Ÿ’–

Software to query DNS and convert between the textual representation of DNS resource records and the address format defined in MIXER was developed with RFC1664. This software also allows a smooth implementation and deployment period, eventually taking care of the transition phase. It can be used (with little or no modification) for this updated specification too, supporting the new 'gate1' MIXER table. DNS software implementations supporting RFC1664 also support this memo's new specification with no modification. ๐Ÿ”ฅ

A further informational document describing the operation and implementation of the service is expected. โญ


8. Acknowledgements ๐Ÿซถ

We want to thank everyone who contributed to the discussion and revision of this document: many of their ideas and suggestions are essential parts of this work. Special thanks to Jon Postel, Paul Mockapetris, Rob Austin and the whole IETF x400ops, TERENA wg-msg and IETF namedroppers groups. A special mention goes to Christian Huitema for his fundamental contribution to this work.

This document is a revision of RFC1664, edited by one of its authors on behalf of the IETF MIXER working group. The current editor also wants to thank the authors of RFC1664:

Antonio Blasco Bonito     RFC822: bonito@cnuce.cnr.it
CNUCE - CNR               X.400:  C=it;A=garr;P=cnr;
Reparto infr. reti                O=cnuce;S=bonito;
Viale S. Maria 36
I 56126 Pisa
Italy
Bruce Cole                RFC822: bcole@cisco.com
Cisco Systems Inc.        X.400:  C=us;A= ;P=Internet;
P.O. Box 3075                     DD.rfc-822=bcole(a)cisco.com;
1525 O'Brien Drive
Menlo Park, CA 94026
U.S.A.
Silvia Giordano           RFC822: giordano@cscs.ch
Centro Svizzero di        X.400:  C=ch;A=arcom;P=switch;O=cscs;
Calcolo Scientifico               S=giordano;
Via Cantonale
CH 6928 Manno
Switzerland
Robert Hagens                   RFC822: hagens@ans.net
Advanced Network and Services   X.400:  C=us;A= ;P=Internet;
1875 Campus Commons Drive               DD.rfc-822=hagens(a)ans.net;
Reston, VA 22091
U.S.A.

9. References ๐Ÿ“š

  • [CCITT] CCITT SG 5/VII, "Recommendation X.400, Message Handling Systems: System Model - Service Elements", October 1988.
  • [RFC 1327] Kille, S., "Mapping between X.400(1988)/ISO 10021 and RFC 822", RFC 1327, March 1992.
  • [RFC 1034] Mockapetris, P., "Domain Names - Concepts and Facilities", STD 13, RFC 1034, USC/Information Sciences Institute, November 1987.
  • [RFC 1035] Mockapetris, P., "Domain names - Implementation and Specification", STD 13, RFC 1035, USC/Information Sciences Institute, November 1987.
  • [RFC 1033] Lottor, M., "Domain Administrators Operation Guide", RFC 1033, SRI International, November 1987.
  • [RFC 2156] Kille, S. E., " MIXER (Mime Internet X.400 Enhanced Relay): Mapping between X.400 and RFC 822/MIME", RFC 2156, January 1998.
  • [Costa] Costa, A., Macedo, J., and V. Freitas, "Accessing and Managing DNS Information in the X.500 Directory", Proceeding of the 4th Joint European Networking Conference, Trondheim, NO, May 1993.

10. Security Considerations ๐Ÿšจ

This document specifies a means by which DNS "PX" records can direct the translation between X.400 and Internet mail addresses.

This can indirectly affect the routing of mail across a gateway between X.400 and Internet Mail. A successful attack on this service could cause:

  • incorrect translation of an originator address (thus "forging" the originator address),
  • incorrect translation of a recipient address (thus directing the mail to an unauthorized recipient, or making it appear to an authorized recipient that the message was intended for recipients other than those chosen by the originator),
  • or force the mail path via some particular gateway or message transfer agent where mail security can be affected by compromised software.

There are several ways an attacker might be able to deliver incorrect PX records to a client:

  • (a) compromise of a DNS server,
  • (b) generating a counterfeit response to a client's DNS query,
  • (c) returning incorrect "additional information" in response to an unrelated query.
๐Ÿšจ Clients using PX records SHOULD ensure that routing and address translations are based only on authoritative answers. Once DNS Security mechanisms [RFC 2065] become more widely deployed, clients SHOULD employ those mechanisms to verify the authenticity and integrity of PX records.

11. Author's Address ๐Ÿ’Œ

Claudio Allocchio
Sincrotrone Trieste
SS 14 Km 163.5 Basovizza
I 34012 Trieste
Italy

RFC822: Claudio.Allocchio@elettra.trieste.it
X.400:  C=it;A=garr;P=Trieste;O=Elettra;
S=Allocchio;G=Claudio;
Phone:  +39 40 3758523
Fax:    +39 40 3758565

Copyright (C) The Internet Society (1998). All Rights Reserved. ๐ŸŽ€

okay bestie, the legal part! ๐Ÿ™ˆ you can copy this document and hand it out to people ๐Ÿ’– and you can make derivative works that comment on it, explain it, or help people implement it ๐Ÿฆ‹ you can publish and distribute those too, in whole or in part, with no real restrictions ๐ŸŒˆ the one catch is that the copyright notice and this paragraph have to stay on every copy and every derivative work ๐Ÿซถ

but the actual document itself? it may NOT be modified ๐Ÿ˜ญ no removing the copyright notice, no deleting the references to the Internet Society or the other Internet orgs ๐Ÿšซ the only exceptions are: (a) developing Internet standards, where you have to follow the copyright procedures in the Internet Standards process, or (b) translating it into languages other than English ๐ŸŒ that's it, that's the whole list ๐Ÿ’œ

the limited permissions above are perpetual ๐Ÿ”ฅ they will not be revoked by the Internet Society or its successors or assigns, so they're forever, no cap โœจ

and the disclaimer, which is serious so I'm putting it in a box ๐Ÿ‘‘:

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.

so basically the ISOC and the IETF are not promising the doc is perfect, won't break your rights, or will be good for anything specific ๐Ÿ’€ use it at your own risk, bestie ๐Ÿงš

๐Ÿ“ฆ where this page comes from