要約

  • DATA終端に対する肯定完了応答は、SMTP receiverがmessageを受理し、配送または中継の責任を負ったことを示す。これはcustodyの移転であり、destination receiptではない。
  • 250はcommandとstateを失うと意味を失う。EHLO、MAIL、RCPT、RSET、NOOPの後にも同じ数字が現れるが、完全なmessageを受理したとは限らない。
  • 監査可能な記録はenvelope、recipient別応答、DATA最終応答、durable queue、次hop、本地配送を別々に結ぶ。spam配置と人の閲覧は独立した事実である。

成功したのはどのcommandか

運用画面に250 OKとだけ表示されている。数字は正しい。それでも、この一行からmessageの行方は決められない。

EHLOへの250は会話の初期状態とextensionを扱う。MAIL FROMへの応答はreverse-pathを受け入れる。RCPT TOへの応答はそのforward-pathをtransactionに残す。RSETは状態を消去した後に肯定され、NOOPは何も変えなくても肯定される。

完全なmessageが対象になるのはDATAの後半である。receiverはまず354でcontent送信を許可する。clientが本文と終端を送り終えると、serverは保存したreverse-path、成功したRCPT、mail dataを処理する。受理するなら肯定完了、受理しないならfailureを返す。この点で基本SMTPはtransactionの一部だけを受け入れる表現を持たない。

最終の肯定応答によってresponsibilityが移る。senderは、recipientに届いたと確認したからcopyを消すのではない。receiverが配送、relay、または後で判明するfailureの処理を引き受けたために消せる。

したがって、reply codeをcommandから切り離したlogは証拠を縮める。connection、transaction、MAIL FROM、RCPTの順序と結果、DATA終端、時刻、server identity、queue handleが一組になって初めてhandoffを復元できる。

John Klensinの位置も限定される。IETF Datatrackerの公式profileはDr. John C. Klensinと記し、調査時点で60件のRFCを掲載していた。RFC 5321は本人をauthorとして掲げる。これはcollective standardへの寄与であり、特定MTA、queue、vendor製品の支配や保証ではない。

応答より先に保管を終える

responsibilityの文法は実装順序に影響する。positive replyを送った後に永続化を試す設計では、senderがcopyを解放したのにreceiverにも確実なcopyがない時間が生まれる。

RFC 5321は、後のcrashや予測可能なresource不足といった軽率な理由でaccepted mailを失ってはならないとする。ただし、特定databaseやreplication方式を全運用者に強制しない。journal、transaction、mirrorなどの選択はlocalである。

standardは責任を定義できるが、ある実行でfsyncやreplicationが完了したことまでは証明しない。Heng Luのrunning-code primacyは、この差を埋めるために規格を否定するのではなく、規格から実行証拠を借りないよう求める。

「二重保存後に返答」をserviceが約束するなら、queue identifier、durability class、configuration epoch、reply時刻を結ぶ必要がある。本文を長期保存しなくても、この順序のprovenanceは残せる。

RFC authorの名前もexecution receiptにはならない。authorはgrammarに責任を持ち、implementerは順序を作り、operatorはstorageとretryを選ぶ。authorityを混ぜないことが人物記事の前提である。

relayの受理はmailboxではない

RFC 5321の責任は「deliver or relay」である。receiverがrelayなら、次は自分がSMTP clientとなり、別のserverに対して新しいtransactionを行う。各hopで新しいhandoffと新しいclockが始まる。

Received traceは経路復元に役立つ。sending hostとreceiving hostが名乗ったidentity、時刻を積み重ねる。しかしend-to-endの署名済み配送証明ではない。次queueのdurability、alias展開、gateway後のidentity、userへの表示を保証しない。

SMTPでいうfinal deliveryもscopeがある。messageがSMTP environmentを離れることを指し、通常はuserまたは関連mail dropに至るが、別のmail systemがさらに処理し転送する場合もある。protocolのfinalはhuman outcomeのfinalではない。

