メインコンテンツまでスキップ

8. On-Wire Protocol (オンワイヤープロトコル)

NTPオンワイヤープロトコルの中核は、サーバー、ピア、およびクライアント間で時刻値を交換するコアメカニズム (core mechanism) です。これは本質的に、失われたパケットや重複したパケットに対して耐性があります。データの整合性はIPおよびUDPチェックサムによって提供されます。フロー制御や再送信機能は提供されておらず、必要ありません。プロトコルはタイムスタンプ (timestamps) を使用します。これらはパケットヘッダーから抽出されるか、パケットの到着または出発時にシステムクロックから取得されます。タイムスタンプは精密データであり、リンクレベルの再送信の場合には再取得する必要があり、送信時にMACを計算する時間に対して補正する必要があります。

NTPメッセージは、一対一および一対多 (one-to-one and one-to-many) という2つの異なる通信モードを使用します。これらは一般にユニキャストおよびブロードキャスト (unicast and broadcast) と呼ばれます。このドキュメントの目的上、ブロードキャストという用語は、利用可能な任意の一対多メカニズムとして解釈されます。IPv4の場合、これはIPv4ブロードキャストまたはIPv4マルチキャスト (multicast) のいずれかに相当します。IPv6の場合、これはIPv6マルチキャストに相当します。この目的のために、IANAはIPv4マルチキャストアドレス224.0.1.1と、:101で終わるIPv6マルチキャストアドレスを割り当てています。プレフィックスはスコーピングルールによって決定されます。これらの割り当てられたマルチキャストアドレスに加えて、他の未割り当てマルチキャストアドレスも使用できます。

オンワイヤープロトコルは、図15に示すように、t1からt4まで番号付けされた4つのタイムスタンプと、org、rec、xmtの3つの状態変数を使用します。この図は、2つのピアAとBがそれぞれ他方に対するオフセットと遅延を独立して測定する最も一般的なケースを示しています。説明の目的で、パケットタイムスタンプは小文字で示され、状態変数は大文字で示されています。状態変数は、パケットの到着または出発時にパケットタイムスタンプからコピーされます。

          t2            t3           t6            t7
     +---------+   +---------+   +---------+   +---------+
     |    0    |   |    t1   |   |   t3    |   |    t5   |
     +---------+   +---------+   +---------+   +---------+
     |    0    |   |    t2   |   |   t4    |   |    t6   |  Packet
     +---------+   +---------+   +---------+   +---------+ Timestamps
     |   t1    |   |t3=clock |   |   t5    |   |t7=clock |
     +---------+   +---------+   +---------+   +---------+
     |t2=clock |                 |t6=clock |
     +---------+                 +---------+
                                                            Peer B
     +---------+   +---------+   +---------+   +---------+
org  |   T1    |   |    T1   |   | t5<>T1? |   |    T5   |
     +---------+   +---------+   +---------+   +---------+   State
rec  |   T2    |   |    T2   |   |   T6    |   |    T6   | Variables
     +---------+   +---------+   +---------+   +---------+
xmt  |    0    |   |    T3   |   |  t3=T3? |   |    T7   |
     +---------+   +---------+   +---------+   +---------+

               t2      t3                 t6          t7
     ---------------------------------------------------------
                /\         \                 /\            \
                /           \                /              \
               /             \              /                \
              /               \/           /                 \/
     ---------------------------------------------------------
          t1                t4         t5                  t8

         t1            t4            t5             t8
     +---------+   +---------+   +---------+   +---------+
     |    0    |   |    t1   |   |   t3    |   |    t5   |
     +---------+   +---------+   +---------+   +---------+
     |    0    |   |    t2   |   |   t4    |   |    t6   |  Packet
     +---------+   +---------+   +---------+   +---------+ Timestamps
     |t1=clock |   |    t3   |   |t5=clock |   |    t7   |
     +---------+   +---------+   +---------+   +---------+
                   |t4=clock |                 |t8=clock |
                   +---------+                 +---------+
                                                            Peer A
     +---------+   +---------+   +---------+   +---------+
org  |    0    |   |  t3<>0? |   |   T3    |   | t7<>T3? |
     +---------+   +---------+   +---------+   +---------+   State
