Bonfire.Mailer.ConnDebug (Bonfire v1.0.0-social-rc.3.22)

View Source

Connectivity and handshake debugging for simple TCP, TLS/SMTPS (implicit TLS like port 465), or SMTP with STARTTLS (like port 587).

Return values:

  • | {:open, :tls} | {:open, :tls_verified}

  • where reason is an atom (e.g., :refused, :timeout, :starttls_not_advertised, etc.)

Notes:

  • Host can be a binary domain (e.g., "smtp.gmail.com"), a charlist ('smtp.gmail.com'), or an IP tuple.
  • For TLS verification, system CAs are used if available (OTP 26+: :public_key.cacerts_get/0). You can override with :cacerts or :cacertfile in ssl_opts.
  • To force IPv6, include :inet6 in tcp_opts or ssl_opts.

Summary

Functions

Sends an SMTP message directly using Mua.easy_send/1, loading host, sender, port, auth, and ssl from mailer config.

SMTP with STARTTLS check (e.g., port 587). Performs

SMTPS (implicit TLS) check, defaults to port 465. Thin wrapper over tls_port_status/5.

Attempts a TLS handshake to the host:port (implicit TLS), e.g., HTTPS 443 or SMTPS 465.

Functions

send_smtp_message(recipients, message, opts \\ [])

Sends an SMTP message directly using Mua.easy_send/1, loading host, sender, port, auth, and ssl from mailer config.

Example

send_smtp_message(["recipient@example.com"], "Subject: ...\r\n...")

Returns {:ok, receipt} or {:error, reason}

smtp_starttls_status(host, port \\ 587, opts \\ [])

@spec smtp_starttls_status(
  charlist() | binary() | :inet.ip_address(),
  :inet.port_number(),
  keyword()
) :: {:open, :tls} | {:open, :tls_verified} | {:closed, term()}

SMTP with STARTTLS check (e.g., port 587). Performs:

  • TCP connect
  • Read 220 greeting
  • EHLO
  • Detect STARTTLS capability
  • Issue STARTTLS
  • Upgrade the socket to TLS

Options (keyword list):

  • :timeout -> overall per-step timeout in ms (default 7000)
  • :ehlo_host -> EHLO client name (charlist or binary), default 'localhost'
  • :ssl_opts -> options appended to TLS handshake
  • :verify -> when true, enables certificate verification (default false)
  • :tcp_opts -> extra gen_tcp options (merged with defaults [:binary, packet: :line, active: false])

Returns:

  • | {:open, :tls_verified}

  • {:closed, reason}

    reasons include: :timeout, :refused, :unexpected_banner, :starttls_not_advertised, :starttls_rejected, :handshake_failure, other low-level errors.

Example: smtp_starttls_status("smtp.gmail.com", 587, verify: true)

smtps_port_status(host, port \\ 465, timeout \\ 5000, ssl_opts \\ [], verify \\ false)

@spec smtps_port_status(
  charlist() | binary() | :inet.ip_address(),
  :inet.port_number(),
  non_neg_integer(),
  keyword(),
  boolean()
) :: {:open, :tls} | {:open, :tls_verified} | {:closed, term()}

SMTPS (implicit TLS) check, defaults to port 465. Thin wrapper over tls_port_status/5.

tcp_port_status(host, port, timeout \\ 3000, tcp_opts \\ [])

@spec tcp_port_status(
  charlist() | binary() | :inet.ip_address(),
  :inet.port_number(),
  non_neg_integer(),
  keyword()
) :: {:open, :tcp} | {:closed, term()}

Checks plain TCP reachability.

Options:

  • tcp_opts: extra gen_tcp options (default [:binary, packet: :raw, active: false, nodelay: true])

Examples: tcp_port_status("example.com", 443)

tls_port_status(host, port, timeout \\ 5000, ssl_opts \\ [], verify \\ false)

@spec tls_port_status(
  charlist() | binary() | :inet.ip_address(),
  :inet.port_number(),
  non_neg_integer(),
  keyword(),
  boolean()
) :: {:open, :tls} | {:open, :tls_verified} | {:closed, term()}

Attempts a TLS handshake to the host:port (implicit TLS), e.g., HTTPS 443 or SMTPS 465.

Parameters:

  • host, port, timeout (ms)
  • ssl_opts: options passed to :ssl.connect/4
  • verify: when true, enables certificate verification using system CAs (unless overridden in ssl_opts)

Examples: tls_port_status("smtp.gmail.com", 465) tls_port_status("smtp.gmail.com", 465, 5000, [], true)