テレビのアニメはどこから来る? / 第84話

第84話:イトは、「To」があるのに送れなかった|メールの宛先は二つ?

ピコルート第84話。To欄へaddressを書いたのにemailは動かなかった。イトは見えるheaderとSMTP envelopeを分け、宛先domainのMXから受信mail serverを探します。

SMTP envelopemessage headerMXレコード一時失敗と恒久失敗10分更新

第83話で止めた長文の封筒を、イトは郵便routeの台へ置いた。

見学者へ、入口変更を知らせるemailだ。

本文の上には、宛先が見える。

To: yui@blue-route.test
Subject: 見学入口の変更

「Toにaddressがある。これなら届く」

イトはsend leverを倒した。

封筒は一歩も動かなかった。

送信台の下で、red lampが点く。

SMTP envelope recipients: 0。

見えるToと、配送に使う宛先

本文の上に見えるToは、message contentに含まれるheader fieldだ。

mail appで人が見たり、返信や表示に使ったりする。

けれど、SMTPがserver間で配送するときは、別のenvelopeを使う。

今回の封筒には、visible Toはある。

SMTP transactionのRCPT TOに相当するenvelope recipientがない。

message content
  From / To / Subject header fields
  body

SMTP envelope
  envelope sender
  one or more envelope recipients

二つは同じaddressから作られる場合があっても、同じ役割ではない。

visible Toだけをnetworkの配送先として信じると、Bccのようにheaderへ見せないrecipientも扱えない。

反対に、headerの表示を変えただけでSMTP envelope recipientが変わるとも限らない。

ユイ

便箋の上に書く宛名と、郵便局が読む外側の宛先を分けるんですね

イト

ぼくは中のToだけ書いて、配送用の外側を空にした

マコト

相手の端末へ直接投げる前に、送り出すmail serverも必要そうだ

公開mail testまで、あと百二十秒。

入口変更はtest mailboxへ一件だけ届ける。

届かなければ失敗。

同じmailを二重配送しても失敗だ。

appから、まずsubmission serverへ

mail appは、recipient mail serverへ毎回直接つながるとは限らない。

今回のfixtureでは、イトが認証済みのsubmission serverへmessageを預ける。

submissionとserver-to-server relayは、役割とpolicyを分ける。

submission serverは、送ってよいaccountか、envelope recipientがあるか、message formatを受け付けられるかを確認する。

ここでacceptedになっても、相手が読んだわけではない。

まだ送信側のqueueへ預かった段階だ。

authenticated submitter  Ito
envelope sender          ito@pico-route.test
envelope recipient       yui@blue-route.test
message content          headers + body
queue item               mail-084

envelope senderは、配送失敗を返す先にも関係する。

visible Fromと常に同じとは決めつけない。

三つの送り方

イトは、動かなかった封筒を送信台へ残した。

その横へ、三枚のroute cardを置く。

イト

A。visible Toを読んで、そのまま相手のscreenへ投げる

イト

B。送信側serverへ預けるけれど、To headerだけを配送先として使う

イト

C。message contentとSMTP envelopeを分け、envelope recipient domainのmail exchangerをDNSで探す

Aには、相手のdeviceが何台あるか、onlineか、どこへ受信箱を置くかが分からない。

Bでは、表示用headerと実配送recipientを混ぜたままだ。

Cなら、mail appはsubmission serverへ預け、送信側serverがrecipient側mail serverを探せる。

Picoはroute cardへ触れない。

空のSMTP envelope slotと、動かない封筒だけをcyan lightで照らしている。

イトがdirect-to-screen chuteを閉じた

イトはAのdirect-to-screen chuteを閉じた。

Bのheader routes mail leverもOFFへ戻す。

Cのsubmission-to-MX railを、自分の右手で開いた。

まず、envelope recipientをSMTP transactionへ渡す。

MAIL FROM  ito@pico-route.test
RCPT TO    yui@blue-route.test
CONTENT    visible headers + body