rec  |    0    |   |    T4   |   |   T4    |   |    T8   | Variables
     +---------+   +---------+   +---------+   +---------+
xmt  |   T1    |   |  t1=T1? |   |   T5    |   |  t5=T5? |
     +---------+   +---------+   +---------+   +---------+

                     図15: オンワイヤープロトコル

図では、Aが送信する最初のパケットには起点タイムスタンプ (origin timestamp) t1のみが含まれており、これがT1にコピーされます。Bはt2でパケットを受信し、t1をT1に、受信タイムスタンプt2をT2にコピーします。この時点、またはt3の後のある時点で、BはAにt1、t2、および送信タイムスタンプt3を含むパケットを送信します。3つのタイムスタンプはすべて対応する状態変数にコピーされます。Aはt4で3つのタイムスタンプt1、t2、t3および宛先タイムスタンプt4を含むパケットを受信します。これら4つのタイムスタンプは、以下に説明するように、Aに対するBのオフセットと遅延を計算するために使用されます。

xmtおよびorg状態変数が更新される前に、重複、偽造、または再生されたパケットから保護するために2つのサニティチェック (sanity checks) が実行されます。上記の交換では、パケット内の送信タイムスタンプt3がorg状態変数T3と一致する場合、パケットは重複または再生です。パケット内の起点タイムスタンプt1がxmt状態変数T1と一致しない場合、パケットは偽造です。これらのいずれの場合も、状態変数が更新され、その後パケットが破棄されます。最後に送信されたパケットの再生から保護するために、xmt状態変数は偽造チェックが成功した直後にゼロに設定されます。

最新の4つのタイムスタンプT1からT4は、Aに対するBのオフセット (offset) を計算するために使用されます

theta = T(B) - T(A) = 1/2 * [(T2-T1) + (T3-T4)]

および往復遅延 (round-trip delay)

delta = T(ABA) = (T4-T1) - (T3-T2).

括弧内の量は64ビット符号なしタイムスタンプから計算され、63個の有効ビットと符号を持つ符号付き値になります。これらの値は、過去68年から未来68年までの日付を表すことができます。ただし、オフセットと遅延はこれらの値の和と差として計算され、62個の有効ビットと2つの符号ビットを含むため、過去34年から未来34年までの明確な値を表すことができます。言い換えれば、サービスが開始される前に、クライアントの時刻はサーバーの34年以内に設定する必要があります。これは64ビット整数演算の基本的な制限です。

浮動小数点倍精度演算 (floating double arithmetic) が利用可能な実装では、一次差分を浮動小数点倍精度に変換し、その演算で二次和と差を計算できます。二次項は通常、タイムスタンプの大きさに比べて非常に小さいため、精度の損失はありませんが、明確な範囲は34年から68年に復元されます。

クライアントの初期周波数オフセットが比較的大きく、実際の伝播時間が小さい一部のシナリオでは、遅延計算が負になる可能性があります。たとえば、周波数差が100 ppmで、間隔T4-T1が64秒の場合、見かけの遅延は-6.4ミリ秒です。負の値は後続の計算で誤解を招くため、deltaの値はs.rho以上にクランプする必要があります。ここで、s.rhoは第11.1節で説明されているシステム精度で、秒単位で表されます。

上記の議論では、2つの対称ピアがそれらの間のオフセットと遅延を独立して測定する最も一般的なケースを想定しています。ステートレスサーバー (stateless server) の場合、プロトコルを簡素化できます。ステートレスサーバーは、クライアントパケットからT3とT4をサーバーパケットのT1とT2にコピーし、クライアントに送信する前に送信タイムスタンプT3を追加します。残りのプロトコルフィールドを埋めるための追加の詳細は、第9節以降のセクションおよび付録に記載されています。

説明されているオンワイヤープロトコルは、サーバー応答パケットの再生に抵抗します。ただし、クライアント要求パケットの再生には抵抗せず、これにより新しいT2とT3の値を持つサーバー応答パケットが生成され、誤ったオフセットと遅延が発生します。この脆弱性は、オフセットと遅延を計算した後にxmt状態変数をゼロに設定することで回避できます。