プログラミングインタフェース

マルチキャストの使用

IP マルチキャストは、タイプ SOCK_DGRAM SOCK_RAW のソケット AF_INET6 AF_INET でのみサポートされます。IP マルチキャストはまた、インタフェースドライバがマルチキャストをサポートするサブネットワーク上でのみサポートされます。

IPv4 マルチキャストデータグラムの送信

マルチキャストデータグラムを送信するには、sendto(3SOCKET) 呼び出しで宛先アドレスとして 224.0.0.0 から 239.255.255.255 までの範囲の IP マルチキャストアドレスを指定します。

デフォルトでは、IP マルチキャストデータグラムは生存期間 (TTL) 1 で送信されます。この値では、データグラムは単一のサブネットワーク外には転送されません。ソケットオプション IP_MULTICAST_TTL を指定すると、後続のマルチキャストデータグラムの TTL を 0 から 255 までの任意の値に設定できます。したがって、マルチキャストの配信範囲を制御できます。

    u_char ttl;
    setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, &ttl,sizeof(ttl))

TTL 0 のマルチキャストデータグラムはどのサブネット上でも伝送されませんが、送信ホストが宛先グループに属しており、送信側ソケットでマルチキャストループバックが有効な場合は、ローカルに配信できます。最初の配信先 (ホップ) となるサブネットが 1 つまたは複数のマルチキャストルーターに接続されている場合、1 より大きな TTL を持つマルチキャストデータグラムを複数のサブネットに配信できます。配信範囲の制御に意味を持たせるために、マルチキャストルーターは TTL しきい値という概念をサポートします。このしきい値は、一定の TTL より少ないデータグラムが一定のサブネットを超えることを回避します。このしきい値は、次のような初期 TTL の値を使用して、マルチキャストデータグラムの規約を実施します。

0

同じホストに制限される

1

同じサブネットに制限される

32

同じサイトに制限される

64

同じ地域に制限される

128

同じ大陸に制限される

255

配信範囲内で制限されない

サイトと地域は厳密には定義されず、サイトはローカルの事柄としてさらに小さな管理ユニットに分割できます。

アプリケーションは、上記の TTL 以外に初期 TTL を選択できます。たとえば、アプリケーションはマルチキャスト照会を送信することによって (つまり、TTL を 0 から開始して、応答を受信するまで、TTL を大きくしていく照会のこと)、ネットワークリソースの拡張リング検索を実行できます。

マルチキャストルーターは、TTL の値にかかわらず、224.0.0.0 から 224.0.0.255 までの宛先アドレスを持つマルチキャストデータグラムを転送しません。この範囲のアドレスは、経路指定プロトコルとその他の低レベルトポロジの発見または保守プロトコル (ゲートウェイ発見、グループメンバーシップ報告など) の使用に予約されています。

ホストが複数のマルチキャスト可能なインタフェースを持つ場合でも、各マルチキャスト伝送は単一のネットワークインタフェースから送信されます。ホストがマルチキャストルーターでもあり、TTL が 1 より大きい場合には、発信元以外のインタフェースにもマルチキャストを転送できます。ソケットオプションを使用すると、特定のソケットからの後続の転送用のデフォルトを変更できます。

    struct in_addr addr;
    setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF, &addr, sizeof(addr))

addr は、希望する発信インタフェースのローカル IP アドレスです。デフォルトインタフェースに戻すには、アドレス INADDR_ANY を指定します。インタフェースのローカル IP アドレスを取得するには、SIOCGIFCONF ioctl を使用します。インタフェースがマルチキャストをサポートするかどうかを判断するには、 SIOCGIFFLAGS ioctl を使用してインタフェースフラグを取り出し、IFF_MULTICAST フラグが設定されているかどうかをテストします。このオプションは、インターネットトポロジと明確な関係があるマルチキャストルーターなどのシステムサービスを主な対象としています。

送信ホスト自体が属しているグループにマルチキャストデータグラムが送信された場合、デフォルトでは、データグラムのコピーが IP 層によってローカル配信用にループバックされます。次のように別のソケットオプションを使用すると、送信側は明示的に、後続のデータグラムがループバックされるかどうかを制御できます。

    u_char loop;
    setsockopt(sock, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop))  

loop の値は、ループバックを無効にする場合は 0、ループバックを有効にする場合は 1 です。このオプションを使用すると、自分自身の伝送を受信するというオーバーヘッドを排除できるので、単一のホストに単一のインスタンスしか持たないアプリケーションの性能が上がります。単一のホストに複数のインスタンスを持つアプリケーションや送信側が宛先グループに属さないアプリケーションは、このオプションを使用してはなりません。

送信ホストが別のインタフェースの宛先グループに属している場合、1 を超える初期 TTL で送信されたマルチキャストデータグラムは、他方のインタフェース上の送信ホストに配信できます。このような配信には、ループバック制御オプションは何の効果もありません。

