マルチキャストについて調べてみた

# マルチキャストとは？

ネットワークスペシャリストの学習の中でマルチキャストについて学習したのでアウトプットとして学習した内容を書いていきたいと思います

通信相手の数が異なるんだなーというあいまいな理解だったのですがこれを成り立たせる仕組みは以外と複雑でした

## テーマ

以下のテーマごとにマルチキャストについてユニキャストとの違いをもとに説明していきます

- [マルチキャストとは？](#マルチキャストとは)
  - [テーマ](#テーマ)
    - [通信対象](#通信対象)
    - [TCP/UDP](#tcpudp)
    - [IP アドレス](#ip-アドレス)
    - [宛先の特定](#宛先の特定)
      - [グループ参加プロトコル](#グループ参加プロトコル)
      - [ルーティングプロトコル](#ルーティングプロトコル)
      - [PIM-SSM](#pim-ssm)
    - [L2 スイッチ](#l2-スイッチ)
      - [マルチキャスト MAC アドレス](#マルチキャスト-mac-アドレス)
      - [IGMP スヌーピング](#igmp-スヌーピング)
      - [FEC](#fec)
  - [まとめ](#まとめ)
  - [参考資料](#参考資料)

### 通信対象

ユニキャストは 1 対 1 で特定の端末を IP アドレスによって明確に指定して送信する通信方法です

一方、マルチキャストは 1 対 多で特定のグループに属する端末に対してデータを送信する通信方法です

図でイメージするとこんな感じです

> ユニキャスト

```mermaid
graph LR;
    A[送信元] -->|パケット| B[送信先]
```

> マルチキャスト

```mermaid
graph LR;
    A[送信元] -->|パケット| B[送信先]
    A -->|パケット| C[送信先]
    A -->|パケット| D[送信先]
```

### TCP/UDP

ユニキャストでは TCP と UDP のどちらも使用することができるのに対し、マルチキャストでは UDP のみが使用されます

これは受信先を個々で指定しないため、TCP のような確認応答を行うプロトコルは使うことができないためです

> 代わりに上位プロトコルで TCP にある機能を独自に実装することでカバーすることはできます

### IP アドレス

ユニキャストにおける IP アドレスは A から C クラスが使われ、受信先を識別するために使用されます
一方、マルチキャストでは D クラスが使われ、アドレスが示す意味もユニキャストとは異なります

マルチキャストにおける IP アドレスは宛先を指定するのではなく、通信内容を示すために使用されます
以下に簡単な例を挙げておきます

- `224.0.0.1` : サブネット内の全てのホスト
- `224.0.0.2` : サブネット内のルータ
- `224.0.0.5` : OSPF ルータ
- `224.0.0.18` : VRRP ルータ

### 宛先の特定

IP アドレスが宛先を指定しない場合、どのようにして通信先を特定するのでしょうか？
マルチキャストの場合、2 つの役割のプロトコルが使用されます

- ホストがルーターに受信したい通信内容を伝える
- ルーターが通信をルーティングする

#### グループ参加プロトコル

マルチキャストの場合、ホストがルーターに対して受信したい通信内容をリクエストする必要があります
そしてそのためのプロトコルがグループ参加プロトコルです
ルーターはこのリクエストを受け取り、その情報をルーティングテーブルに登録します
IPv4 では IGMP 、IPv6 では MLD が使用されます

図でイメージすると、、、

例えば、以下の図のようにルーターに３つの端末が接続しているとします

```mermaid
graph LR;
    B[端末1] --ポート1--- A[ルータ]
    C[端末2] --ポート2--- A
    D[端末2] --ポート3--- A
```

まず、端末１がルータにグループ A のマルチキャストグループに参加するためのリクエスト(IGMP Report)を送信と

| グループ | 出力ポート |
| -------- | ---------- |
| A        | ポート１   |

のようにルータのマルチキャストルーティングテーブルが設定されます

そしてさらに端末 2 がグループ A と B のマルチキャストグループに参加するためのリクエスト(IGMP Report)を送信すると

| グループ | 出力ポート         |
| -------- | ------------------ |
| A        | ポート１、ポート 2 |
| B        | ポート 2           |

のようにルータのマルチキャストルーティングテーブルが設定されます

こうすることでルーターに送信されてきたマルチキャスト通信を適切なポートに転送することができます

#### ルーティングプロトコル

では次にルーティングプロトコルについて説明します

マルチキャストにおけるルーティングプロトコルには 2 つのモードがあります

- Dense モード
- Sparse モード

しかし、Dense モードはルーターからのマルチキャスト通信をフラッティングするだけのため、現在はあまり使用されていないので Sparse モードで使われている PIM-SSM というプロトコルを使用した場合のルーティングについて説明します

#### PIM-SSM

PIM-SSM(Protocol Independent Multicast - Source Specific Multicast)
を使用する場合、ルーティングテーブルは主にユニキャスト通信によって設定されます

> 前提としてマルチキャスト通信を受信するホストは、送信元の IP アドレスを知っている必要があります
> また、IGMP のバージョンは 3 である必要があります

PIM-SSM によるマルチキャスト通信の流れは以下のようになります

1. ホストがルーターに受信したい通信内容と送信元の IP アドレスを通知する(IGMP Report)
2. ルーターがリクエストを受け取り、その情報をもとにルーティングテーブルに登録する
3. 必要ならルーターがリクエストを送信元の IP アドレスをもとに転送する(PIM join)
4. 配信用サーバーからマルチキャスト通信が送信される
5. ルーターがマルチキャスト通信を受信した場合、ルーティングテーブルを参照し、適切なポートに転送する
6. ホストがマルチキャスト通信を受信する

### L2 スイッチ

L2 スイッチにおいてもマルチキャスト通信を行うための機能があります
というかこの機能がないとマルチキャスト通信をフラッティングしてしまうため、ネットワークに負荷がかかってしまいます

#### マルチキャスト MAC アドレス

データリンクにおいては、マルチキャスト MAC アドレスを使用して通信を行います
マルチキャスト MAC アドレスは以下のような形式になっています

```plaintext
01-00-5E-00-00-00 ～ 01-00-5E-7F-FF-FF
```

前半部分は固定で指定されて、後半部分はマルチキャストグループの IP アドレスの下位 23 ビットが使用されます

しかしこれだとどのホストがマルチキャスト通信を受信したいのかわかりません
結果として、マルチキャスト通信をフラッティングしてしまうことになります

#### IGMP スヌーピング

IGMP Report を受信すると、その情報をもとにマルチキャスト通信を受信したいポートにのみ転送するためのテーブルを作成する機能です
これによって、マルチキャスト通信をフラッティングすることなく、必要なポートにのみ転送することができます

#### FEC

UDP にはない再送信機能を実装するための機能で、本来のデータに追加してエラー訂正のための冗長データを追加することで、受信側でエラーを修正する機能です

## まとめ

個人的に深いところまでは理解してなかったところが多かったので、知れてよかったと思ってます
他のプロトコルと一部として使われているものもあるので、こういった元となる知識は大事だなと思いました

本当は PIM-SM についても書きたかったのですが、長くなりすぎるので別途書くことにします

## 参考資料

[ヤマハのIPマルチキャスト概要](https://network.yamaha.com/setting/router_firewall/multicast/outline)

PIM-SM はこっちを見たほうがいいと思います