|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T p
Length: 29261 (0x724d) Types: TextFile Names: »part.6«
└─⟦9ae75bfbd⟧ Bits:30007242 EUUGD3: Starter Kit └─⟦2fafebccf⟧ »EurOpenD3/mail/smail3.1.19.tar.Z« └─⟦bcd2bc73f⟧ └─⟦this⟧ »design/part.6«
Part 6: Routing. Given a <target> and a <remainder> as determined using the rules in section 3.2, a route must be found to the <target>. Several means can be used to determine this. In the UUCP zone, information from a pathalias(8) database might be used. On the internet, nameserver information might be used. Many sites talk to multiple zones, including internal networks of various kinds. Given this, we need to determine what route to use in delivering a message. In the process of routing we also determine the transport that is to be used in delivering the message to a recipient. Often a given routing system will make use of only one transport, however, this is not always the case. A reasonable generalization is to assume that routines that do a specific kind of routing are also best suited in determining the type transport. For example, it is often the case that routes found from the pathalias information would be associated with UUCP's uux transport program. However, a local network could be organized around !-routes while using an SMTP-base transport. Also, a batched SMTP protocol could be used on top of UUCP instead of using the standard uux->rmail facilities, when communicating with some remote hosts. Part 6 describes how collections of low level routines, called routing drivers, compute a route to the <target> for a given recipient address. Further sections discuss how they are associated with a transport for delivery. Section 6.1: The router file. To provide a reasonable configuration interface for routing setup, we create a file defining the use of routing drivers. This file specifies order of the routers, the routing drivers to call, and default transports. It also specifies data and flags for use by high level routing code and by routing drivers. We shall refer to this file as the router file. This file follows the form described in Part 5. As a sample, the router file for site amdahl is: # @(#)/usr/lib/smail/routers 2.3 1/10/88 13:12:61 # match INET addresses such as [192.2.12.1]. Match these # first as these addresses will probably just confuse the # other routers. inet-addrs: # generic router attributes: driver=gethostbyaddr, transport=smtp # local tweaks to the path information, within our domain: amdahl-local: # generic router attributes: driver=pathalias, method=uux-table, always; # driver-specific attributes: file=/usr/lib/smail/paths.local, # local path info proto=lsearch, # use the raw path file domain=uts.amdahl.com # under our local domain # match hosts on the ethernet inet-hosts: # generic router attributes: driver=gethostbyname, transport=smtp # grab output of uuname for neighbor hosts uuname: # generic router attributes: driver=uuname, method=uux-table; # driver-specific attributes cmd = /usr/bin/uuname # get neighboring host info # for everybody else, it's either you are in the Usenet # maps, and related local data, or we can't route usenet-maps: # generic router attributes: driver=pathalias, method=uux-table; # driver-specific attributes: file=/usr/lib/smail/paths, # external path info proto=bsearch, # use a sorted path file domain=uucp # names stored without trailing uucp The current set of generic attributes that are recognized in the router file are: always type: boolean Routers will not always find a complete match for a particular hostname. For example, if a routing data- base has a route to the domain amdahl.com but not to the hostname futatsu.uts.amdahl.com then the routing driver might return the route to amdahl.com. Gen- erally, the route for the longest match of the target host is used. However, if the always attribute is set, then any match found by this router will be used in preference to routes that might have been returned by routers later in the router list. This is useful for hardwiring a certain number of routes within a small database. For example, this is useful for Internet sites that gateway for a small number of UUCP sites in the UUCP zone. driver type: string The driver attribute names a specific set of low-level functions which will do the work of routing remote mail. This attribute is required. method type: string transport type: string The router driver has the option of specifically set- ting a transport to use for remote delivery. If the driver does not do so, then either a method or a tran- sport attribute must exist to specify how the mail is to be delivered. A method attribute specifies a file which contains a table relating hostnames to tran- sports. A transport attribute specifies a specific transport. If the method file does not contain a match for all hosts, then the transport named with the tran- sport attribute is used. The format of a method file is given in the next section. Section 6.1.1: Sleep(1) Yet another attempt to avoid section renumbering! Section 6.1.2: Routing drivers. The routing driver is the underlying function that searches somewhere for an association between the <target> and a <next_host>, <route> pair. This search may be as simple as calling a program which lists neighboring hosts, or it may be as complex as conversing with remote name servers over the internet. The router table given in Section 6.1 uses two common types of routing drivers: a command based router and a file based router using a database built by the pathalias command. We examine the pathalias routing driver in detail in section 6.4. Other routers currently exist and more will be available in the future. A routing driver can explicitly specify a transport to be used in mail delivery. This transport will be used if a <next_host> is returned, indicating that the address did not route to the local host. It is recommended that this feature only be used if the generic transport and method attributes are insufficient. None of the present routers make use of this. Section 6.1.3: Method files and default transports. The routines that call the routing drivers may handle some of the processing required in the previous section. For example, associating a recipient address with a default transport or searching for a transport in a table are operations that may be done above the driver level, under the control of the transport and method attributes. If a method attribute is given, then it specifies a file that is consulted as a table of host/transport pairs. An example of a method file is: # @(#)/usr/lib/smail/methods/uux-table 1.10 1/4/88 10:11:86 # associate a next-host found by pathalias with a transport. # we poll our major neighbor sites on demand to get mail # out through them fast. Extensive use of this is probably # a questionable idea. pyramid demand hplabs demand decwrl demand sun demand # we also poll internal sites on demand as well, unless it # is too expensive. muts demand muts12 demand # go over SNA to corporate ccc sna # experimentally, send mail using batched SMTP commands over # UUCP to smail development machines eek uusmtp namei uusmtp # for everybody else inside or outside amdahl we will # poll eventually from a cron daemon, or they will call us * uux Specifically, the method file is a file of records which specify one hostname and one transport. These two strings are separated in the file records by comments or whitespace. The table is scanned from beginning to end until a record is found containing a match for the host in question. The transport in that record is used for delivery to that host. As a catch-all feature, the special hostname ``*'' matches any hostname, and should always be in the last record in the method file. If no method attribute exists, or no lines in the method file match the host in question, then the transport attribute is used to name a specified transport. Section 6.1.3.1: Intermission. This section intentionally has twelve words in it, not including the heading. Section 6.1.4: Partial domain matches. Some routing drivers will return routes even though a complete match was not found. An example is a search for the <target> ``foo.bar.com'', where a driver found only ``.bar.com''. The driver may return the <next_host> and <route> for reaching the gateway to .bar.com. When a driver returns a route, it also returns the number of characters in the target that were matched for the route that was found. In the above example with .bar.com, the number of chars was 8 out of a possible complete match of 11. Note that a partial match must match on the end of a <target> not the middle or the beginning, and that a match must not split a domain part. Thus, a domain of ``foo.bar'' or ``bar'' or ``r.com'' would not be a match for foo.bar.com. This return value is used by the top level routing algorithm described in the next section. When a router returns a partial match to a target, the target is passed to successive routers in turn to determine if another router can find a better match. The exception to this is if the `always' boolean attribute is set for the router. In this case a partial match produced by that router is used in preference to more complete matches found by later routers. As an example, consider a site which performs a gateway service for a number of subdomains between the internet and the UUCP zone. Such a site will probably always use the internet to reach any sites matched by the internet domain system, with the exception of subdomains that it gateways to. This can be accomplished using a router file such as: # match domains that we gateway to from the internet gateway-domains: driver=pathalias, transport=uux, always; file=/usr/lib/smail/gateway-paths # otherwise match any sites on the internet internet: driver=gethostbyname, transport=smtp # otherwise match any sites in the UUCP zone uucp-zone: driver=pathalias, transport=uux; file=/usr/lib/smail/paths, proto=dbm, domain=uucp Section 6.2: Top level routing. The top level of the routing code is used to query the drivers for routing information, and also to compute the possible routes to use. In general the method used in determining the route is to query each routing driver in turn for routes to <target> until a driver returns a route for a complete match, or there are no more entries in the router file. The <next_host> and <route> returned by the router that matched the most chars is used. An exception to the above rules is that a driver can insist that his or her route be used, or a router file entry can contain the ``always'' attribute. A <next_host> and <route> found under these conditions is used, if it matched more characters of <target> than any driver called previously. When a <route> and <next_host> are chosen from an incomplete match of <target>, the gateway host that the <route> leads will need to know what the real <target> was. Thus when a route is used that did not completely match the target, when computing the <next_address> the <remainder> is replaced by the <address> from the <remainder> and the <target> that were computed. In this way the <target> will be sent on to the gateway for rerouting. See the examples in Section 3.3 for a case where this feature is used. Section 6.3: Currently available router drivers. The following sections describe the currently implemented set of router drivers. Section 6.3.1: The pathalias router. The pathalias router computes routes from a database in the style produced by the pathalias program. It has the following <driver_attributes>: domain type: string A list of domains to be stripped from the end of a hostname before it is searched for in the database. Multiple domains, in this list, are separated by colons. file type: string This defines the name of the file containing the data- base. interval type: number The number of seconds to wait between open retries. optional type: boolean If set, then if the open fails, assume an empty alias file. This is useful for optional databases. For example, in a networking environment, workstations may be configured with the option of having a private alias file, without the necessity of creating such a file on each host. proto type: string Names the protocol used in opening and searching the database. Possibilities are discussed below. reopen type: boolean If set, the pathalias will be closed and reopened after each call to the pathalias driver. This is useful in environments where file descriptors are scarce but many databases are desired. required type: string A list of domains which targets are required to be for a match. The names are not stripped, unless they are also specified by the domain attribute. retries type: number The maximum number of retries for opening a file. This is useful on systems without an atomic rename system call. On such systems there will be a window of vul- nerability when new databases are moved into place where no file will exist. try type: string A list of domains to be stripped only if the target was not found in the database without the domain stripped. (This is currently not supported). tryagain type: boolean If set, then if the open fails, the resolution of local addresses will be attempted at a later time. This is useful in a networking environment where failure to open a database (such as a remote YP database) may be a result of a server machine being down or temporarily inaccessible. The default values for the `retries' and `interval' attributes should generally be reasonable. The current list of possible values for the proto attribute is: aliasyp This is a variant of the yp protocol that is com- patible with the standard Sun mail.aliases YP ser- vice. This database has a different format from other databases which must be taken into account when sending requests. Typically this is not use- ful for a path database. bsearch Use a binary search to look through a sorted file arranged as lines which begin with a key and are followed by the value associated with the key, separated by a colon or whitespace. dbm Use the BSD dbm(3x) or ndbm(3x) routines to search for the key. The keys and data in the dbm data- base must end in a nul byte. If only the dbm(3x) library is available then only one dbm database can be used by smail , while the ndbm(3x) routines will allow any number of databases. However, it is always okay for multiple routers and directors to use the same dbm database, if this is useful. lsearch Use a linear search using the same read routine used to read config files. `#'-style comments are allowed and the beginning of each file entry should be the key, followed by whitespace or a colon character. The rest of the entry should be the value associated with the key. yp Use the Sun YP service to access a paths database stored on a remote machine. In this case the value for the file attribute is of the form: domain_name:database_name where the domain_name: is optional and defaults to the default YP domain for the local host. All database lookups are either independent of case or, when case independent lookups are impossible, case-folded. Thus, all keys in DBM databases should be in lower case. As an example of the use of the `domain', `try' and `required' driver attributes, if domain=uucp, then any <target> that ends in .uucp will have the .uucp removed before being looked up. Alternately, if try=uucp and no domain is given, then .uucp is stripped only if the original <target> was not found. If required=uucp then a <target> is not a candidate for a match unless it ends in .uucp. The effects of `domain' and `try' are not cummulative and the <target> is applied to the `required' attribute before being applied to `domain' and `try', in that order. Note that the length of any stripped string is added to the count of characters matched for purposes of deciding which router had the most complete match. A sample pathalias router entry is: pathalias: transport=uux, driver=pathalias; file=/usr/lib/smail/paths, proto=bsearch, domain=uucp In the following sections, we will be referring to the following pathalias file for site nsavax: .amdahl.com seismo!amdahl!%s .kgb.comm seismo!mcvax!yupiter!kgbvax!%s .nbc.com glotz!namei!walldrug!nbctrs80!%s .nsa.gov %s .wall.com glotz!namei!walldrug!%s amdahl glotz!amdahl!%s namei glotz!namei!%s glotz glotz!%s kgbvax seismo!mcvax!yupiter!kgbvax!%s kgbvax.kgb.comm seismo!mcvax!yupiter!kgbvax!%s nbcmac glotz!namei!walldrug!nbcmac!%s nsavax %s nsavax.nsa.gov %s seismo seismo!%s walldrug glotz!namei!walldrug!%s yupiter seismo!mcvax!yupiter!%s This data base associates a host or domain name, on the left hand side, with a path, on the right hand side. The right hand side should be a pure bang route ending in a %s. The format is intended to be more general, with the %s shows where to put the <remainder>. The pathalias(8) can produce routes involving both right and left operators such as: decwrl decwrl!%s@ucbvax This form is not recommended in general because the historical disagreement over the presidence of ``!'' and ``@''. By standardizing on !-routes, as will be produced with from the Usenet maps, we avoid many routing ambiguities. A low level interface to a pathalias database returns a data structure containing the first element of an associated path as the <next_host>, and a <route> of the remaining path information with the trailing ``!%s'' removed. As a special case, if the path is just ``%s'', it routes back to the local host. The <next_host> will then be associated with a transport using a table defining these associations. Section 6.3.1.1: Rules for obtaining a route from pathalias information. Using a pathalias database and given a <target>, search for a <route> and <next_host> using the following rules for the <next_host>!<route> associated with the first match found: 1. If <target> ends in a dot, then remove that ending dot, then if it does not begin with a dot insert one at the beginning. 2. Look for an exact match of <target>. 3. If <target> begins with a dot, look for a match to <target> without the initial dot. Otherwise look for a match to <target> with an initial dot. 4. Strip the first component of <target>, leaving the initial dot before the second component. Look for a match. A component of <target> is defined as a set of characters that do not include dots. Components are separated by dots. In the case that the <route> is found in step 4, the original <target> should be appended to the route. See examples for an explanation. If a match in step 4 routes to %s (the local host), routing fails. 5. Strip the next component of <target>, and repeat step 4 until there are no components to <target> remaining. Examples: <target>: nsavax.nsa.gov lookup: nsavax.nsa.gov <next_host> is null and <route> is null <target>: walldrug lookup: walldrug <next_host> = <glotz> and <route> = namei!walldrug <target>: wall.com. lookup: .wall.com <next_host> = glotz and <route> = namei!walldrug <target>: amdahl.com lookup: amdahl.com no match lookup: .amdahl.com <next_host> = seismo and <route> = amdahl <target>: .kgbvax.kgb.comm lookup: .kremvax.kgb.comm no match lookup: kremvax.kgb.comm <next_host> = kremvax and <route> is null <target>: kray.rsrch.kgb.comm lookup: kray.rsrch.kgb.comm no match lookup: .kray.rsrch.kgb.comm no match lookup: .rsrch.kgb.comm no match lookup: .kgb.comm <next_host> = seismo and <route> = mcvax!yupiter!kgbvax characters matched = 9 out of a possible 19 <target>: node.fido.net lookup: node.fido.net not found lookup: .node.fido.net not found lookup: .fido.net not found lookup: .net not found, routing failed <target>: .subdom.wall.com lookup: .wall.com <next_host> = glotz, <route> = namei!walldrug characters matched = 9 <target>: somehost.sub.nsa.gov lookup: .sub.nsa.gov not found lookup: .nsa.gov found the localhost but return failure because the local host is the gateway to .nsa.gov but it does not know how to route to a sub domain that it should know about, if it existed Section 6.3.2: The uuname driver. Some sites in the UUCP zone might wish to always use a direct path to all their neighbors, instead of relying on a pathalias database that uses time-optimal routes (supposedly) instead of least-hop-count routes. As another possibility, they may wish to use the pathalias routes to their neighbors only in the case that a domain address is given (i.e., neighbor.uucp). A simple and portable driver for these requirements is the uuname driver, that reads a list of hostnames from the output of an executable program (normally /usr/bin/uuname) and will return these hostnames as <next_host> values, along with null <route> values, for any <target> that matches a name in this list. Optionally, the <target> will also match if it ends in a specific <domain_part> (normally uucp) with the base <domain_part> matching an entry in the list. An example entry for a site that wishes to route to their neighbors for <target> values that may end in .uucp is: uuname: transport=uux, driver=uuname; cmd=/usr/bin/uuname, domain=uucp The alternate is a site that wishes to bypass the pathalias router only for explicit target matches, so that neighbor.UUCP will be routed through pathalias. This can be done by not specifying a domain, as in: uuname: transport=uux, driver=uuname; cmd=/usr/bin/uuname The `uuname' driver also supports the `domain', `required' and `try' attributes, and all three domain-style attributes can be colon separated lists. See the pathalias driver for more details. Section 6.3.4: The gethostbyname driver. In a network on top of a BSD-style network, hostnames on the network can be matched using this driver, which merely calls the gethostbyname(3N) library routine. This routine is only available on systems that supply a BSD networking library. The only driver attributes for this driver are the `domain', `required' and `try' attributes, which are compatible with the pathalias and uuname drivers. The gethostbyname will only match a target host completely. The <next_host> value returned will be the proper name for the host as given by the h_name field of the hostname structure. NOTE: The hostname given to gethostbyname(3N) will be downcased, so that upper-case or mixed-case names can be matched correctly. Section 6.3.5: The gethostbyaddr driver. Also in a network environment, it is useful to be able to specify explicit INET addresses using a target such as: [192.2.12.3] The gethostbyaddr driver matches targets of this form, defined by square brackets surrounding only digits and dot characters. The driver then converts this number into a hostname by calling gethostbyaddr() to determine the proper name for the host. If gethostbyaddr(3N) fails, then the input target is returned as the <next_host> value, which is useful for incomplete host tables. The gethostbyaddr driver has the following attributes: name type description ---- ---- ----------- check_for_local boolean if set, see if the hostname returned by gethostbyaddr() matches one of the known names for the local host. The name "localhost" is counted here as a potential nane for the local host. NOTE: This attribute is set by default. fail_if_error boolean if set, then any domain-literal target which does not fit the form of an internet address is considered an error. If not set, then such addresses are merely not matched by the gethostbyaddr driver. Section 6.3.6: The smarthost driver. Sometimes it is handy to be able to redirect mail destined for a host that you don't know about to some other host that has more routing information than you do. This other host is called a ``smart-host'', and can be named in the smarthost driver. The smarthost driver has the following driver attribute: path - define a host or !-route path that defines the smart host. If no `transport' or `method' attribute is given for the router file entry, this address will be re-sent through all the routing drivers. An exception is that an address cannot be sent to the smarthost driver twice, as this would mean that the path to the smarthost was not known. For example, if site namei wanted to use amdahl's routing database for mail delivery to non-neighbor sites they could use a router file entry of: smart_host: driver=smarthost; path=amdahl or smart_host: transport=uusmtp, driver=smarthost; path=amdahl NOTE: at the present time, a `transport' or `method' attribute is required, as the software is not yet in place that can rescan the routers in the required ways. Then, a recipient address of frank.human@cyborg will be rewritten so that the target is amdahl and the remainder is frank.human@cyborg. Alternately, in the second form for the entry, the <next_host> would become ``amdahl'' immediately, and the <next_address> would be frank.human@cyborg, with the transport being set to ``uux''. By specifying a !-route it is possible to route mail to a smart-host that you would not otherwise be able to route to. For example, if the machine ``glotz'' wished to use amdahl as its smart host, through its neighboring site ``namei'', it could use: smart_host: driver=smarthost; path=namei!amdahl or smart_host: transport=demand, driver=smarthost; path=namei!amdahl It is possible to set the path and/or the transport in the config file (described in Section 9.3). This is done by setting the config file attributes smart_path and smart_transport. For example, the config file could contain the following: smart_path = amdahl smart_transport = uusmtp Then, if the entry in the router file was: smart_host: driver=smarthost the configuration would be essentially the same as in the second smart_host example above. This makes it possible to share copies of the router file among several machines, with the smart host configuration specific to one machine being set in its private configuration file. These config file attributes are used only if the path driver attribute is not given in the smart_host entry. If used, the `smart_transport' will override a `transport' or `method' attribute. Section 6.4: Complete router file examples. The following router file will work with the current set of available drivers, and is set up for the site `namei', that uses a small pathalias database to route downstream, and makes use of amdahl as a smarthost: # try pathalias for our downstream sites, these sites # are by default under the domain UUCP pathalias: transport=localnet, driver=pathalias; file=/usr/lib/smail/paths, proto=lsearch, domain=uucp # if not one of them, send to amdahl over demand uux as # our gateway to the world the-world: transport=demand, driver=smarthost; path=amdahl Meanwhile, amdahl might use uuname for explicit references to neighboring hosts, not in the .uucp domain, and pathalias otherwise, using both an amdahl-internal database for within the company, and a pathalias database constructed from Usenet map data otherwise. This example can be seen in Section 6.1. \f