The owner, 2026-10-16: the Inbound log lacks the upstream's answer - "Не понятна судьба письма: принято, отклонено, хост не доступен"; the result in the row only, a page per message later if needed. Mockups5348330and46b90d2, plan295d72e. - Migration 0012: inbound_spam_log gains queue_id, upstream_status ('', queued, held, sent, deferred, bounced; CHECK), upstream_relay, upstream_reply, upstream_at, and a partial index on queue_id. Schema 12. - The inbound journal milter writes an accepted row with the queue id of end-of-message and "queued" ("held" when the filter had it held), the recipient as Postfix logs it (recipientAsLogged), after detaching older rows of a queue id Postfix uses again; no queue id, no result. - The tailer: a delivery line no send-log row took goes to the journal - status, relay= ("" for none), the reply after the first status=, cut to 255 printable bytes, the line's time; queued/held/deferred rows only, sent and bounced final. qmgr's expiry makes them bounced, keeping the last reply. cleanup's "removed (" detaches rows of a message never queued. Addresses in delivery lines are read by Postfix's quoting (loggedAddress): a quoted RCPT TO cannot end one early. - The page: an Upstream column - a plain tag for queued and held, else a tag opening the host, the reply, when and what follows; "—" for refused mail and older rows. Help (word for word with the mockup), guide, architecture, security, schema-migrations, CHANGELOG. Reviewed before the commit (technical and security, 2026-10-16); the plan lists each finding and what it became. Tests: store (results, finality, expiry, held, a reused id, the queue-id index in every plan), milter (queue id, held, quoted recipient, no {i}), logtail (relay and reply, a forged quoted recipient, Run hands the journal what the send log did not take, cleanup's removal), view (the column, held, null sender), e2e (both relayed messages sent with the sink's 250; an upstream refusing connections deferred with the reason and no host, then expired to bounced; the refused row has none). go vet + go test (26 packages) and make e2e on the test server for this tree. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -368,6 +368,28 @@ operator can act on it.
|
||||
ask for it at all, an application with a client-address list is refused when
|
||||
no address is known, and neither milter replies anything but "continue" to a
|
||||
message it lets through. `test/e2e` sends two `MAIL FROM` on one connection.
|
||||
- **The upstream's answer is an update of a row, not a row**
|
||||
(inbound-upstream-result, `2.10.0`). A delivery line of mail accepted on
|
||||
port 25 changes the result of that message's journal rows and adds
|
||||
nothing: a stranger who sends more mail gets more rows from the milter, as
|
||||
before, and each row at most one update per delivery attempt, at Postfix's
|
||||
retry pace. The lines themselves of port-25 mail are still not kept. What
|
||||
is written: the status and the time are Postfix's fields; the host is
|
||||
Postfix's `relay=`, the reply the upstream's words - which may quote the
|
||||
stranger's address - or Postfix's own about a host it could not reach, both
|
||||
printable and cut to 255 bytes, shown in `sp-mono` cells like a refusal's
|
||||
reply (escaped by html/template). The stranger's own text reaches the line
|
||||
only as its `to=` and `orig_to=`, which is the key and nothing else: they
|
||||
are read by Postfix's quoting (`loggedAddress`, `internal/logtail`), so a
|
||||
quoted RCPT TO holding `>`, `,` or `status=` cannot end the address early
|
||||
and pass fields of its own for another recipient's row - and one holding an
|
||||
`@` is a routed address, which port 25 refuses as relaying
|
||||
(`allow_untrusted_routing=no`). Short queue ids repeat (Postfix's default
|
||||
`enable_long_queue_ids=no`): before writing a message's rows the milter
|
||||
detaches older rows of its queue id, so a message that is gone cannot take
|
||||
a new one's results. Accepted: a row whose insert waited longer than the
|
||||
milter's 30 s timeout - the database held - can miss its first delivery
|
||||
line and stay `queued`.
|
||||
- **The inbound journal is written from what strangers send.** The inbound
|
||||
journal milter is the last on port 25, read-only and attached fail-open; it
|
||||
keeps of the filter's verdict only what its patterns recognise. **A verdict
|
||||
|
||||
Reference in New Issue
Block a user