要約

  • FTP の一つのファイル操作は二本の接続にまたがった。データ接続がバイトを運び、制御接続がコマンド状態を運ぶ。1yz は肯定的でも予備的であり、後続の完了応答を必要とした。
  • データ接続の閉鎖には、正常な EOF、中止、ポート指定の変更、制御接続の終了、回復不能なエラーという異なる原因があり得た。閉じ方だけでは結果を決められない。
  • 実行中の転送を ABOR した場合、426 は元の転送の異常終了、続く 226 は中止コマンドの正常処理を報告する。最後の肯定コードだけを見ると、取り消した仕事を成功した仕事に変えてしまう。

データ経路は「なぜ止まったか」を知らない

FTP クライアントの画面では、一つの進捗バーが一つの処理に見える。しかしプロトコルの内部では、長く維持される制御接続と、転送ごとに現れるデータ接続が別々に働く。前者にはコマンドと三桁応答が流れ、後者にはディレクトリ一覧やファイルの内容が流れた。

データ転送プロセスが観測できるのは、接続の成立、オクテット、EOF、輸送障害である。サーバーのプロトコル解釈部は、どのコマンドが進行中か、予備応答を返したか、どの最終応答でその要求を閉じるかを知る。

二本の記録は重複した領収書ではない。片方を失えば、残りが自動的に全体の意味を引き継ぐわけでもない。FTP はこの区別によって制御を継続させながらデータ経路を使い捨てられたが、監視側には「TCP の終了をアプリケーション成功に昇格させない」という責任が残った。

初期仕様にも「正しい終了」と「閉じた未完了」があった

現在の応答クラスより前から差は明示されていた。1972 年 7 月の RFC 354252 FTP transfer completed correctly を定義し、別に 452 FTP: File transfer incomplete, data connection closed を置いた。

どちらもデータ接続が閉じた後に現れ得る。違いはソケットの状態ではなく、サーバーがファイル転送をどう評価したかにあった。古い二つのコードは、「正常な FIN なら成功」という後世の短絡を既に否定している。

当時の FTP は、文字表現、論理バイト長、レコード構造、保存方式が異なるホストを接続した。ネットワーク上のバイトが尽きても、変換やローカル書き込みの結果まで一意には定まらない。制御対話は、その異種環境をまたぐ共通の状態表現でもあった。

ただし、サーバーごとに異なる説明文は機械処理に向かなかった。数字だけで、待つべきか、追加情報を送るべきか、新しい要求に移れるかを判断できる必要があった。

最初の一桁が次の行動を決めた

1974 年の RFC 640 は応答体系を整理した。1yz は肯定予備で、要求された動作は始まったが未完了、別の応答が来る。2yz は肯定完了。3yz は追加情報待ちの肯定中間。4yz5yz は、再試行の含意を異にする否定完了である。

ここでは「肯定」と「完了」が同義ではない。150 はデータ側へ注意を移す合図になっても、ファイル操作を成功として計上する権限は持たない。

RFC 640 は予備応答を送る時点も早めた。転送可能で、データ接続が存在するか、これから接続を試す段階で送れるようにした。応答性は上がるが、証明の範囲は狭くなる。接続を試みる準備と、接続の成立と、転送の完了は三つの別の事実である。

一つの 1yz の後に最終応答が残っていた

RFC 765 と 1985 年の RFC 959 は二段階を維持した。RFC 959 では一つのコマンドにつき 1yz は高々一回で、その後に完了応答が必要となる。

ファイル操作の表を見ると、125 はデータ接続が既に開いて転送を始めること、150 はファイル状態に問題がなくデータ接続を開こうとしていることを表す。最終結果は 226250、または 425426451551552 などの失敗となる。

したがって、150 と期待どおりのバイト数と FIN だけでは、FTP の記録として未完である。逆に、バイト数が合っても最終否定応答は消えない。観測が食い違ったときこそ、両方を残す価値がある。

