-
DcRouter v32.4.0
StableRelease / build-and-release (push) Successful in 21m9sreleased this
2026-09-25 14:52:19 +00:00 | 20 commits to main since this release2026-09-25 - 32.4.0
Features
- Serve gateway-client hostname records and exact certificates, the
@serve.zone/interfaces32.21.0 contractssyncGatewayClientDnsRecord,getGatewayClientCertificateandreleaseGatewayClientCertificate, and advertise them asdns.clientRecordsandcertificates.exactIssuance. A gateway client can now hold an exact hostname without a gateway route: oneAorAAAArecord at an address inside its newallowedDnsRecordAddressespolicy field, and one certificate for exactly that name, which Cloudly needs for its cluster relay names. Only gateway-client credentials can call them, with thesyncDnsRecords,requestCertificatesandreadCertificatescapabilities, for hostnames inside the client'shostnamePatterns. A hostname has one holder: a testing reservation, an enabled gateway-client route, another client or app, or an address record dcrouter does not own is a conflict, and dcrouter never overwrites or adopts such a record. The route DNS reconciler in turn answersrecord-conflictfor a hostname an ownership holds, also through a certificate alone. Records are managed asgateway-client-hostnameunder the route reconciler's DNS exclusion. Certificates need a zone with verified authority and are issued by SmartAcme's exact-identifier DNS-01 path in a namespace per client and app; a request answerspendingwhile the issuance runs. A request for a hostname nobody holds yet first synchronizes a provider zone and is refused ashostname-conflictwhen the name carries an address record dcrouter does not own, or answersissuance-unavailable(retryable) when the synchronization fails; polls for a held hostname synchronize nothing. Releasing a certificate retires its stored material, and a sweep at start and every minute removes the records, certificates and claims of deleted clients, of hostnames outside the client's patterns and of addresses outside its allowance. The allowance is set throughprovisionGatewayClientCredential,createGatewayClientandupdateGatewayClient, stored canonically, and left out of the policy digest while it is empty, so existing credentials keep matching. The exact-certificate issuance now takes its SmartAcme namespace from the caller, and testing grants keep theirs.@serve.zone/interfacesmoves from 32.0.0 to 32.21.0 in the lockfile (^32.0.0→^32.21.0), which brings@push.rocks/smartlog4.0.0 as its dependency.test/test.gateway-client-hostname.node.tscovers the record lifecycle, the conflicts in both directions, certificate issuance, release and the sweep against a real database and DNS manager, and the handlers' credential, pattern and capability checks. - Show and edit a gateway client's
allowedDnsRecordAddressesin the Ops UI under Access > Gateway Clients: a DNS addresses column, a field in the create dialog and the row action Edit DNS Addresses. Both dialogs judge the comma separated list with@serve.zone/interfaces'validateGatewayAllowedDnsRecordAddresses, which the web bundle now imports, keep the dialog open with the reason when it or dcrouter refuses the value, and close only on success. The create dialog previously closed before the request and ignored a refusal, andupdateGatewayClientActionignored an unsuccessful answer; it now records dcrouter's message as the view's error. Changing the allowance through an admin update raises the client's policy generation like any policy change, so its credentials must be provisioned again.test/test.gateway-clients.chromium.tsrenders the view and drives the edit dialog through a refused value, a refused update and a saved one. - Refuse a testing grant, on request and on approval, for a hostname a gateway-client hostname ownership holds, with
ownership_conflict. The ownership is looked up by hostname under the DNS exclusion its writers take, so one that holds only a certificate, with no DNS record, is refused too.test/test.testing-access.node.tscovers the certificate-only case.
Maintenance
- Make
test/test.email-domain-creation-progress.node.ts"domain observation switches from list discovery to id polling" independent of the wall clock; it failed on every run, also on v32.3.2. The test gaveobserveNewEmailDomaina 100 ms deadline with 1 ms polls and asserted two list and two id reads. tsx, which runs the test, scans its disk cache synchronously once per process (131,641 entries in the shared cache on the build host) and blocked the event loop for about 110 ms during the first 1 ms wait, so the deadline expired after one list read.observeNewEmailDomainnow takes an optionalnowclock for its deadline (defaultDate.now), and the test passes a frozen one, so the reads alone decide the result and tstest's timeout still bounds a hang. The module's behaviour with the default clock is unchanged.
Downloads
- Serve gateway-client hostname records and exact certificates, the