状態は分けるべきだ。このhopで受理、local queueに永続化、next hopが受理、local delivery agentに移管、mailboxに格納、quarantine、policy discard、user visibility unknown。公開されない状態はunknownのままにし、前hopのgreenを複製しない。

bounceがない理由は一つではない

受理後にfailureが判明した場合、receiverは通常、envelope reverse-path宛てにnotificationを作る。その通知自身はnull reverse-pathを使い、failure notificationがさらにbounceを生むloopを防ぐ。

しかし負のchannelには穴がある。original reverse-pathがnullならSMTP notificationは送れない。relay、mailing list、alias、temporary DNS errorではtransaction中にfinal addressを判断できない。現代のabuse環境では、偽装senderへのbackscatterを避けるため、不要mailを通知せず落とすpolicyも認められ得る。

ゆえに「bounceなし」はdelivery receiptではない。成功、reportがqueue中、return先なし、gatewayでstatus喪失、silent policy、単なる観測不足のいずれもあり得る。

RFC 3461、3463、3464のDSNは別のreceiptを作る。recipientごとにfailed、delayed、delivered、relayed、expandedなどを表せるが、要求したから必ず届くわけではない。relayedはfinal mailboxを主張せず、deliveredも人が読んだ証明ではない。DSN自体にも配送経路がある。

DATA最終250と後のDSNを一つにしてはいけない。前者はresponsibility holderを決め、後者は別時点のresultを報告する。joinを残すことで初めて「誰が、いつ、何を知ったか」が読める。

reply lossはduplicate riskになる

receiverが安全に保存し250を送った直後、senderがreplyを見る前にconnectionが切れる場合を考える。receiverには正当なcopyがある。senderは受理を証明できないためcopyを保持しretryする。二重配送が起こり得る。

RFC 5321がDATA terminationに長いtimeoutを置き、receiverに速やかな応答を求める理由の一つがこの曖昧さである。それでもhandoffの最後のeventを両者が必ず共有することはできない。

「final replyを観測しなかった」は「remote rejection」ではない。duplicate riskを伴うambiguous stateである。元message handle、disconnect、retry decision、downstream correlationを残す必要がある。deliveryなしとも、一回だけdeliveryとも断定できない。

positive response率も同じ境界を持つ。数えるのはacknowledged handoffであり、mailboxではない。retryとduplicate candidateを別に数えなければ、successの裏に不確実性が隠れる。

LMTPはrecipientごとに答える

SMTPではRCPTごとにDATA前の応答があるが、DATA後のcompletionはaccepted transaction全体に対する一つの結果である。

local delivery向けのLMTPは形が違う。RFC 2033はfinal dotの後、以前成功した各RCPTに一つずつ、同じ順番でreplyを返す。positive completionは対応recipientへのresponsibilityを引き受ける。

collectorはprotocolとcardinalityを保存しなければならない。SMTPの一つの250をrecipient数だけのfinal successに展開するとprecisionを捏造する。LMTP sequenceを一つに潰すとfailureを別addressに結び付ける恐れがある。

custody ledgerの最小形

最初のblockにはconnectionとtransaction、観測したendpoint、TLS contextをmessage acceptanceと分離して記録する。MAIL FROM、各RCPTとreply、354、DATA final reply、timestamp、queue IDが続く。

handoff後は新ownerがdurability、attempt、next hop、reply、ambiguous disconnectを記す。local deliveryはagentまたはLMTP resultを追加する。DSNはper-recipient ActionとStatusに加え、そのreport自身がhandoffされたかを持つ。spam placement、closed gateway、human readは独立証拠がなければunknownである。

これはminimum initial specificationであって共通softwareではない。operatorはqueue engine、retry、privacy、retentionを選べる。共通の約束は、replyからcommandを消さない、custodyをdeliveryと呼ばない、前hopの確実性を次hopへ自動継承しないことだ。

事故報告の結論はこうなる。このserverはこのenvelopeとmessageをDATA終端で受理し、responsibilityが移った。その後はこれらのrelayまたはlocal resultが確認できた。残るrecipient outcomeとuser outcomeはunknownである。

出典