通常の次コマンドを完了応答まで待つ理由もここにある。制御側では前の状態遷移が続いている。ABORSTAT が特別なのは、進行中の処理に割り込み、または状態を問い合わせる必要があるからだ。

閉鎖理由は一つではなかった

RFC 959 はサーバーがデータ接続を閉じる理由を複数挙げる。正常な転送完了、ABOR の受信、ユーザーによるポート指定の変更、制御接続の正常または異常終了、回復不能なエラーである。

輸送層では似た閉鎖に見えても、コマンドの結果は異なる。整然とした TCP FIN は、予定境界まで到達したか、ローカルなファイル操作が成立したか、意図的な中止だったかを語らない。

Stream モードでは接続を閉じることがファイル終端の表現になる。しかしそれはフレーミング規則であり、成功証明の拡張ではない。再開処理を考えれば限界は明瞭で、制御記録を欠いた閉鎖だけでは正常終了と途中切断を分けられない場合がある。

監視記録では、「データ EOF/閉鎖を観測」と「FTP コマンドがコード X で完了」を別のイベントにする必要がある。同時刻でも同じ証拠ではない。

226 が成功させたのは中止だった

ABOR は最後の行だけを読む危険を示す。元のサービスが既に完了していれば、中止すべき作業はない。それでもサーバーは ABOR を処理した結果として 226 を返せる。これは前のファイルを改めて保証する応答ではない。

転送が進行中なら、RFC 959 は二つの応答を求める。まず 426 がデータ接続の閉鎖と元の転送の中止を報告し、次に 226ABOR の正常処理を報告する。

対応は次のようになる。

  1. 元の転送 → 異常終了(426
  2. 中止要求 → 正常完了(226

最後のコードだけ保存すれば、取り消された転送を成功にしてしまう。二つとも元の転送に付ければ、中止コマンドの成功を失う。応答の意味は、順序と所有するアクションを含めて初めて定まる。

226 は耐久性や内容同一性を保証しない

通常の転送で 226 が示すのは、FTP 境界におけるデータ接続の閉鎖と要求されたファイル操作の成功である。内容ハッシュ、オブジェクト版、永続媒体への同期、バックアップ、将来の権限、下流アプリケーションの受理は含まれない。

より強い主張には別の領収書が要る。ハッシュは内容を比較し、永続化記録はローカル保存を語り、不変 ID は版を区別し、アプリケーション応答は後続利用を語る。

また、226 を受け取らなかったことは副作用がなかった証明でもない。サーバーが書き込みを終えた直後、制御接続だけ失われることがある。無条件の再送は重複や上書きを起こす。ここで正しい結論は「FTP 結果不明」であり、「何も起きなかった」ではない。

転送記録には制御履歴も必要だった

監査可能な記録には、コマンドと順序、125/150、データ終端点、接続結果、バイト数、EOF、判明している閉鎖原因、全最終応答、ABOR/STAT の時刻関係が必要である。

加えて、表現とモード、パス解決、ファイル操作の副作用、永続化、独立ハッシュ、オブジェクト版を別項目として保存する。FTP の応答で代用しない。

状態も done 一つでは足りない。予備受理、接続待ち、データ転送中、データ閉鎖後の最終待ち、転送肯定完了、転送否定完了、中止要求済み、元転送中止済み、中止処理済み、制御結果不明を区別すべきである。

この順序を圧縮すると、後から最後のコードの対象を復元できない。不可逆な損失は、接続が閉じたときではなく、意味の履歴を捨てたときに起きる。

情報源と証拠の限界

本稿は RFC 354RFC 542RFC 640RFC 765RFC 959RFC 1123 に基づく。応答クラス、二本の接続、閉鎖理由、ファイル操作の順序、ABOR の帰属はこれらから確認できる。

RFC 1123 が 1989 年に再開、ABOR、Block モードを有用だが広く実装されていないと述べた点は、当時の観測である。現在の製品普及率、実装適合性、ファイルシステムの耐久性を示す資料ではない。