「コンピューター入門」 の記事「ルーターの仕組み」を読んだことがあれば、ネットワーク トラフィックを管理し、パケットを送信するための最適なルートを見つけるためにルーターが使用されることをご存知でしょう。しかし、ルーターがこれをどのように行うか考えたことがありますか?ルーターは、パケットをどこにどのように送信するかを決定するために、ネットワークのステータスに関する情報を必要とします。しかし、彼らはどのようにしてこの情報を収集するのでしょうか?
この記事では、ルーターがパケットの送信先を決定する際にどのような情報を使用するかを正確に説明します。
基本
ルーターはルーティング アルゴリズムを使用して、宛先への最適なルートを見つけます。 「最適なルート」というときは、ホップ数 (ネットワーク内のあるルーターまたは中間点から別のルーターまたは中間点までのパケットの移動)、時間遅延、パケット送信の通信コストなどのパラメーターが考慮されます。
ルーターがネットワークの構造に関する情報を収集する方法と、最適なルートを特定するための情報の分析に基づいて、グローバル ルーティング アルゴリズムと分散型ルーティング アルゴリズムという 2 つの主要なルーティング アルゴリズムがあります。分散型ルーティング アルゴリズムでは、各ルーターは、直接接続されているルーターに関する情報を持っています。ネットワーク内のすべてのルーターについては知りません。これらのアルゴリズムは、 DV (距離ベクトル) アルゴリズムとしても知られています。グローバル ルーティング アルゴリズムでは、すべてのルーターがネットワーク内の他のすべてのルーターとネットワークのトラフィック ステータスに関する完全な情報を持っています。これらのアルゴリズムは、 LS (リンク ステート) アルゴリズムとも呼ばれます。 LS アルゴリズムについては次のセクションで説明します。
LS アルゴリズム
LS アルゴリズムでは、すべてのルーターは次の手順に従う必要があります。
- 物理的に接続されているルーターを特定し、その IP アドレスを取得する ルーターが動作を開始すると、まずネットワーク上に「HELLO」パケットが送信されます。このパケットを受信した各ルータは、そのIP アドレスを含むメッセージで応答します。
- 隣接ルータの遅延時間 (または、平均トラフィックなどのネットワークのその他の重要なパラメータ) を測定します。これを行うために、ルータはネットワーク上でエコー パケットを送信します。これらのパケットを受信したすべてのルーターは、エコー応答パケットで応答します。往復時間を 2 で割ることにより、ルーターは遅延時間をカウントできます。 (往復時間は、ネットワーク上の現在の遅延の尺度であり、リモート ホストからバウンスされたパケットのタイミングを測定することでわかります。) この時間には、送信時間と処理時間の両方が含まれることに注意してください。つまり、パケットが宛先に到達するまでにかかる時間であり、受信者がそれを処理して返信するのにかかる時間。
- 他のルーターに対してネットワーク上で情報をブロードキャストし、他のルーターの情報を受信する このステップでは、すべてのルーターが知識を共有し、相互に情報をブロードキャストします。このようにして、すべてのルータはネットワークの構造と状態を知ることができます。
- 適切なアルゴリズムを使用して、ネットワークの 2 つのノード間の最適なルートを特定します。このステップでは、ルーターはすべてのノードへの最適なルートを選択します。これは、ダイクストラ最短経路アルゴリズムなどのアルゴリズムを使用して行われます。このアルゴリズムでは、ルーターは、他のルーターから収集した情報に基づいて、ネットワークのグラフを構築します。このグラフは、ネットワーク内のルーターの位置と相互のリンクを示します。すべてのリンクには、重みまたはコストと呼ばれる数値がラベル付けされています。この数値は、遅延時間、平均トラフィック、および場合によっては単純にノード間のホップ数の関数です。たとえば、ノードと宛先の間に 2 つのリンクがある場合、ルーターは重みが最も小さいリンクを選択します。
ダイクストラ アルゴリズムは次の手順を実行します。
- ルーターはネットワークのグラフを構築し、送信元ノードと宛先ノードを、たとえば V1 と V2 として識別します。次に、「隣接行列」と呼ばれる行列を構築します。この行列において、座標は重みを示します。たとえば、[i, j] は Vi と Vj の間のリンクの重みです。 Vi と Vj の間に直接的なリンクがない場合、この重みは「無限大」として識別されます。
- ルーターは、ネットワーク上のすべてのノードのステータス レコード セットを構築します。レコードには 3 つのフィールドが含まれています。 先行フィールド – 最初のフィールドは前のノードを示します。長さフィールド – 2 番目のフィールドには、ソースからそのノードまでの重みの合計が表示されます。ラベルフィールド – 最後のフィールドはノードのステータスを示します。各ノードは、「永続」または「暫定」という 1 つのステータス モードを持つことができます。
- ルータはステータス レコード セットのパラメータを (すべてのノードに対して) 初期化し、その長さを「無限大」に、ラベルを「暫定」に設定します。
- ルーターは T ノードを設定します。たとえば、V1 がソース T ノードになる場合、ルーターは V1 のラベルを「永続」に変更します。ラベルが「永続」に変更されると、再度変更されることはありません。 T ノードはエージェントであり、それ以上のものではありません。
- ルーターは、ソース T ノードに直接リンクされているすべての仮ノードのステータス レコード セットを更新します。
- ルーターはすべての仮ノードを調べ、V1 に対する重みが最も低いノードを選択します。そのノードが宛先 T ノードになります。
- このノードが V2 (目的の宛先) ではない場合、ルーターはステップ 5 に戻ります。
- このノードが V2 の場合、ルーターはステータス レコード セットから以前のノードを抽出し、V1 に到達するまでこれを実行します。このノードのリストには、V1 から V2 への最適なルートが表示されます。
次のページでは、このアルゴリズムを例として使用します。
例: ダイクストラアルゴリズム
ここでは、A と E の間の最適なルートを見つけたいと考えています (下記を参照)。 A と E の間には 6 つの可能なルート (ABE、ACE、ABDE、ACDE、ABDCE、ACDBE) があることがわかります。ABDE の重みが最も低いため、ABDE が最適なルートであることは明らかです。しかし、人生は常にそれほど簡単ではなく、最適なルートを見つけるためにアルゴリズムを使用しなければならない複雑なケースもあります。
- 最初の画像でわかるように、ソース ノード (A) は T ノードとして選択されているため、そのラベルは永続的です (永続ノードは黒丸で、T ノードは –> 記号で示されています)。
- 次のステップでは、T ノード (B、C) に直接リンクされている仮ノードのステータス レコード セットが変更されたことがわかります。また、B の重みが小さいため、T ノードとして選択され、そのラベルは永続的なものに変更されました (下記を参照)。
- ステップ 3 では、ステップ 2 と同様に、T ノード (D、E) への直接リンクを持つ仮ノードのステータス レコード セットが変更されています。また、D の重みが小さいため、T ノードとして選択され、そのラベルは永続的なものに変更されました。
- ステップ 4 では、仮のノードがないため、次の T ノードを特定するだけです。 E の重みが最も小さいため、T ノードとして選択されます。
最後にEが目的地なのでここで終わります。
もう終わりだ!次に、ルートを特定する必要があります。 E の前のノードは D、D の前のノードは B、B の前のノードは A です。したがって、最適なルートは ABDE です。この場合、合計の重みは4 (1+2+1) になります。
このアルゴリズムはうまく機能しますが、非常に複雑なため、ルーターが処理するのに時間がかかり、ネットワークの効率が低下する可能性があります。また、ルーターが他のルーターに間違った情報を与えた場合、すべてのルーティング決定が無効になります。このアルゴリズムをよりよく理解するために、C で書かれたプログラムのソースを次に示します。
#define MAX_NODES 1024 /* 最大ノード数 */
#define INFINITY 1000000000 /* すべての最大パスより大きい数値 */
int n,dist[MAX_NODES][MAX_NODES]; /*dist[I][j] は i から j までの距離です */
void short_path(int s,int t,int path[ ])
{struct state { /* 作業中のパス */
int 先行関数 ; /*前のノード */
int length /*ソースからこのノードまでの長さ*/
enum {永続的、暫定的} label /*ラベルの状態*/
}状態[MAX_NODES];
int I、k、分;
構造体の状態 *
p;
for (p=&state[0];p < &state[n];p++){ /*状態を初期化します*/
p->先行=-1
p->長さ=無限大
p->label=暫定;
}
状態[t].length=0;状態[t].label=永続的;
k=t ;
/*k は最初の作業ノードです */
する{
/* k からのパスの方が良いですか? */
I=0の場合;私は<n; I++)
/*このグラフには n 個のノードがあります */
if (dist[k][I] !=0 && state[I].label==暫定){
if (state[k].length+dist[k][I] < state[I].length){
state[I].predecessor=k;
state[I].length=state[k].length + dist[k][I]
}
}
/* 最小のラベルを持つ暫定的にラベル付けされたノードを検索します。 */
k=0;min=INFINITY;
for (I=0;I < n;I++)
if(state[I].label==暫定 && state[I].length <
min)=state[I].length;
k=私;
}
state[k].label=永続的
}while (k!=s);
/*パスを出力配列にコピーします*/
I=0;k=0
Do{path[I++]=k;k=state[k].predecessor;} while (k > =0);
}
DV アルゴリズム
DV アルゴリズムは、ベルマン-フォード ルーティング アルゴリズムおよびフォード-フルカーソン ルーティング アルゴリズムとしても知られています。これらのアルゴリズムでは、すべてのルーターに、宛先への最適なルートを示すルーティング テーブルがあります。ルーター J の典型的なグラフとルーティング テーブルがページの上部に表示されます。
表が示すように、ルータ J がパケットをルータ D に受け取りたい場合は、ルータ H にパケットを送信する必要があります。パケットがルータ H に到着すると、ルータ H は自身のテーブルを確認し、パケットを D に送信する方法を決定します。
DV アルゴリズムでは、各ルーターは次の手順に従う必要があります。
- 直接接続されているリンクの重みをカウントし、その情報をテーブルに保存します。
- 特定の期間内に、そのテーブルをその隣接ルータ (すべてのルータではない) に送信し、各隣接ルータのルーティング テーブルを受信します。
- 近隣のルーティング テーブルの情報に基づいて、自身のルーティング テーブルを更新します。
DV アルゴリズムの最も重要な問題の 1 つは、「無限までカウントする」と呼ばれます。この問題を例を使って調べてみましょう。
以下に示すようなグラフのあるネットワークを想像してください。このグラフからわかるように、A とネットワークの他の部分の間にはリンクが 1 つだけあります。ここでは、すべてのノードのグラフとルーティング テーブルが表示されます。
ここで、A と B の間のリンクが切断されたと想像してください。このとき、B はテーブルを修正します。一定時間が経過すると、ルーターはテーブルを交換するため、B は C のルーティング テーブルを受け取ります。 C は A と B の間のリンクに何が起こったのかを知らないため、重み 2 の A へのリンクがあると言います (C から B へのリンクは 1、B から A へのリンクは 1 ですが、実際にはそうではありません)。 B には A へのリンクがないことはわかっています)。 B はこのテーブルを受け取り、C と A の間に別のリンクがあると考えます。そのため、テーブルを修正し、無限大を 3 に変更します (C が言ったように、B から C の場合は 1、C から A の場合は 2)。もう一度、ルーターはテーブルを交換します。 C が B のルーティング テーブルを受信すると、B が A へのリンクの重みを 1 から 3 に変更したことがわかります。そのため、C はテーブルを更新し、A へのリンクの重みを 4 に変更します (C から B へのリンクの重みは 1、C から B へのリンクの重みは 3)。 Bが言ったように、BからAへ)。
このプロセスは、すべてのノードが A へのリンクの重みが無限であることを認識するまでループします。この状況を次の表に示します。このように、専門家は DV アルゴリズムの収束速度が遅いと述べています。
この問題を解決する 1 つの方法は、ルーターが宛先への排他的リンクではない近隣ルーターにのみ情報を送信することです。たとえば、この場合、A への唯一の手段が B であるため、C は A に関する情報を B に送信すべきではありません。
階層型ルーティング
ご覧のとおり、LS アルゴリズムと DV アルゴリズムの両方で、すべてのルーターは他のルーターに関する情報を保存する必要があります。ネットワークのサイズが大きくなると、ネットワーク内のルーターの数も増加します。その結果、ルーティング テーブルのサイズも増加し、ルーターはネットワーク トラフィックを効率的に処理できなくなります。この問題を解決するために、階層ルーティングを使用します。この主題を例を使って調べてみましょう。
DV アルゴリズムを使用して、ノード間の最適なルートを見つけます。以下に示す状況では、ネットワークのすべてのノードが 17 レコードを含むルーティング テーブルを保存する必要があります。 A の典型的なグラフとルーティング テーブルは次のとおりです。
階層型ルーティングでは、ルーターはリージョンと呼ばれるグループに分類されます。各ルーターは、自分のリージョン内のルーターに関する情報のみを持ち、他のリージョンのルーターに関する情報は持ちません。したがって、ルーターは他のリージョンごとに 1 つのレコードをテーブルに保存するだけです。この例では、ネットワークを 5 つの地域に分類しました (下記を参照)。
A がリージョン 2 (D、E、F、または G) 内のいずれかのルーターにパケットを送信したい場合は、パケットを B に送信します。ご覧のとおり、このタイプのルーティングではテーブルを要約できるため、ネットワーク効率が向上します。上の例は、2 レベルの階層ルーティングを示しています。 3 レベルまたは 4 レベルの階層ルーティングを使用することもできます。
3 レベルの階層ルーティングでは、ネットワークはいくつかのクラスターに分類されます。各クラスターは多数のリージョンで構成されており、各リージョンには複数のルーターが含まれています。階層ルーティングはインターネット ルーティングで広く使用されており、いくつかのルーティング プロトコルを利用します。