Skip to content

calabi 2.2.1

Choose a tag to compare

@calabinet calabinet released this 15 Oct 02:30
· 2 commits to main since this release

Nothing to configure, and no order to update in. No config file changed,
and neither did anything the client, the edge and the coordinator say to each
other. The changes are in the client, the Android app and the coordinator; the
edge is the 2.2.0 code under the new version number.

Local console

  • Changed — Tunnels are called endpoints. The local console says
    endpoint wherever it said tunnel — the menu, the list, the wizard, the
    messages — in all ten languages, as the web console and the documentation
    already do. Where it said visitor it now says caller, source address or
    request, whichever was meant. The pages moved with the name: #/tunnels is
    #/endpoints and #/tunnels/new is #/endpoints/new; the old addresses,
    with whatever follows them, still lead to the new ones, so a bookmark keeps
    working. The command line and what it prints, the configuration keys and
    the daemon's own API keep their names: nothing that reads or scripts the
    client needs editing.
  • Changed — An endpoint's address is labelled External. The tag in
    front of an address in the endpoint list, and the address row at the end of
    the wizard, said Public. They say External now, the name the web console
    uses.
  • Fixed — The Overview page was taller than the window. Once its
    figures had loaded, the page came out 68–90 px taller than the space it had:
    a scrollbar appeared and the live throughput chart sat below the edge of the
    window — every time in the desktop app, whose window has a fixed size. The
    charts now take the space they are given, and the page fits.
  • Fixed — Connected to your own server, the Overview page had three
    more faults.
    • The relay share of today's and this month's traffic always read 0 B, and
      the 7-day chart showed no relay bars, however much the device relayed.
      Both now come from the device's own mesh metering, as the endpoint share
      already did.
    • The 7-day chart ran backwards, with today on the left, and on a machine
      west of Greenwich every date under it was a day early.
    • With a coordinator connected, the page did not fit in the desktop app. The
      card with the coordinator's mesh usage now takes the place of the 7-day
      chart in the bottom row, and draws its own last 7 days as a full chart.
  • Fixed — The German sign-in page. The text of the button for
    connecting to a self-hosted server ran past the edges of the button. It is
    shorter now.

Mesh

  • Fixed — On Windows, a relay close by could stay marked as refusing
    the device.
    A relay that refused a device and later admitted it is struck
    off the refused list once it answers a keepalive. Windows clocks can move in
    steps as coarse as 15.6 ms, and a relay on the same machine or the same LAN
    answers within one step, so the round trip measured exactly 0 — which the
    client read as no answer yet. The refusal stayed on the list: if the link
    dropped afterwards, redialling the home relay could wait out the rest of a
    backoff of up to five minutes, and the relay's round-trip time came and went
    in the status. An answer now counts however short the round trip.

Mobile

  • Changed — The Android app says endpoints too. The tab, the list, its
    empty and scope notes and the usage figures say Endpoints where they said
    Tunnels, in English and in Chinese.

Your server

  • Fixed — On a coordinator that stores to SQLite, a device's report of
    its endpoints could fail.
    The coordinator replaces a device's endpoint list
    in a transaction that reads first and writes second. If another write was
    under way when it came to write, SQLite refused at once instead of waiting
    — the busy timeout does not cover that step — and the report failed until
    the client sent it again a minute later. Transactions now take the write
    lock when they begin, and wait for it under the busy timeout. Nothing to
    migrate: the change is in how the coordinator opens its database file, and
    it takes effect when the coordinator restarts. A coordinator on PostgreSQL
    was not affected.

These are the same files published at https://download.calabi.net — same
version, same bytes. This release is not a separate CI build; it is that build,
uploaded here as well.

Verify them yourself

gh release download v2.2.1 --pattern build-manifest.json
bash scripts/verify-reproducible-build.sh build-manifest.json

That clones this repository at 7789ed0e2df402597e47adc4e5428d140ebced19 — the commit these binaries were
built from — rebuilds all 21 Go artifacts and compares hashes. The
verify-release workflow runs exactly that on GitHub's runners for this
release, so you can also just read its result.

SHA256SUMS (client + desktop), SHA256SUMS.edge and SHA256SUMS.coord
answer a different question: whether your download arrived intact. Archives
themselves are not reproducible (tar/zip record mtimes) — the manifest compares
the binary inside.

Not covered by the manifest

The installers. The two desktop ones are Tauri/Rust builds with their own
toolchains and are not reproducible yet; every installer is listed in
SHA256SUMS, so its integrity is checkable.

calabi-desktop-windows-x64-setup.exe — the calabi daemon it carries is a
different matter: since v1.7.1 that is the released calabi-windows-amd64
binary itself, byte for byte, so the program you actually run is covered by the
manifest even though the installer around it is not.

calabi-desktop-macos-universal.pkg — here the daemon is NOT covered either.
It is a universal (arm64 + x86_64) binary produced by lipo, so it is not byte
identical to either released macOS archive. It is also neither code-signed nor
notarized yet: macOS will stop it on first open, and the download page says how
to proceed. If you would rather not trust a build you did not make, the client
is in this repository — build it.

calabi-android.apk — built from apps/client-android and apps/client/mobile
in this repository, but not reproducibly yet: the Go core records the absolute
directory it was built in, so the same commit built elsewhere differs. It is
signed with the release key; check the signer before installing:

apksigner verify --print-certs calabi-android.apk
# certificate SHA-256 digest: 5800bc9938dd507b1a4fb7cc497f9b3ce50e3c20655fdcb5383aac4049f97d23

Components

  • calabi — the client (endpoints + mesh + the local console on :7400)
  • calabi-edge — the data plane: role: tunnel for endpoints, role: mesh
    for the mesh relay, role: both for the two
  • calabi-coord — the coordinator, every device's identity: invites, device
    registry, addresses, ACLs; names the edge and signs the grants it accepts

calabi-coord and calabi-edge together are your server
(deploy/server).

Docker images (amd64 + arm64): calabinet/calabi, calabinet/calabi-edge,
calabinet/calabi-coord. The binary inside each is the released linux one,
byte for byte.