Data Stream Interface (DSI) は、TCP上でAFPのトラフィックを運ぶために使われるセッション層である。

## 概要

1990年代にAppleが漢字Talk7にMacTCPやOpen Transportを導入した際、これらはTCPとAppleTalkの両方の上で動く ファイル共有プロトコル (AFP) を必要とした。AFP 2.xでは、AppleTalk Session Protocol (ASP) と、TCPのためのDSIを同時に導入した。

DSIはMac OSやafpfs-ngのようなAFPクライアントで直接実装されている。

## プロトコル

DSIはクライアントとAFPサーバの間の会話で使われる。全てのDSIのやりとりは、以下のようなDSIヘッダを持つ。

### パケット構造

DSIヘッダ

| Bit offset | Bits 0–7 | | | | | | | | 8-15 | | | | | | | | 15-23 | | | | | | | | 24-31 | | | | | | | |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 0 | フラグ | | | | | | | | コマンド | | | | | | | | リクエストID | | | | | | | | | | | | | | | |
| 32 | エラーコード/ 含まれるデータのオフセット | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| 64 | 全データ長 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| 96 | 予約済 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| 128 | ペイロード | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |

それぞれのフィールド:

- フラグ:: パケットがリクエスト (0x00) かリプライ (0x01) かどうか
- コマンド: 7つの有効なコマンドのうちのひとつ (下記参照)
- リクエストID: リクエストおよびそれをリプライにコピーしたシーケンシャルな識別子
- エラーコード/ 含まれるデータのオフセット:
  - リクエストでは、これはゼロのままである。ただしDSIWriteコマンドを除く。
  - リプライでは、これはエラーコードである。
- 全データ長: DSIヘッダの後の全データ長
- 予約済: 将来の拡張のため
- ペイロード: ここがDSIデータの境界であるか、または更に一般的なAFPヘッダが置かれるかどうか

### コマンド

7つの有効なコマンドがある:

DSIコマンド

| 名称 | コード | 方向 | 説明 |
| --- | --- | --- | --- |
| DSICloseSession | 1 | 両方 | 成立したセッションを閉じる |
| DSICommand | 2 | クライアントから | AFPコマンドを含む添付データ |
| DSIGetStatus | 3 | クライアントから | サーバに関する情報の取得 |
| DSIOpenSession | 4 | クライアントから | 新規セッションの成立 |
| DSITickle | 5 | 両方 | 接続がアクティブであることの確保 |
| DSIWrite | 6 | クライアントから | サーバへのデータの書き込み |
| DSIAttention | 8 | サーバから | クライアントの注意点の取得 |

### リクエストとリプライ

処理された全てのDSIリクエストはリプライメッセージで応答される。リプライは以下を含む:

- 0x01(リプライ)に設定したフラグフィールド
- リクエストと同じ値に設定したコマンド
- リクエストで送られたものと同じリクエストID (了解済のリクエストをクライアント見つけるのに使われる)
- データ長及びデータ自身。これは任意。

### セッションの確立、維持および解除

セッションはクライアントが送るDSIOpenSessionによって準備される。これはDSIAttentionパッケージのためのクライアントの受信バッファのサイズを含むであろう(Attention Quantumと呼ばれ、一般には1024である)。サーバは要求を受け入れ、データ受信バッファのサイズ(一般にはMac OS X Leopardで256k)を返す。

セッションの解除はDSICloseSessionを送ることにより、どちら側からでも行なうことができる。送り手はリプライを待つ必要はなく、メッセージを送った後にすぐセッションを閉じるべきである。

コネクションの維持はticklingにより行なわれる。DSIはクライアントとサーバが相手が今なおアクティブであることを知ることを保証するためのメカニズムを提供する。30秒毎の不活性期間をおいて、サーバはクライアントにtickleリクエストを送る。自分自身にtickleを返す。もしクライアントがそのようなリクエストを受け取らないなら、tickleを送る。クライアントもサーバも相手から120秒間tickleを聞くことがなければ、DSIセッションを終了できる。

### GetStatusによるサーバ情報の取得

これは最も複雑なDSIコマンドである。クライアントがサーバにログインすることなしに、サーバからの情報を得るのに使われる。

データの要素は構造化データを示すインデックスのカタログをもつパケットの中にまとめられる。。

DSIGetStatus要求はサーバに以下の情報を返答させるであろう:

- 基本的なサーバの性質を示すフラグ
- サーバ名(7ビットASCIIとUTF-8)
- シグネチャ: 他のAFPトランザクションのサーバと一意的に識別するために使われる
- サーバタイプ: 典型的には "Macintosh" や "Netatalk"
- AFPバージョンを示す文字列のリスト (例: "AFP3.2")
- UAMリスト: ユーザ認証方法 (User Authentication Method) を示す文字列のリスト(例 : "DHX2")
- 64x64ピクセルアイコン
- ディレクトリサーバのリスト

DSIGetStatusのリプライは、AFPやASPのFPGetSrvrParmsと同一である。

### エラーコード

エラーコードはAFPリターンコードである。

## さらなる研究

DSIは決して単独で説明されず、じゅうぶんに単純で静的である。古い参考文献は現在の実装に適している。DSIの概念はAppleTalk Session Protocol (ASP) と同一であり、Inside AppleTalk, Second Editionの概説が参考になる。

最も簡潔な手引は、Apple Filing Protocol Version 2.1 and 2.2の "AFP over TCP" の章である。

DSIを理解するのに重要な情報源は、パケットスニファを使ってAFPサーバとクライアント間の会話を解析することである。

## 参考資料

- AppleTalk Filing Protocol Version 2.1 and 2.2
- Inside AppleTalk
- Apple Filing Protocol Programming Guide, April 4, 2006
- Apple Filing Protocol Reference, May 23, 2006