标题：简单网络时间协议
介绍
简单网络时间协议（SNTP：Simple Network Time Protocol）
RFC 1305 指定了NTP协议机制中的事件，状态，传输功能和操作，另外，还有可选择的算法，它改进测时质量并且减少了一些同步源中可能存在的错误。为了获得因特网上主要路径的延时精确到毫秒级，使用一些复杂的算法或者他们的等价算法是必要的。但是，在许多场合这样的精确度是不要求，或许精确到秒已足够了。在这样的情况下，更简单的协议例如“时间协议”[POS83 ]已被使用。这些协议通过基于RPC交换：客户端请求此刻时间，然后服务器回传从某个已知时间点到现在的秒钟数。 
NTP被设计成了性能差异很大的客户端及服务器均能适用，且适用于客户端及服务器所在网络有大范围的网络延迟和抖动的情况。今天的因特网上的NTP同步子网的大多数用户使用一个软件包包括了一整套的NTP 的选择和算法，是一个比较复杂，实时的应用系统。软件要适用于多种硬件平台：从巨型计算机到个人计算机。要在这样的范围都适用，它的庞大尺寸和复杂性就不适合于很多应用了。按照要求，探求一些可供选择的访问策略( 使用适合于精确度要求不是很严格的简单软件)是有用的。 
本备忘录描述简单网络时间协议(SNTP)，它是一个简化了的NTP服务器和NTP客户端策略。SNTP在协议实现上没有什么更改，在最近也不会有什么变动。访问范例与UDP/TIME 协议是一致的，实际上，SNTP应该更容易适用于使用个人计算机的 UDP/TIME 客户。而且，SNTP 也被设计在一个专门的服务器( 包括一台集成的无线电时钟)里操作。由于在系统里的那些各种各样反应机制的设计和控制，交付调节时间精确到微秒是可能的。这样的专门设计是切实可行的。 
强烈建议SNTP 仅仅在同步子网的末端被使用。 SNTP 客户端应该仅在子网的叶子( 最高的阶层) 操作并在配置过程中没有依靠其它NTP或者SNTP客户端来同步。SNTP 服务器应该仅在子网的根( 阶层1) 操作并在配置过程中，除一台可靠的无线电时钟外中没有其它同步源。只有使用了有冗余的同步源及不同的子网路径及整套NTP实现中的crafted 算法，主服务器通常期望的可靠性才有可能达到。这种做法使主同步源在无线电时钟通信失败或者交付了错误时间时，还能用到其它几个无线电时钟和通向其它主要服务器的备份路径。因此，应该仔细考虑客户端中SNTP的使用，而不是在主服务器里的NTP的使用。
工作模式与地址分配
象NTP一样，SNTP 能在单播(点向点) 或者广播(点对多点) 模式中操作。单播客户端发送请求到服务器并且期望从那里得到答复，并且（可选的），得到有关服务器的往返传播延迟和本地时钟补偿。广播服务器周期性地送消息给一指定的IP 广播地址或者IP多播地址，并且通常不期望从客户端得到请求，广播客户端监听地址但通常并不给服务器发请求。一些广播服务器可能选择对客户端作出反应请求以及发出未经请求广播消息；同时一些广播客户端可能会送请求仅为了确定在服务器和客户端之间的网络传播延迟。 
在单播方式下，客户端和服务器的IP 地址按常规被分配。在广播方式下，服务器使用一指定的IP播送地址或者IP多播地址，以及指明的媒介访问播送地址，客户端要在这些地址上帧听。为此，IP 广播地址将限制在一个单独的IP子网范围，因为路由器不传播IP广播数据报。就以太网而论，例如，以太网媒介访问广播地址(主机部分全部为1) 被用于表示IP广播地址。
另一方面，IP 多播地址将广播的潜在有效范围扩展到整个因特网。其真实范围，组会员和路由由因特网组管理协议(IGMP) 确定 [DEE89 ]，对于各种路由协议，超出了这份资料的讨论范围。就以太网而论，例如，以太网媒介访问播送地址(全部为1)要和分配的224.0.1.1 的IP 多播地址合用。 除了IP 地址规范和IGMP，在服务器操作IP广播地址或者IP多播地址没有什么不同。  
广播客户端帧听广播地址，例如在以太网情况下主机地址全部为1的。就广播地址的IP而论，没有更进一步规定的必要了。在IP多组广播情况下，主机可能需要实现IGMP，为的是让本地路由器把消息拦截后送到224.0.1.1 多播组。这些考虑不属于这份资料的讨论范围。 
就当前指定的SNTP而论，其真正的弱点是多目广播客户端可能被一些行为不当或者敌对的在因特网别处的SNTP/NTP 多播服务器攻击而瘫痪，因为目前全部这样服务器使用相同的IP 多播地址：224.0.1.1 组地址。 所以有必要，存取控制要基于那些以客户端信任的服务器源地址，即客户端选择仅仅为自己所知的服务器。或者，按照惯列和非正式协议，全部NTP多播服务器现在在每条消息内应包括已用MD5加密的加密位，以便客户端确定消息没有在传输中被修改。SNTP 客户端能实现那些必要加密和密钥分发计划在原则上是可能的，但是这在SNTP被设计成的那些简单的系统里不可能被考虑。 
考虑到没有一个完整的SNTP规范，故IP 广播地址将使用在IP子网和局域网部分(指有完整功能的NTP服务器和SNTP客户端在同一子网上的局域网)，而对于IP 多播地址来说，将只能用在为达到以上相同目而设计的特例中。尤其，只有服务器实现了RFC 1305 描述的NTP认证时（包括支持MD5消息位的算法），在SNTP 服务器里的IP 多播地址才被使用。
SNTP时间戳格式
sntp使用在RFC 1305 及其以前的版本所描述标准NTP时间戳的格式。与因特网标准标准一致， NTP 数据被指定为整数或定点小数，位以big-endian风格从左边0位或者高位计数。除非不这样指定，全部数量都将设成unsigned的类型，并且可能用一个在bit0前的隐含0填充全部字段宽度。
因为SNTP时间戳是重要的数据和用来描述协议主要产品的，一个专门的时间戳格式已经建立。 NTP用时间戳表示为一64 bits unsigned 定点数，以秒的形式从1900 年1月1 日的0：0：0算起。整数部分在前32位里，后32bits（seconds Fraction）用以表示秒以下的部分。在Seconds Fraction 部分，无意义的低位应该设置为0。这种格式把方便的多精度算法和变换用于UDP/TIME 的表示（单位：秒），但使得转化为ICMP的时间戳消息表示法(单位：毫秒)的过程变得复杂了。它代表的精度是大约是200 picoseconds，这应该足以满足最高的要求了。 
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                           Seconds                             |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                  Seconds Fraction (0-padded)                  |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
注意，从1968 年起，最高有效位(整数部分的0 bit位) 已经被确定，64 位比特字段在2036 年将溢出。 如果NTP或者SNTP在2036 年还在使用的话，一些外部方法将有必要用来调整与1900年及2036 年有关的时间 (136 年的其它倍数也一样)。 用这样的限制使时间戳数据变得很讲究(要求合适的方法可容易地被找到)。从今以后每136 年，就会有200picosecond 的间隔，会被忽略掉，64 个比特字段将全部置为0 ，按照惯列它将被解释为一个无效的或者不可获得的时间戳。
SNTP报文格式
NTP 和SNTP 是用户数据报协议( UDP) 的客户端 [POS80 ]，而UDP自己是网际协议( IP) [DAR81 ] 的客户端. IP 和UDP 报头的结构在被引用的指定资料里描述，这里就不更进一步描述了。UDP的端口是123，UDP头中的源断口和目的断口都是一样的，保留的UDP头如规范中所述。
以下是SNTP 报文格式的描述，它紧跟在IP 和UDP 报头之后。SNTP的消息格式与RFC-1305中所描述的NTP格式是一致的，不同的地方是：
一些SNTP的数据域已被风装，也就是说已初始化为一些预定的值。NTP 消息的格式被显示如下。 
1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|LI | VN  |Mode |    Stratum    |     Poll      |   Precision   |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                            根延迟                             |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                            根差量                             |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                          参考标识符                           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
|                          参考时间戳(64)                       |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
|                           原始时间戳(64)                      |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
|                           接受时间戳 (64)                     |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
|                          传送时间戳(64)                       |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
| |
|                         认证符(可选项) (96)                   |
| |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
如下一部分描述，在SNTP 里大多数这些字段被预规定的数据给赋初值。为完整起见，每个字段的功能在下面被简要总结。 
1.       闰秒标识器：这是一个二位码，预报当天最近的分钟里要被插入或删除的闰秒秒数。用1/0表示，分别说明如下：
LI             Value                    含      义
--------------------------------------------------------------------------------------00              0                        无预告
01              1                     最近一分钟有61秒
10              2                     最近一分钟有59秒
11              3                     警告状态（时钟未同步）
2.       版本号：这是一个三bits的整数，表示NTP的版本号，现在为3。
3.       模式：这是一个三bits的整数，表示模式，定义如下：
mode                          含        义
0 保留
1 对称性激活
2 被动的对称性
3 客户端几
4 服务器
5 广播
6 为NTP控制性系保留
7 为自用保留
在点对点模式下，客户端机在请求中设置此字段为3，服务器在回答时设置此字段为4；在广播模式下，服务器在回答时设置此字段为5。
4.       stratum（层）：这是一个8bits的整数（无符号），表示本地时钟的层次水平，数值定义如下：
stratum                 含      义
0 未指定或难以获得
1 主要参考（如无线电时钟钟）
2-15 第二参考（通过NTP/SNTP）
16-255 保留
5．测试间隔：八位signed integer，表示连续信息之间的最大间隔，精确到秒的平方及。本字段的值从4（16s）到14（16284s）；然而，大多数应用使用6（64s）到10（1024s）。
6．精度：八位signed integer，表示本地时钟精度，精确到秒的平方级。值从-6（主平）到-20（微妙级时钟）。
7.       根时延：32位带符号定点小数，表示在主参考源之间往返的总共时延，以小数位后15~16bits。数值根据相关的时间与频率可正可负，从负的几毫秒到正的几百毫秒。
8.       根离散：32位带符号定点小数，表示在主参考源有关的名义错误，以小数位后15~16bits。范围：0~几百毫秒。
9.       参考时钟标识符：32bits，用来标识特殊的参考源。在stratum 0（未指定）或stratum 1（基本参考）的情况下，该字段以四个八位字节，左对齐，零填充的string表示。当没有NTP枚举时，使用下列ASCII标识符：
阶层     代码                  意思 
----------------------------------------------------------------
1        pps          精度校准源，例如ATOM(原子钟)，PPS代表(
每秒脉冲精度源)，等等 
1         service    除了一般的NTP报时服务外，例如ACTS 
(计算机自动化报时服务)，TIME（UDP/Time协议)，
TSP(Unix 报时服务协议)，DTSS. 
(数字化时间同步服务)，等等 
1         radio      一般的收音机服务，带有callsigns，例如CHU， 
DCF77， MSF， TDF， WWV， WWVB， WWVH，等等 
1     nav     无线电导航系统，例如OMEG(欧米加导航系统)， 
LORC(远距离无线电导航系统)，等等 
1     satellite   一般的卫星业务，例如GOES(地球同步轨道环境卫星)，
GPS(全球卫星定位服务)，等等 
2     address     二级参考(4个八位二进制字节表示的NTP服务器因特网
地址）
--------------------------------------------------------------------------------
10.    参考时间戳：64bits时间戳，本地时钟被修改的最新时间。
11.    原始时间戳：客户端发送的时间，64bits。
12.    接受时间戳：服务端接受到的时间，64bits。
13.    传送时间戳：服务端送出应答的时间，64bits。
14.    认证符（可选项）：当NTP的认证机制已运行后，这个字段包含认证者的信息（参见RFC1305 中的附件C）。在SNTP中本字段一般被来报输入消息所忽略，也不用在输出消息中。
SNTP客户端操作
SNTP客户端与NTP/SNTP 服务器通信的模式是一个非持久状态的远程过程调用。在单播方式，客户端发给服务器(方式3) 请求并且期望服务器答复 (方式4)。 在广播方式，客户端送并不请求只是等待一台或更多的服务器的广播消息(方式5) ，这取决于设置。 根据客户端和服务器设置，单播客户端和广播服务器通常在从64 给1024 s 的间隔里发送消息。  
单播客户端初始化SNTP 报文首部，再把消息发送到服务器，然后从服务器回复的报文中剥去时间包。为此，上面提到的所有报文首部字段，除第一个八位字节外都设置成0。 在这个八位字节里Li 字段设置为0( 没有警告) 和方式字段设置为3(客户端)。VN 字段必须同NTP 或者SNTP 服务器的软件版本一致；但是，NTP 版本3( RFC 1305)的服务器也将接受第2( RFC 1119) 版本的消息以及版本1( RFC 1059)的消息，而NTP 版本2服务器也将接受NTP 为版本1的消息。版本0 ( RFC 959) 消息不再被支持。因为今天因特网已有了NTP 服务器操作的3个版本，推荐VN 字段设置1。 
在单播及广播方式下，单播服务器回答及广播以上所述的所有字段；但是，在SNTP下，各字段中，只有传送时间戳在非零情况下才有明确的意思.这个字段的整数部分包含服务器此刻的时间，其格式与UDP/TIME 协议相同[POS83].这个字段的fraction部分通常是有效的, SNTP的精确度证明可以精确到秒。如果传送用时间戳字段是全0，则该消息将被忽略。
在广播方式下，客户端没有附加信息用以计算在服务器和客户端之间的传播延迟，因为在此方式下，传送用时间戳和接收时间戳字段是没有意义的。即使在单播方式，大多数客户端也会选择忽略原始时间戳和接收时间戳字段。但是，在单播方式下，一种简单的计算可以用来计算与服务器有关的往返传播延迟d及本地时钟补偿t，通常对在数十毫秒内。为此，客户端在请求包中将本地时钟时间按NTP的格式写入源时间戳。当收到答复时，客户端将目的时间戳作为到达时间，并根据它的本地时钟，将其转变成NTP格式。下述表格总结4个时间戳。 
用时间戳名字           ID         产生 
------------------------------------------------------------
原始时间戳        T1         时间请求由客户端送 
收到时间戳        T2         时间请求在服务器收到 
传送时间戳        T3         时间答复通过服务器送 
目的地时间戳      T4         时间答复在客户端收到 
往返传播延迟d和本地时钟补偿t定义为： 
D =( T4 - T1) - ( T2 - T3) 
T =(( T2 - T1) +( T3 - T4)) /2。 
下述表格是SNTP客户端操作的总结。在表格里显示有两种推荐的错误检查方式。在全部NTP 版本里，如果Li 字段为3；或者阶层字段不在第1-15范围里；或者传送用时间戳是0，服务器决不同步或者不予同步成过去24小时内有效的时间源。在客户端的判断中，保留字段值也可能被检查。 是否相信传送用时间戳取决于对这些字段中的一个或多个字段的有效性判断。  
字段名               请求             回答 
-------------------------------------------------------------
Li                        0       闰秒指示器； 如果是3 
(非同步)，则放弃该消息 
VN                        1( 参见正文)    忽略 
方式          3( 客户端)      忽略 
阶层                  0            忽略 
轮询                   0               忽略 
精度                  0            忽略 
根延迟               0               忽略 
根差量            0               忽略 
参考标识符            0               忽略 
参考时间戳        0               忽略 
原始用时间戳      0       忽略( 参见正文) 
收到用时间戳      0       忽略( 参见正文) 
传送天的时间戳        0       时间； 如果是0 
(非同步)，则忽略该消息 
Authenticator.      (不使用)      忽略
SNTP服务器操作
SNTP 服务器与NTP 或者SNTP客户端操作的模式是一种没有持久状态的RPC 模式。全套的NTP 算法用来支持冗余校验和不同的网络路径，SNTP服务器通常不实现全套的NTP 算法，建议一台SNTP 服务器只与一个外部同步的时钟源一道操作，例如一台可靠的无线电时钟。这样的话，服务器总是工作在阶层1。 
服务器可以工作在单播方式或广播方式或两者同时都用。当单播方式的服务器得到一条请求消息时，就在NTP或者SNTP 的来报头里修改特定字段，并把消息返回给发送人，也许还使用了与请求相同的信息缓冲区。如果不同步到一台正确操作的无线电时钟的话，服务器可能也可能不回答请求，但是回答是首选的，因为可达性可以忽略同步状态如何。在单播方式下，VN 和poll字段被完整地复制到应答包中的相同字段。如果请求的方式字段是3(客户端)，那么在答复过程中它设置成4(服务器)；否则，为了与NTP规范相符，这个字段设置成2(被动的对称性)。 
在广播方式下，服务器只有在已同步的情况下，才发消息给一个正常运行的参考时钟。在此方式下， VN 字段设置成3(针对当前的SNTP 版本)，方式字段设成5(广播)。字段poll设置服务器测试间隔，接近秒的平方。一台服务器既支持广播方式，同时也支持单播方式，这是非常合乎需要的。这对一些潜在的广播客户端来说尤其必要，因为这样做，能使用客户端机/服务器的消息来计算传播延迟，这一方法要优于只定时接收广播消息的方法。 
在单播方式和广播方式下保留的字段被同样地设置。假定服务器是被同步成一台无线电时钟或者其它正确的主要参考源，则阶层字段设置为1(主要服务器)，Li 字段设置为0；如果不是，阶层字段设置0，Li 字段设置3。精度字段的设置反映出本地时钟的最大的读数误差。对所有的实际情况来说，在NTP格式里被计算的值是小数点右边的有效数值，值被表示成负数时间戳形式。为了主服务器，根延迟和根差量字段可以设置成0，根差量字段能设置成任意数值(表示时钟的最大的期望误差值)。参考标识符设置指明主要参考源，如在上面在表格里说明的。 
这些时间戳字段被设置如下。如果服务器未被同步或是首先启动的话，全部时间戳字段设置成零。如果同步，参考用时间戳设置成最后更新时间（来源于无线电时钟）或者设置成消息被送出的时间（如果更新时间不可以获得）。接收时间戳和传送时间戳字段设置成当时消息发出的时间。在单播方式下，原始时间戳字段直接从请求包的传送时间戳拷贝过来。因为客户端要用它来检查应答，所以复制完整很重要。用广播方式下，这个字段被设置成消息被送出的时间。下面的表格总结这些操作。 
字段名               请求                 回答 
----------------------------------------------------------
Li            忽略            0(正常)， 3 
(非同步) 
VN            1， 2 或者3         3 或者从请求包中拷贝 
方式          3(参见正文)         2，4 或者5(参见正文) 
阶层                   忽略               服务器阶层 
投票                   忽略               拷贝请求包
精度                  忽略                服务器精度 
根延迟               忽略                0 
根差量            忽略            0(参见正文) 
参考标识符            忽略                来源标识符 
参考时间戳        忽略                0 或者当前的时间 
创造时间戳           忽略                 0 或者当前的时间或者从
传送时间戳请求复制 
收到时间戳            忽略                0 或者当前的时间 
传送时间戳        (参见正文)          0 或者当前的时间 
Authenticator         忽略            (不使用) 
当例如可能发生在刚启动或在运行期间主要参考源不起作用时，有一些多数客户端允许的无效时间戳的范围。一台运行不正常的服务器的最重要的标志是Li 字段，其中一3 的值表明一种非同步的状态。当这值被出现时，客户端应该丢掉该条服务器消息，而不管其它字段的内容。
参考资料
[DAR81 ]波斯特尔， J.，" 网际协议 - DARPA网际计划协议说明"，标准5，1981 年9月， DARPA， RFC 791。 
[DEE89 ]迪林， S.，" IP 多播 的主机扩展。 标准5， RFC 1112，斯坦福大学， 1989 年8月。 
[MIL92 ] Mills, D，" 网络时间协议( 第3 版本) 说明，实现和分析。 RFC 1305，特拉华大学， 1992 年3月。 
[POS80 ]波斯特尔， J.，" 用户数据报协议"，标准6， RFC 768， USC/Information 科学研究所， 1980 年8月。 
[POS83 ]波斯特尔， J. 和K. Harrenstien，" 时间协议"，标准26， RFC 868， USC/Information 科学研究所， SRI， 1983 年5月。