Arquitetura

O mxout é stateless: cada requisição HTTP inicia um ciclo completo de montagem, assinatura e entrega sem depender de estado externo.

Diagrama de fluxo

Aplicação
    │
    │  POST /send  (JSON: from, to[], subject, body)
    ▼
┌─────────────────────────────────────────────────────┐
│                      mxout                          │
│                                                     │
│  1. Valida domínio do from → busca kit DKIM         │
│  2. Gera Message-ID e Date                          │
│  3. Monta MIME                                      │
│  4. Assina DKIM (RSA-SHA256)          ← ledger      │
│                                                     │
│  Por destinatário:                                  │
│  5. Resolve DNS MX (menor prioridade primeiro)      │
│  6. Loop de retry (imediato, +5s, +10s, +30s)      │
│     └── Conecta ao MX                              │
│         EHLO → STARTTLS? → re-EHLO                 │
│         → MAIL FROM → RCPT TO → DATA → QUIT        │
│                                    ↓               │
│              5xx → falha permanente (aborta)        │
│              4xx → retenta                          │
│              2xx → sucesso            ← ledger      │
└─────────────────────────────────────────────────────┘
                         │
                         ▼
               MX do domínio destino

Ciclo por destinatário

Uma única requisição POST /send pode conter múltiplos destinatários. Para cada um, o mxout executa o ciclo abaixo de forma independente.

1. Montagem MIME

O mxout constrói o e-mail com os dados recebidos. Gera o Message-ID no formato <unixts.token@dominio-do-from> e o Date antes de qualquer assinatura. Isso é necessário porque esses campos são assinados — gerá-los depois invalidaria a assinatura.

2. Assinatura DKIM

A chave privada RSA-2048 do domínio (indicada pelo kit configurado) assina os headers From, To, Subject, Date e Message-ID. O header DKIM-Signature resultante é inserido no e-mail.

3. Resolução de MX

O mxout consulta o DNS pelo registro MX do domínio do destinatário. Os servidores são ordenados por prioridade (menor valor = maior prioridade). Se não houver registro MX, o RFC 5321 permite usar o registro A como MX implícito — o mxout segue essa regra.

4. Loop de retry

Tentativas: imediata, +5 s, +10 s, +30 s (4 ao total). As tentativas ficam em memória; não há persistência.

  • Resposta 5xx do servidor remoto indica erro permanente. O destinatário é descartado imediatamente.
  • Resposta 4xx ou falha de conexão indica erro temporário. O mxout retenta até esgotar as tentativas.
  • Esgotadas as tentativas sem sucesso, o erro é registrado no ledger e o destinatário é descartado.

Stateless e ledger

O mxout não mantém banco de dados nem fila em disco. O ledger gravado em stdout (JSON por linha) é a fonte de verdade de cada envio: contém o message_id, o destinatário, o resultado e os detalhes de cada tentativa.

  • Ledger — formato completo dos eventos registrados.
  • Entrega MX direta — detalha resolução de MX, STARTTLS e retry.
By Borlot.com.br on 01/06/2026