Linux

Kernel Connection Mulitplexor (KCM)

More than 1 year has passed since last update.

はじめに

Linux 4.6でマージされたKernel Connection Mulitplexor (KCM)についてまとめます。

目的

  • TCP上にメッセージベースのプロトコルを実装する手助けをする
    • アプリケーションはデータグラム(SOCK_DGRAM)ソケットで通信できる
    • アプリケーションは独自に定義したプロトコルをカーネルに教えて、カーネルはそれを元に効率のよくメッセージを処理する
      • 例えば、ヘッダ解析やメッセージ単位でアプリケーションにデータを渡す等
  • メッセージの多重化機能を提供する
    • アプリケーションのソケット(KCMソケット)とTCPソケット間で多対多のメッセージ多重化(multiplexing)する機能を提供する
      • N対1構成も可能
    • カーネル内でうまく負荷分散してくれる
  • バッチ処理のメカニズムを提供する
    • sendmsgにMSG_BATCHフラグを渡すと、次のメッセージを待ってから送信してくれる
    • 受信はメッセージが完成してからアプリケーションに通知してくれる
      • N個溜まったら通知、が可能かは不明

なんでカーネルに実装するの?とか、なんでTCP上に実装するの?等のFAQが このマージコミット に書かれているので、気になる人は読んでみると良いかもです。

概念図

Documentation/networking/kcm.txtより抜粋。

+------------+   +------------+   +------------+   +------------+
| KCM socket |   | KCM socket |   | KCM socket |   | KCM socket |
+------------+   +------------+   +------------+   +------------+
      |                 |               |                |
      +-----------+     |               |     +----------+
                  |     |               |     |
               +----------------------------------+
               |           Multiplexor            |
               +----------------------------------+
                 |   |           |           |  |
       +---------+   |           |           |  ------------+
       |             |           |           |              |
+----------+  +----------+  +----------+  +----------+ +----------+
|  Psock   |  |  Psock   |  |  Psock   |  |  Psock   | |  Psock   |
+----------+  +----------+  +----------+  +----------+ +----------+
      |              |           |            |             |
+----------+  +----------+  +----------+  +----------+ +----------+
| TCP sock |  | TCP sock |  | TCP sock |  | TCP sock | | TCP sock |
+----------+  +----------+  +----------+  +----------+ +----------+

メッセージ解析

Berkeley Packet Filter (BPF)を使っているらしい。どのように使われるか、どうやってBPFを書くのかは別の機会に調べたいです。おそらく bpf(2)Documentation/networking/filter.txt を読むことになると思います。

使い方

  1. KCM(+KCMソケット)を作る
    • socket(AF_KCM, SOCK_DGRAM or SOCK_SEQPACKET, KCMPROTO_CONNECTED)
  2. KCMソケットを増やす
    • ioctl(kcmfd, SIOCKCMCLONE, &info)
  3. KCMにトランスポート(TCP)ソケットを繋ぐ(BPFを指定する)
    • info.fd = tcpfd
    • info.bpf_fd = bpf_prog_fd
    • ioctl(kcmfd, SIOCKCMATTACH, &info)

おわりに

あまりアプリケーションプログラムを書かないので、この機能がどの程度嬉しいのかはわからないですが、BPFで通信最適化ができて楽しそうではあります。

参考文献