在17.1之前,STCP会先查询任何配置的DNS来解析主机名,只有在没有响应或名字服务器没有响应时,才会搜索本地主机文件。
从17.1开始,你现在可以选择先搜索本地hosts文件,但有一些条件。首先,你的应用程序必须在17.1系统的POSIX规则下构建。>system>stcp>command_library中的标准命令集都是以这种方式构建的,但是你不能只安装17.1而不重新构建你的应用程序,并期望使用这个功能。其次你必须在>system>stcp目录下安装Name Service Switch,即nsswitch.conf,配置文件。该文件的默认版本可以在>system>stcp>templates目录下找到。
从图1中可以看到,nsswitch.conf文件似乎控制了所有的东西。然而,只有"hosts"和"networks"条目对系统行为有任何影响。关键字"dns"和"files"的顺序控制着搜索顺序。如果"files"先出现,则会先搜索hosts或networks文件,然后再查询DNS。如果"dns"在前,则先查询DNS,再查询文件。如果"hosts"或"networks"条目中只包含一个关键词,那么将只搜索该关键词对应的内容。
使用hosts文件而不是仅仅查询DNS的主要原因是速度/灾难恢复和控制。如例 1所示,当其中一个名称服务器没有应答时,名称解析时间会从 20 毫秒变为近 2 秒。如果您的所有名称服务器都没有应答,名称解析时间可能会非常长(例2)。通过将关键的名字放在hosts文件中,并先搜索hosts文件,你就不用担心解析名字所需的时间了(例3)。
先搜索hosts文件的另一个原因是本地控制。当使用DNS时,你放弃了对名称解析过程的控制。在大多数情况下,这样做是没有问题的,但有时需要本地控制。例如,如果有必要临时或永久地阻止访问主机,您可以在防火墙上进行,或者通过改变DNS数据库或主机文件,将对问题主机的请求重定向到不同的地址。 可能无法改变DNS数据库,对防火墙的改变也可能需要太长的时间,但你可以改变自己的hosts文件。例4显示,访问www.google.com会被重定向到本地主机。
hosts文件的缺点是主机名和IP地址之间的映射是静态的。如例5所示,名称服务器可以被配置为提供不同的IP地址,以在多个应用服务器之间分散负载。如果你在hosts文件中添加一个条目,该条目是静态的,你就会失去DNS可能提供的任何负载平衡的好处。此外,如果/当主机 IP 地址发生变化时,您必须手动维护主机文件。
那么应该如何配置nsswitch.conf文件。文件中的注释(图1)建议你不要将该文件安装到>system>stcp目录下,直到你所有的应用程序都重建使用它。这将防止可能出现的分歧结果,即旧的应用程序使用DNS得到一个地址,而新的应用程序使用hosts文件得到不同的地址(例4)。 此外,由于DNS总是先被查询,所以很有可能现有的hosts文件中的条目不再正确。另一种策略是安装文件时将hosts条目设置为"files dns",但要确保hosts文件中唯一的条目是localhost(例子6)。然后,你可以根据需要在hosts文件中添加主机/IP地址,并进行最少的编辑,要记住,任何旧的应用程序都不会看到主机文件的地址。
好吧,那网络呢?一直以来,我们都可以通过在>system>stcp>networks文件中给网络命名。就我个人而言,我从来没有看到需要,但你可以在添加路由时使用一个名字。有趣的是,当你打印路由时,名字不会显示出来(例7)。你也可以在使用arp命令中的-network参数时使用名称。网络的默认nsswitch.conf文件首先搜索networks文件,然后查询DNS。除非你真的配置了DNS来返回网络名信息,否则我的建议是删除networks条目中的dns关键字。
最后一点。我已经包含了两个示例程序。第一个resolve.c使用了旧的名称解析函数gethostbyname;第二个new_resolve.c使用了新的函数getaddrinfo。gethostbyname函数已经被POSIX标准函数getaddrinfo所取代。因为它是POSIX标准函数,所以在Stratadoc 中找不到任何关于getaddrinfo的文档;但是在网上有大量的文档,只要google getaddrinfo即可。
例如:
在下面的例子中,resolve_17.0和resolve程序是基于相同的源代码。唯一不同的是resolve_17.0是在VOS 17.0系统上编译的,而resolve是在17.1系统上编译的。名称服务器1.1.1.1、1.1.1.2、1.1.1.3是虚构的,是用来模拟名称服务器没有响应的。我还把不在公网的主机的主机号给X掉了。
d >system>stcp>resolv.conf -match命名服务器 %phx_vos#m16_mas>system>stcp>resolv.conf 11-05-24 08:07:13 mst 名称服务器 164.152.XXX.XXX 名称服务器 134.111.XXX.XXX 准备好了 08: 07: 13 resolve_17.0 ftp。stratus.com。 ftp.stratus.com解析为192.52.248.14,在。 20.615ms 准备好了 08: 07: 20 d >system>stcp>resolv.conf -match命名服务器 %phx_vos#m16_mas>system>stcp>resolv.conf 11-05-24 08:07:30 mst 命名服务器 1.1.1.1 名称服务器 164.152.XXX.XXX 名称服务器 134.111.XXX.XXX 准备好了 08:07:30 resolve_17.0 ftp。stratus.com。 ftp.stratus.com解析为192.52.248.14,在。 1989.395ms 准备好了 08:07:38 |
例子1--当名称服务器(1.1.1.1)没有应答时,时间的变化。 |
d >system>stcp>resolv.conf -match命名服务器
%phx_vos#m16_mas>system>stcp>resolv.conf 11-05-23 13:11:31 mst
命名服务器 1.1.1.1
命名服务器1.1.1.2
命名服务器1.1.1.3
准备好了 13:11:31
resolve_17.0 ftp。stratus.com。
ftp.stratus.com解析为192.52.248.14,在。 14759.949ms
准备就绪 13:12:13
|
例2--当没有名称服务器应答时,解析名称的时间。 |
d >system>stcp>resolv.conf -match命名服务器 %phx_vos#m16_mas>system>stcp>resolv.conf 11-05-24 08:18:10 mst 命名服务器 1.1.1.1 名称服务器 164.152.XXX.XXX 名称服务器 134.111.XXX.XXX 准备好了 08: 18: 10 d >system>stcp>nsswitch.conf -match hosts。 %phx_vos#m16_mas>system>stcp>nsswitch.conf 11-05-24 08:18:21 mst hosts: files dns 准备好了 08: 18: 21 stratus.com ftp.stratus.com解析为192.52.248.14,在。 13.702ms 准备好了 08: 18: 31 www1.stratus.com www1.stratus.com解析到134.111.1.84,在。 227.798ms 准备好了 08:18:39 |
例子3--先搜索hosts文件和找到/没有找到条目时的时间差。 |
d >system>stcp>resolv.conf -match命名服务器 %phx_vos#m16_mas>system>stcp>resolv.conf 11-05-23 13:28:51 mst 名称服务器 164.152.XXX.XXX 名称服务器 134.111.XXX.XXX 准备好了 13: 28: 51 d %phx_vos#m16_mas>system>stcp>hosts -match google。 %phx_vos#m16_mas>system>stcp>hosts 11-05-23 13:29:29 mst 127.0.0.1 www.google.com google.com google 准备好了 13: 29: 29 resolve_17.0 www.google.com www.google.com,决心 74.125.226.115,在180.099。ms 准备好了 13: 29: 40 解决www.google.com www.google.com,决心 127.0.0.1 in 13.458ms 准备好了 13: 30: 01 |
例子4--通过将地址改为localhost来阻止访问www.google.com,以便新的应用。 |
解决 www.yahoo.com www.yahoo.com,决心 67.195.160.7621.439毫秒 准备就绪 13:35:56 解决 www.yahoo.com www.yahoo.com,决心 69.147.125.6521.713毫秒 准备就绪 13:35:56 解决 www.yahoo.com www.yahoo.com,决心 67.195.160.7630.106毫秒 准备就绪 13:35:57 解决 www.yahoo.com www.yahoo.com,决心 69.147.125.6529.739毫秒 准备就绪 13:35:58 解决 www.yahoo.com www.yahoo.com,决心 67.195.160.7623.880毫秒 准备就绪 13:35:58 解决 www.yahoo.com www.yahoo.com,决心 69.147.125.6522.736毫秒 准备好了 13: 35: 58 |
例5 - DNS提供多个IP地址 |
d >system>stcp>hosts。 %phx_vos#m16_mas>system>stcp>hosts 11-05-24 08:32:51 mst # # 主机文件样本 # # IP地址名称别名 #评论意见 # 127.0.0.1 localhost loopback-host loopback lb # 必需的 准备好了 08: 32: 51 |
例6 - 最小主机文件 |
路由添加 诺亚试炼164.152.XXX.XXX 5.255.255.0 准备就绪 13:52:54 航线打印 默认网关:164.152.XXX.XXX。 网络地址 网关地址 子网掩码 重定向寿命 1.2.3.0 164.152.XXX.XXX 255.255.255.0 准备好了 13:53:26 d networks -match noahs-test %phx_vos#m16_mas>system.17.1>stcp>networks 11-05-23 13:53:48 mst nahs-test 1.2.3.0 准备好了 13: 53: 48 |
例7 - 使用网络表中的名称添加网络 |
# # nsswitch.conf(5)样本--服务交换机配置文件的名称。 # # 这个配置文件只被已经建立的程序使用。 # 在17.1或更高版本的POSIX规则下。 如果这个配置 # 文件不存在,主机名查询将与 # 旧版本的DNS软件。 为了避免混淆,我们 # 建议你推迟使用这个配置文件,直到所有的 # #应用程序已重建使用POSIX。 # # 非POSIX DNS软件(以及发布之前的所有DNS软件)。 # 17.1)解析主机,首先使用DNS,然后使用 # >system>stcp>hosts文件。 这有几个小问题。 # # 1. 如果hosts文件中有一个错误的条目,它将不会得到。 #检测到,直到有东西导致DNS消失。 这个 #可能导致混乱,正是当一个人不希望它。 # # 2. 没有办法覆盖一个从DNS回来的坏主机。 # # 3. 大多数其他的实现都是先搜索hosts文件。 # # 这些都没有足够的说服力来做出不兼容的改变。 # 变成默认的行为;但是,你可以切换搜索顺序。 # 使用这个文件来避免上述问题。 搜索hosts文件 # 首先,你要。 # # hosts: files dns # #先做DNS,并保持100%兼容的行为。 #以前发布的VOS,你要: # # hosts: dns files # # 另外,请注意,非POSIX和17.1之前的软件从来没有使用dns来实现。 #查找网络。 新软件就是这样做的。 默认情况下,它这样做 # 在>system>stcp>networks文件中查看后。 可以配置 #这种行为,也。 通常没有多少有用的信息 #从网络的DNS回来。 如果你想关闭DNS查询。 # 对于网络,这样做。 # # 网络:文件 # 组别:同行 group_compat: nis hosts: files dns 网络:文件 dns 密码:compat passwd_compat: nis 贝壳:文件 服务:兼容 services_compat: nis 协议:文件 rpc:文件 |
图1 - 在>system>stcp>templates中找到的默认nsswitch.conf文件。 |
#define _POSIX_C_SOURCE 200112L #include <netdb.h> #include <arpa/inet.h> #include <stdlib.h> #include <stdio.h> #include <string.h> int main (argc, argv) int argc; char *argv []; { struct hostent *hInfo; /* used to hold host information including IP address after resolving hostname */ long long jJiffy1; /* starting jiffy time */ long long jJiffy2; /* ending jiffy time */ extern void s$read_jiffy_clock(long long *); double milliseconds; /* ms between jJiffy2 & jJiffy1 */ /* process arguments. If we don't have exactly the right number of arguments print out a usage message, a version message and exit */ if (argc != 2) { printf ("Usage:ntresolve hostnamen"); exit (0); } /* Take a timestamp, resolve the name and take another timestamp */ s$read_jiffy_clock (&jJiffy1); hInfo = gethostbyname (argv [1]); s$read_jiffy_clock (&jJiffy2); milliseconds = (jJiffy2 - jJiffy1) / 65.536; if (hInfo == NULL) printf ("nCould not resolve the address of %s - %3.3f msn", argv [1], milliseconds); else { printf ("%s resolved to %s in %3.3f msn", argv [1], inet_ntoa (*(struct in_addr *)(hInfo -> h_addr_list [0])), milliseconds); } endhostent (); } |
图2 - resolve.c使用了旧的gethostbyname函数。 |
#define _POSIX_C_SOURCE 200112L #include <netdb.h> #include <arpa/inet.h> #include <sys/socket.h> #include <stdlib.h> #include <stdio.h> int main (argc, argv) int argc; char *argv []; { struct addrinfo *addressInfo; /* used to hold host information */ struct sockaddr_in *sin; /* template to extract addr info */ int error; long long jJiffy1; /* starting jiffy time */ long long jJiffy2; /* ending jiffy time */ extern void s$read_jiffy_clock(long long *); double milliseconds; /* ms between jJiffy2 & jJiffy1 */ char szIP [16]; /* holds printable IP address */ /* process arguments. If we don't have exactly the right number of arguments print out a usage message, a version message and exit */ if (argc != 2) { printf ("Usage:ntresolve hostnamen"); exit (0); } /* Take a timestamp, resolve the name and take another timestamp */ s$read_jiffy_clock (&jJiffy1); error = getaddrinfo (argv [1], NULL, NULL, &addressInfo); s$read_jiffy_clock (&jJiffy2); milliseconds = (jJiffy2 - jJiffy1) / 65.536; if (error != 0) printf ("nCould not resolve the address of %s - %3.3f msn", argv [1], milliseconds); else { if (inet_ntop (AF_INET, &(((struct sockaddr_in *)(addressInfo->ai_addr))-> sin_addr.S_un.S_addr), szIP, 16) == NULL) printf ("Could not convert address %xn", (((struct sockaddr_in *)(addressInfo->ai_addr))-> sin_addr.S_un.S_addr)); else printf ("%s resolved to %s in %3.3f msn", argv [1], szIP, milliseconds); } freeaddrinfo (addressInfo); } |
图3 - new_resolve.c使用了新的POSIX标准getaddrinfo函数。 |