ここでは仕組みを分けるために要素だけを示している。実際のSMTP command構文、認証、TLS、extensionの全てを再現するfixtureではない。

recipient addressの@より右、blue-route.testを取り出す。

送信側serverはDNSへMX lookupを行った。

preference 10  mx-a.blue-route.test
preference 20  mx-b.blue-route.test

MX recordは、そのdomainのmailを受け取るmail exchanger候補を示す。

数値をserverの速さscoreとはみなさない。小さいpreferenceを先に試す候補順として扱う。

イトが端末へ直接投げるchuteを閉じ、送信mail serverからMX sorterを経て受信mail serverへ一通の封筒を通す
visible Toから端末へ飛ばさず、SMTP envelope recipientのdomainからmail exchangerを探す。

一台目が沈黙しても、端末へ投げなかった

submission serverは、preference 10のmx-aへ接続を試した。

今回はtest switchで、connectionをtimeoutさせる。

イトは封筒をtablet chuteへ戻さなかった。

利用できる次のMX候補mx-bを試す。

mx-bはenvelope senderを受け、recipient yui@blue-route.testを受け、message contentを受け取った。

最後にsuccess replyを返す。

mx-a connection          timeout
mx-b recipient accepted  1
remote message accepted  1
duplicate delivery       0

recipient serverがmessageをacceptedにした時点で、そのserverは配送責任を引き受ける。

ただし、どのfolderへ置くか、spam判定でどう扱うか、userがいつ読むかは、その後の段階だ。

今回のclosed mailboxでは、受信箱へ一件だけappendした。

recipient mailbox stored 1
recipient app synced     0
human read               0

「remote accepted」を「読了」に塗り替えない。

一時失敗と恒久失敗を、同じ赤lampにしない

次に、二種類のfailureを入れた。

一つ目はtemporary reply。

recipient serverが今は処理できないが、後なら受けられる可能性を示す。

SMTPの4yz categoryは、今回のqueueでretry対象にした。

reply category  4yz temporary
queue retained  1
retry scheduled 1
failure report  0 now

fixtureでは五分後に一回retryする。

五分がemail一般の正解ではない。実運用はqueue lifetimeやretry intervalをpolicyで決める。

二つ目はpermanent recipient failure。

このmailboxは存在しない、という5yz replyを入れた。

同じaddressへ無限にretryしない。

reply category  5yz permanent
queue retained  0
retry scheduled 0
failure report  1

イトは4yzの封筒をretry shelfへ置き、5yzの封筒をstop trayへ移した。

一つのred lampへまとめず、次に取るactionを分ける。

failure report自体がさらに配送できない場合や、偽装senderへ返す危険など、mail failure handlingには追加境界がある。今回はauthenticated local senderへ返すclosed fixtureに限った。

受信箱の下に、共通の道が見えた

公開testのclockが0になる。

test mailboxには、入口変更mailが一件だけ入った。

visible Toも、SMTP envelope recipientも、意図した相手を指している。

けれど、配送に使ったのはenvelope recipientとMX routeだった。

イトはmailboxのread lampを消したままにした。

相手がmail appを開くまでは、読んだことにしない。

そのとき、mail railの床板が透明になった。

下には、小さなdata blockが流れている。

chatのeventも、pushのsmall noticeも、emailのcontentも、見た目は違う。

けれどnetworkへ出ると、どれもdataとして運ばれる。

イトは一通の封筒を受信箱へ残し、下のdata roadへ手を伸ばしたところで止めた。

次回、ピコルート第85話。

イトは、封筒も動画も同じ道へ載せる?|データ通信の共通点

この物語を、解説で深める

第84話で生まれた疑問を、解説記事で少し深く見ていきます。物語で感じた不思議さを残したまま、言葉と仕組みを順番に整理しましょう。

メールの仕組み|送信サーバーから相手の受信箱に届く流れを読む