IPv4 マルチキャストデータグラムの受信

IP マルチキャストデータグラムを受信するためには、ホストは 1 つまたは複数の IP マルチキャストグループのメンバーになる必要があります。プロセスは、次のソケットオプションを使用して、マルチキャストグループに加わるようにホストに求めることができます。

    struct ip_mreq mreq;
    setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) 

mreq は次の構造体です。

    struct ip_mreq {
        struct in_addr imr_multiaddr;   /* 加わるマルチキャストグループ */
        struct in_addr imr_interface;   /* 加わるインタフェース */
    }  

各メンバーシップは単一のインタフェースに関連付けられます。したがって、複数のインタフェース上にある同じグループに加わることができます。デフォルトのマルチキャストインタフェースを選択するには、imr_interface アドレスに in6addr_any を指定します。特定のマルチキャスト可能なインタフェースを選択するには、ホストのローカルアドレスの 1 つを指定します。

メンバーシップを取り消すには、次のコードを使用します。

    struct ip_mreq mreq;
    setsockopt(sock, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq))  

mreq には、メンバーシップの追加に使用した値と同じ値が入ります。ソケットを閉じるか、ソケットを保持しているプロセスを停止すると、そのソケットに関連付けられたメンバーシップは取り消されます。特定のグループ内で複数のソケットがメンバーシップを要求でき、ホストは最後の要求が取り消されるまでそのグループのメンバーにとどまります。

任意のソケットがデータグラムの宛先グループのメンバーシップを要求した場合、カーネル IP 層は受信マルチキャストパケットを受け入れます。特定のソケットがマルチキャストデータグラムを受信するかどうかは、ソケットに関連付けられた宛先ポートとメンバーシップ、または、raw ソケットのプロトコルタイプによって決定されます。特定のポートに送信されたマルチキャストデータグラムを受信するには、ローカルアドレスを未指定のまま (INADDR_ANY などに指定) ローカルポートにバインドします。

bind(3SOCKET) の前に次に示すコードがあると、複数のプロセスを同じ SOCK_DGRAM UDP ポートにバインドできます。

    int one = 1;
    setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one))  

この場合、共有ポートに向けられた各受信マルチキャストまたは受信ブロードキャスト UDP データグラムは、そのポートにバインドされているすべてのソケットに配信されます。下位互換性の理由から、この配信は単一キャストの受信データグラムには適用されません。データグラムの宛先ポートにバインドされているソケットの数にかかわらず、単一キャストデータグラムが複数のソケットに配信されることはありません。SOCK_RAW ソケットは、SO_REUSEADDR オプションがなくても単一の IP プロトコルタイプを共有できます。

マルチキャストに関連する新しいソケットオプションの説明は、<netinet/in.h> を参照してください。IP アドレスはすべて、ネットワークバイトオーダーで渡されます。

IPv6 マルチキャストデータグラムの送信

IPv6 マルチキャストデータグラムを送信するには、sendto(3SOCKET) 呼び出しで宛先アドレスとして ff00::0/8 という範囲内の IP マルチキャストアドレスを指定します。

デフォルトでは、IP マルチキャストデータグラムはホップ制限 1 で送信されます。この値では、データグラムは単一のサブネットワーク外には転送されません。ソケットオプション IPV6_MULTICAST_HOPS を指定すると、後続のマルチキャストデータグラムのホップ制限を 0 から 255 までの任意の値に設定できます。したがって、マルチキャストの配信範囲を制御できます。

    uint_l;
    setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &hops,sizeof(hops))

ホップ制限 0 のマルチキャストデータグラムはどのサブネットにも伝送できませんが、次の場合、データグラムはローカルに配信できます。

最初の配信先 (ホップ) となるサブネットが 1 つまたは複数のマルチキャストルーターに接続されている場合、1 より大きなホップ制限を持つマルチキャストデータグラムを複数のサブネットに配信できます。IPv4 マルチキャストアドレスと異なり、IPv6 マルチキャストアドレスには、アドレスの最初の部分にコード化された明示的な配信範囲情報が含まれます。定義されている配信範囲を次に示します (X は未指定)。

ffX1::0/16

ノード - ローカルな配信範囲 — 同じノードに制限される

ffX2::0/16

リンク - ローカルな配信範囲

ffX5::0/16

サイト - ローカルな配信範囲

ffX8::0/16

組織 - ローカルな配信範囲

ffXe::0/16

グローバルスコープ

アプリケーションは、マルチキャストアドレスの配信範囲とは個別に、異なるホップ制限値を使用できます。たとえば、アプリケーションはマルチキャスト照会を送信することによって (つまり、ホップ制限を 0 から開始して、応答を受信するまで、ホップ制限を大きくしていく照会のこと)、ネットワークリソースの拡張リング検索を実行できます。

