Egress
Applies to both dlr_url on a submission and forward.mo.url on a connector.
smsg.webhook.redirects changed from following redirects to not following them. It is the setting
the others depend on: once a redirect is followed, the address that was checked is not the address
that is fetched. An endpoint relying on a redirect now fails loudly rather than quietly going
somewhere else.
private.targets changed to deny in 0.11. A receipt URL resolving to a private, loopback or
link-local address is refused unless you set allow. The old default let a customer’s dlr_url
address anything your gateway could reach, which is a request-forgery surface handed to whoever sends
you traffic. If you post receipts to an application on your own network, set allow before you
upgrade — the refusal is silent to the customer and shows up only as receipts that never arrive.
It resolves the host and then connects, so a name that answers differently in between defeats it. It
raises the cost rather than closing the hole — egress firewall rules are what close it.
The retry ladder is exponential with full jitter, and that changed in 0.11. At the defaults the
ceilings are 2, 4, 8, 16 and 32 minutes, then an hour before each of the last four attempts — ten
attempts spanning at most 5h 2m, where the old flat 120-second wait gave up eighteen minutes after
the first failure and lost every receipt for an endpoint down over a lunchtime deploy. Each wait is
drawn uniformly from zero up to its ceiling, so ten attempts average nearer two and a half hours, and
receipts that failed together do not come due together at a host already in trouble.
A first wait longer than an hour is honoured rather than cut to the ceiling. A receipt between
attempts holds nothing open against the endpoint, so a long schedule costs nothing while it waits —
and the gateway keeps at most ten calls in flight to any one host, so a slow endpoint cannot occupy
the whole forwarder.
Receipt forwarding
kannel carries information only where the registered URL has placeholders for it. A URL without
them receives a request with nothing in it, and nothing reports a problem. That silent failure is why
json is the default.
vendor is off by default because it discloses your supplier to your customer, at an endpoint they
control — usually commercially sensitive.
The payload is documented at Delivery receipts.
The delivery receipt store
Correlation state for messages awaiting a receipt, and receipts held for a disconnected SMPP client.
The only persistent state outside PostgreSQL.
The path was previously settable only as a -D fireflo.dlr.db.path system property. That is still
honoured when smsg.dlr.store.path is unset, so an existing deployment is not relocated on upgrade.
smsg.dlr.correlation.days bounds smsg.cdr.deadline.hours. Past the correlation window a
receipt can no longer be matched to its submission, so waiting longer for one only delays the same
answer. The expiry sweeper derives its cap from this value rather than holding a constant of its own,
so widening the window raises the cap and narrowing it lowers it. A deadline above the cap is clamped
and logged.