ホストが複数のマルチキャスト可能なインタフェースを持つ場合でも、各マルチキャスト伝送は単一のネットワークインタフェースから送信されます。ホストがマルチキャストルーターでもあり、ホップ制限が 1 より大きい場合には、発信元以外のインタフェースにもマルチキャストを転送できます。ソケットオプションを使用すると、特定のソケットからの後続の転送用のデフォルトを変更できます。

    uint_t ifindex;

    ifindex = if_nametoindex )"hme3");
    setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_IF, &ifindex,
          sizeof(ifindex))

ifindex は、希望する発信インタフェースのインタフェースインデックスです。デフォルトインタフェースに戻すには、値 0 を指定します。

送信ホスト自体が属しているグループにマルチキャストデータグラムが送信された場合、デフォルトでは、データグラムのコピーが IP 層によってローカル配信用にループバックされます。別のソケットオプションを使用すると、送信側は明示的に、後続のデータグラムをループバックするかどうかを制御できます。

    uint_t loop;
    setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &loop, 
            sizeof(loop))  

loop の値は、ループバックを無効にする場合は 0、ループバックを有効にする場合は 1 です。単一のホストにインスタンスを 1 つしか持たないアプリケーション (ルーターやメールデーモンなど) では、このオプションを使用するとアプリケーション自体の伝送を受信するオーバーヘッドが排除されるため、性能が向上します。このオプションは、単一のホスト上に複数のインスタンスを持つアプリケーション (会議システムプログラムなど) や送信側が宛先グループに属さないアプリケーション (時間照会プログラムなど) に使用してはなりません。

送信ホストが別のインタフェースの宛先グループに属している場合、1 を超えるホップ制限で送信されたマルチキャストデータグラムは、他方のインタフェース上の送信ホストに配信できます。このような配信には、ループバック制御オプションは何の効果もありません。

IPv6 マルチキャストデータグラムの受信

IP マルチキャストデータグラムを受信するためには、ホストは 1 つまたは複数の IP マルチキャストグループのメンバーになる必要があります。プロセスは、次のソケットオプションを使用して、マルチキャストグループに加わるようにホストに求めることができます。

    struct ipv6_mreq mreq;
    setsockopt(sock, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq)) 

mreq は次の構造体です。

    struct ipv6_mreq {
        struct in6_addr ipv6mr_multiaddr;   /* IPv6 マルチキャストアドレス */
        unsigned int    ipv6mr_interface;   /* インタフェースインデックス */
    }  

各メンバーシップは単一のインタフェースに関連付けられます。したがって、複数のインタフェース上にある同じグループに加わることができます。デフォルトのマルチキャストインタフェースを選択するには、ipv6_interface 0 を指定します。マルチキャスト可能なインタフェースを選択するには、ホストのインタフェースの 1 つのインタフェースインデックスを指定します。

グループから抜けるには、次のコードを使用します。

    struct ipv6_mreq mreq;
    setsockopt(sock, IPPROTO_IPV6, IP_LEAVE_GROUP, &mreq, sizeof(mreq))  

mreq には、メンバーシップの追加に使用した値と同じ値が入ります。ソケットを閉じるか、ソケットを保持しているプロセスを停止すると、そのソケットに関連付けられたメンバーシップは取り消されます。複数のソケットは特定のグループ内の 1 つのメンバーシップを要求できます。このとき、ホストは最後の要求が取り消されるまでそのグループのメンバーに残ります。

任意のソケットがデータグラムの宛先グループのメンバーシップを要求した場合、カーネル IP 層は受信マルチキャストパケットを受け入れます。特定のソケットがマルチキャストデータグラムを受信するかどうかは、ソケットに関連付けられた宛先ポートとメンバーシップ、または、raw ソケットのプロトコルタイプによって決定されます。特定のポートに送信されたマルチキャストデータグラムを受信するには、ローカルアドレスを未指定のまま (INADDR_ANY などに指定) ローカルポートにバインドします。

bind(3SOCKET) の前に次に示すコードがあると、複数のプロセスを同じ SOCK_DGRAM UDP ポートにバインドできます。

    int one = 1;
    setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one))  

この場合、ポートにバインドされているすべてのソケットは、共有ポートに向けられたすべての受信マルチキャスト UDP データグラムを受信します。下位互換性の理由から、この配信は単一キャストの受信データグラムには適用されません。データグラムの宛先ポートにバインドされているソケットの数にかかわらず、単一キャストデータグラムが複数のソケットに配信されることはありません。SOCK_RAW ソケットは、SO_REUSEADDR オプションがなくても単一の IP プロトコルタイプを共有できます。

マルチキャストに関連する新しいソケットオプションの説明は、<netinet/in.h> を参照してください。IP アドレスはすべて、ネットワークバイトオーダーで渡されます。